Os recursos deste guia descrevem os recursos de gerenciamento de rede e telefonia que podem ser implementados no app controlador de política de dispositivo (DPC). Este documento contém exemplos de código, e você também pode usar o app Testar DPC como uma fonte de exemplo de código para recursos empresariais do Android.
Um app de DPC pode ser executado no modo de proprietário do perfil em dispositivos pessoais ou no modo de proprietário do dispositivo em dispositivos totalmente gerenciados. Esta tabela indica quais recursos estão disponíveis quando o DPC é executado no modo de proprietário do perfil ou do proprietário do dispositivo:
Recurso | Proprietário do perfil | Proprietário do dispositivo |
Acesse contatos de trabalho em vários perfis | ✓ | |
Garantir uma conexão de rede segura para o tráfego de trabalho | ✓ | ✓ |
Configurar um único ID de rede sem fio entre regiões | ✓ | ✓ |
Especificar um discador separado para o perfil de trabalho | ✓ |
Acessar contatos de trabalho em perfis
Os EMMs podem permitir que o perfil pessoal de um usuário acesse os contatos de trabalho para que os contatos pessoais e de trabalho sejam acessíveis pela pesquisa local e no diretório remoto. Em dispositivos pessoais, um único discador no perfil pessoal pode fazer e receber chamadas pessoais e de trabalho. Além disso, os contatos de trabalho são bem integrados à interface do sistema. Se o perfil de trabalho estiver criptografado, os dados dele não ficarão disponíveis para o perfil pessoal.
Integrado com a interface do sistema
A interface do sistema indica as chamadas de trabalho recebidas usando um ícone de maleta. O
callLog
também mostra o
ícone para designar chamadas de trabalho recebidas e realizadas. O discador pessoal e os apps de contatos podem exibir as informações do identificador de chamadas de um contato de trabalho usando uma pesquisa de diretório remoto. Portanto, não é necessário que o contato já esteja sincronizado no dispositivo local. O app de mensagens pode fazer buscas e identificação de chamadas locais.
O Documento de definição de compatibilidade do Android (CDD) inclui requisitos para que os contatos de trabalho sejam exibidos no discador padrão e requisitos para que os contatos e os apps de mensagens tenham um selo para indicar que são do perfil de trabalho.
Os contatos de trabalho são acessíveis e pesquisáveis
O usuário pode acessar e chamar contatos de trabalho pelo perfil pessoal, que é exibido na tela de pesquisa do app discador. O usuário pode pesquisar contatos de trabalho usando o preenchimento automático, que são sincronizados localmente com o dispositivo e listados em uma pesquisa remota em um diretório.
Controlar contatos de trabalho no perfil principal
O DPC controla a permissão para pesquisar contatos de trabalho. Executado no modo de proprietário do perfil, o DPC gerencia a visibilidade dos contatos de trabalho no perfil pessoal. Para mais informações, consulte Criar um controlador de política de dispositivo.
A pesquisa de contatos de trabalho pelo perfil pessoal está ativada por padrão.
Para conferir como a política é definida, use
DevicePolicyManager.getCrossProfileContactsSearchDisabled()
.Para ativar ou desativar a pesquisa de contatos de trabalho pelo perfil pessoal, use
DevicePolicyManager.setCrossProfileContactsSearchDisabled()
.
Garanta uma conexão de rede segura para o tráfego de trabalho
Em execução no modo de proprietário do dispositivo ou de proprietário do perfil, um controlador de política de dispositivo pode usar uma conexão de rede privada virtual (VPN) sempre ativada para forçar os aplicativos a transmitir tráfego por um app de VPN especificado que não pode ser ignorado. Usando uma conexão VPN sempre ativada, o DPC pode garantir que o tráfego de rede de um perfil de trabalho ou dispositivo gerenciado passe por um serviço de VPN e sem intervenção do usuário. Esse processo cria uma conexão de rede segura para o tráfego contínuo em um perfil de trabalho.
Sobre conexões VPN sempre ativadas
Como parte do framework do sistema, o roteamento de VPN é gerenciado automaticamente para que o
usuário não possa ignorar o serviço de VPN. Se o serviço de VPN for desconectado enquanto o
modo de bloqueio total for desconectado, o tráfego não poderá vazar para a Internet aberta. Para aplicativos que implementam o VpnService
, a VPN sempre ativa oferece um framework para gerenciar e manter uma conexão VPN segura por meio de um servidor confiável. O serviço de VPN reinicia a
conexão automaticamente entre as atualizações de apps, seja por Wi-Fi ou
rede celular. Se o dispositivo for reinicializado, o framework reiniciará a conexão VPN.
A conexão com o serviço de VPN é transparente para o usuário. No caso de um dispositivo da empresa, o usuário não precisa confirmar uma caixa de diálogo de consentimento para uma VPN no modo sempre ativado. As configurações de rede VPN do usuário permitem ativar manualmente uma conexão sempre ativada.
Se DISALLOW_CONFIG_VPN
for true
, o usuário não poderá configurar a VPN. Ative o
DISALLOW_DEBUGGING_FEATURES
para impedir que os usuários substituam a VPN sempre ativada usando o comando adb debug.
Para evitar que um usuário desinstale a VPN, chame
DevicePolicyManager.setUninstallBlocked
.
Configurar o serviço de VPN
A organização que usa sua solução empresarial para Android configura a VPN.
- Instale um app de VPN que implemente
VpnService
. É possível encontrar serviços de VPN ativos usando um filtro de intent que corresponda à açãoVpnService.SERVICE_INTERFACE
. - Declare um
VpnService
no manifesto do app protegido pela permissãoBIND_VPN_SERVICE
. - Configure o
VpnService
para que ele seja iniciado pelo sistema. Evite configurar o app de VPN para iniciar a si mesmo detectando uma inicialização do sistema e controlando o próprio ciclo de vida. - Defina as configurações gerenciadas para o app de VPN. Confira o exemplo abaixo.
Ativar a conexão VPN sempre ativa
O DPC pode configurar uma conexão VPN sempre ativa por meio de um app específico
chamando
DevicePolicyManager.setAlwaysOnVpnPackage()
.
Essa conexão é concedida automaticamente e persiste após uma reinicialização. Se
lockdownEnabled
for falso, o tráfego de rede poderá ficar desprotegido no momento em que o
smartphone for reinicializado e a VPN se conectar. Isso é útil se você não quiser interromper
a conectividade de rede sempre que a VPN falhar ou se a VPN não for essencial.
Verificar a conexão VPN sempre ativa
O DPC pode ler o nome do pacote que administra uma conexão VPN
sempre ativa para o usuário atual com
DevicePolicyManager.getAlwaysOnVpnPackage().
.
Se esse pacote não existir ou se a VPN tiver sido criada no app Configurações
do sistema, null
será retornado.
Exemplo
No app TestDPC, o AlwaysOnVpnFragment.java
usa essas APIs para ativar a configuração de uma conexão VPN sempre ativa.
No exemplo a seguir:
- As configurações
gerenciadas do
serviço de VPN são definidas pelo
DevicePolicyManager
usando o métodosetApplicationRestrictions()
. - As configurações gerenciadas usam pares de chave-valor arbitrários, e este app de exemplo os usa em outro lugar para definir as configurações de rede da VPN. Consulte Verificar configurações gerenciadas.
- O exemplo adiciona o instalador do pacote do Android a uma lista de bloqueio para não atualizar os pacotes do sistema pela VPN. Todo o tráfego de rede do usuário no perfil de trabalho ou dispositivo passa por esse app de VPN, exceto o instalador do pacote. As atualizações usam a Internet aberta.
- O
DevicePolicyManager
ativa a conexão VPN sempre ativa para o pacote VPN usandosetAlwaysOnVpnPackage()
e ativando o modo de bloqueio total.
Kotlin
// Set VPN's managed configurations val config = Bundle().apply { putString(Extras.VpnApp.ADDRESS, "192.0.2.0") putString(Extras.VpnApp.IDENTITY, "vpn.account1") putString(Extras.VpnApp.CERTIFICATE, "keystore://auth_certificate") putStringArray(Extras.VpnApp.DENYLIST, arrayOf("com.android.packageinstaller")) } val dpm = getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager val admin = myDeviceAdminReceiver.getComponentName(this) // Name of package to update managed configurations val vpnPackageName = "com.example.vpnservice" // Associate managed configurations with DeviceAdminReceiver dpm.setApplicationRestrictions(admin, vpnPackageName, config) // Enable always-on VPN connection through VPN package try { val lockdownEnabled = true dpm.setAlwaysOnVpnPackage(admin, vpnPackageName, lockdownEnabled) } catch (ex: Exception) { throw PolicyException() }
Java
// Set VPN's managed configurations final Bundle config = new Bundle(); config.putString(Extras.VpnApp.ADDRESS, "192.0.2.0"); config.putString(Extras.VpnApp.IDENTITY, "vpn.account1"); config.putString(Extras.VpnApp.CERTIFICATE, "keystore://auth_certificate"); config.putStringArray(Extras.VpnApp.DENYLIST, new String[]{"com.android.packageinstaller"}); DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); ComponentName admin = myDeviceAdminReceiver.getComponentName(this); // Name of package to update managed configurations final String vpnPackageName = "com.example.vpnservice"; // Associate managed configurations with DeviceAdminReceiver dpm.setApplicationRestrictions(admin, vpnPackageName, config); // Enable always-on VPN connection through VPN package try { boolean lockdownEnabled = true; dpm.setAlwaysOnVpnPackage(admin, vpnPackageName, lockdownEnabled)); } catch (Exception ex) { throw new PolicyException(...); }
Configurar um único ID de rede sem fio entre regiões
Em execução no modo de proprietário do dispositivo ou de proprietário do perfil, um controlador de política de dispositivo (DPC, na sigla em inglês) pode associar vários certificados de autoridade de certificação (CA, na sigla em inglês) a uma única configuração de rede sem fio. Com essa configuração, um dispositivo pode se conectar a pontos de acesso sem fio que têm o mesmo nome de rede ou identificador de conjunto de serviços (SSID), mas estão configurados com diferentes certificados de CA. Isso é útil quando as redes sem fio da sua organização estão localizadas em várias regiões geográficas e cada região exige uma autoridade de certificação diferente. Por exemplo, assinaturas legais podem exigir uma autoridade local que precisa de uma CA regional.
Observação:o Android oferece suporte a
setCaCertificate
desde a API 18 (Jelly Bean), mas os administradores de TI precisam provisionar as redes
separadamente com cada CA para garantir que os dispositivos tenham autenticação integrada em cada
ponto de acesso, independentemente da região.
Especificar certificados de CA para identificar o servidor
Para especificar uma lista de certificados X.509 que identificam o servidor usando o mesmo
SSID, inclua todas as CAs relevantes na configuração sem fio usando WifiEnterpriseConfig.setCaCertificates()
.
O certificado de um servidor será válido se a CA corresponder a um dos certificados fornecidos.
Os nomes padrão são atribuídos automaticamente aos certificados e usados na configuração. O WifiManager
instala o certificado, salva a configuração automaticamente quando a rede está ativada e remove o certificado quando a configuração é excluída.
Para receber todos os certificados de CA associados à configuração sem fio, use
WifiEnterpriseConfig.getCaCertificates()
para retornar uma lista de
objetos X509Certificate
.
Adicionar uma configuração sem fio usando vários certificados de CA
- Verifique a identidade do servidor:
- Carregue os certificados de CA X.509.
- Carregar a chave privada e o certificado do cliente. Consulte Segurança com HTTPS e SSL para ver um exemplo de como ler um arquivo de certificado.
- Crie um novo
WifiConfiguration
e defina o SSID (Identificador do conjunto de serviços) e o gerenciamento de chaves dele. - Configure a instância
WifiEnterpriseConfig
noWifiConfiguration
.- Identifique o servidor com uma lista de objetos
X509Certificate
usandosetCaCertificates()
. - Defina as credenciais, a identidade e a senha do cliente.
- Defina o método de protocolo de autenticação extensível (EAP, na sigla em inglês) e o método da Fase 2 como parte do estabelecimento da conexão.
- Identifique o servidor com uma lista de objetos
- Adicione a rede com o
WifiManager
. - Ative a rede. O WifiManager salva a configuração automaticamente durante a configuração.
Este exemplo une as etapas:
Kotlin
// Verify the server's identity val caCert0 = getCaCert("cert0.crt") val caCert1 = getCaCert("cert1.crt") val clientKey = getClientKey() val clientCert = getClientCert() // Create Wi-Fi configuration val wifiConfig = WifiConfiguration().apply { SSID = "mynetwork" allowedKeyManagement.set(KeyMgmt.WPA_EAP) allowedKeyManagement.set(KeyMgmt.IEEE8021X) // Set up Wi-Fi enterprise configuration enterpriseConfig.setCaCertificates(arrayOf<X509Certificate>(caCert0, caCert1)) enterpriseConfig.setClientKeyEntry(clientKey, clientCert) enterpriseConfig.setIdentity("myusername") enterpriseConfig.setEapMethod(Eap.TLS) enterpriseConfig.setPhase2Method(Phase2.NONE) } // Add network val wifiManager = getSystemService(Context.WIFI_SERVICE) as WifiManager val netId = wifiManager.addNetwork(wifiConfig) // Enable network if (netId < 0) { // Error creating new network } else { wifiManager.enableNetwork(netId, true) }
Java
// Verify the server's identity X509Certificate caCert0 = getCaCert("cert0.crt"); X509Certificate caCert1 = getCaCert("cert1.crt"); PrivateKey clientKey = getClientKey(); X509Certificate clientCert = getClientCert(); // Create Wi-Fi configuration WifiConfiguration wifiConfig = new WifiConfiguration(); wifiConfig.SSID = "mynetwork"; wifiConfig.allowedKeyManagement.set(KeyMgmt.WPA_EAP); wifiConfig.allowedKeyManagement.set(KeyMgmt.IEEE8021X); // Set up Wi-Fi enterprise configuration wifiConfig.enterpriseConfig.setCaCertificates(new X509Certificate[] {caCert0, caCert1}); wifiConfig.enterpriseConfig.setClientKeyEntry(clientKey, clientCert); wifiConfig.enterpriseConfig.setIdentity("myusername"); wifiConfig.enterpriseConfig.setEapMethod(Eap.TLS); wifiConfig.enterpriseConfig.setPhase2Method(Phase2.NONE); // Add network WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); int netId = wifiManager.addNetwork(wifiConfig); // Enable network if (netId < 0) { // Error creating new network } else { wifiManager.enableNetwork(netId, true); }
Especificar um discador separado para o perfil de trabalho
Você pode colocar um aplicativo discador separado na lista de permissões para usar em um perfil de trabalho.
Pode ser o próprio discador ou um app de voz sobre IP (VoIP, na sigla em inglês) que implementa a
API ConnectionService
para o back-end de chamada. Isso fornece a mesma experiência de discagem da interface do sistema integrada
para aplicativos VoIP no perfil de trabalho, tornando o discador de trabalho
um recurso principal. As chamadas recebidas para as contas de trabalho são
diferenciadas das chamadas recebidas para as contas pessoais.
O usuário pode optar por fazer e receber chamadas do discador de trabalho permitido
em uma conta telefônica. Todas as chamadas feitas desse discador ou recebidas para a conta
de telefone de trabalho são gravadas no provedor
CallLog
do perfil de trabalho. O discador de trabalho mantém um registro de chamadas exclusivo com acesso apenas aos
contatos de trabalho. As chamadas de switch de circuito recebidas são processadas pelo discador principal e armazenadas em um registro de chamadas pessoal. Se um perfil de trabalho for excluído, o registro de chamadas
associado a ele também será excluído, assim como todos os dados
dele.
Os apps de terceiros precisam implementar ConnectionService
Os apps VoIP de terceiros que precisam fazer chamadas telefônicas e essas chamadas
integradas ao app de telefone integrado podem implementar a
API
ConnectionService
. Obrigatório para qualquer serviço VoIP usado para chamadas de trabalho. Esses apps
se beneficiam porque as chamadas são tratadas como chamadas de celular tradicionais.
Por exemplo, elas aparecem no discador integrado do sistema e no registro de chamadas. Se o
app que está implementando
ConnectionService
estiver instalado no perfil de trabalho, ele só poderá ser acessado por um discador também
instalado nesse perfil de trabalho.
Depois que o desenvolvedor implementar o
ConnectionService
,
ele precisará adicioná-lo ao arquivo de manifesto do app e registrar um
PhoneAccount
com o
TelecomManager
.
Uma conta telefônica representa um método distinto para fazer ou receber chamadas,
e pode haver vários PhoneAccounts
para cada
ConnectionService
. Depois que a conta telefônica é registrada, o usuário
pode ativá-la nas configurações do discador.
Integração e notificações da interface do sistema
A interface do sistema oferece aos usuários uma experiência de discagem consistente e integrada
para apps de terceiros que usam a
API ConnectionService
como back-end para fazer chamadas. Se você estiver usando o app em um perfil de trabalho, um ícone de pasta
será exibido nas chamadas recebidas e na barra de status. Um app que implementa o
ConnectionService
instalado no perfil de trabalho pode usar o
discador do sistema ou criar um discador de trabalho separado. Eles podem ser um único app ou
separados.
O aplicativo de telefone determina se está fazendo ou recebendo uma chamada de trabalho
verificando a flag
android.telecom.Call.Details.PROPERTY_ENTERPRISE_CALL
.
Se for uma chamada de trabalho, o discador indica isso ao usuário adicionando um
selo de trabalho (o ícone de pasta):
Kotlin
// Call placed through a work phone account. getCurrentCall() is defined by the // dialer. val call = getCurrentCall() if (call.hasProperty(android.telecom.Call.Details.PROPERTY_ENTERPRISE_CALL)) { // Set briefcase icon }
Java
// Call placed through a work phone account. getCurrentCall() is defined by the // dialer. Call call = getCurrentCall(); if (call.hasProperty(android.telecom.Call.Details.PROPERTY_ENTERPRISE_CALL)) { // Set briefcase icon }