Gerenciar atualizações do sistema

Este guia para desenvolvedores explica como o controlador de política de dispositivos (DPC) pode gerenciar atualizações do sistema Android em nome do usuário do dispositivo.

Introdução

Os dispositivos Android podem receber e instalar atualizações OTA (over-the-air) no sistema e no software do aplicativo. O Android notifica o usuário do dispositivo de que uma atualização do sistema está disponível e o usuário do dispositivo pode instalar a atualização imediatamente ou mais tarde.

Usando o DPC, um administrador de TI pode gerenciar as atualizações do sistema para o usuário do dispositivo. Os DPCs podem ter um dispositivo totalmente gerenciado (chamado de proprietário do dispositivo) ou um perfil de trabalho (chamado de proprietário do perfil). A Tabela 1 mostra como os proprietários de dispositivos podem gerenciar atualizações do sistema, enquanto os proprietários de perfis só podem informar informações sobre atualizações do sistema.

Tabela 1: as tarefas disponíveis para DPCs dependem do modo de proprietário

Tarefa Proprietário de dispositivo Perfil de proprietário
Conferir se há atualizações pendentes do sistema
Receber callbacks quando novas atualizações do sistema estiverem disponíveis
Definir uma política de atualização local para controlar quando o Android instala atualizações do sistema
Congelar a versão do SO durante períodos críticos

Verificar se há atualizações pendentes

Uma atualização pendente é uma atualização do sistema de um dispositivo que ainda não foi instalado. O DPC pode ajudar os administradores de TI a verificar quais dispositivos têm atualizações do sistema pendentes e talvez pedir aos usuários que instalem as atualizações críticas imediatamente.

Proprietários de dispositivos e perfis com o Android 8.0 (nível 26 da API) ou versões mais recentes pode verificar se um dispositivo tem uma atualização do sistema pendente. Chame DevicePolicyManager.getPendingSystemUpdate(), que retorna null se o dispositivo estiver atualizado. Se uma atualização do sistema estiver pendente, o método vai retornar informações sobre a atualização.

Saiba mais sobre uma atualização pendente

Depois de chamar getPendingSystemUpdate(), é possível inspecionar o valor SystemUpdateInfo retornado para saber mais sobre a atualização pendente. O exemplo abaixo mostra como descobrir quando uma atualização pendente ficou disponível para o dispositivo:

Kotlin

val firstAvailable =
        dpm.getPendingSystemUpdate(adminName)?.receivedTime
firstAvailable?.let {
    Log.i(TAG, "Update first available: ${Date(firstAvailable)}")
}

Java

SystemUpdateInfo updateInfo = dpm.getPendingSystemUpdate(adminName);
if (updateInfo != null) {
  Long firstAvailable = updateInfo.getReceivedTime();
  Log.i(TAG, "Update first available: " + new Date(firstAvailable));
}

Callbacks do sistema

Quando uma atualização fica disponível, o sistema Android notifica os proprietários do dispositivo sobre a nova atualização. No Android 8.0 ou versões mais recentes, o sistema também notifica os proprietários do perfil.

Na subclasse DeviceAdminReceiver, modifique o Callback onSystemUpdatePending(). Não é necessário registrar ou anunciar o DPC para receber o callback. O sistema pode chamar esse método mais de uma vez para uma única atualização. Portanto, verifique o status da atualização antes de responder. Ligue para getPendingSystemUpdate() e saiba mais sobre a atualização do sistema no callback. O exemplo a seguir mostra como fazer isso:

Kotlin

/**
 * Called when a new update is available.
 */
override fun onSystemUpdatePending(context: Context?, intent: Intent?,
                                   receivedTime: Long) {

    // System update information is supported in API level 26 or higher.
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
        return
    }

    val updateInfo = getManager(context)
            .getPendingSystemUpdate(getWho(context))
            ?: return
    if (updateInfo.securityPatchState ==
            SystemUpdateInfo.SECURITY_PATCH_STATE_TRUE) {
        // Perhaps install because this is a security patch.
        // ...
    }
}

Java

/**
 * Called when a new update is available.
 */
public void onSystemUpdatePending (Context context, Intent intent,
                                   long receivedTime) {

  // System update information is supported in API level 26 or higher.
  if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
    return;
  }
  SystemUpdateInfo updateInfo = getManager(context)
      .getPendingSystemUpdate(getWho(context));
  if (updateInfo == null) {
    return;
  }
  if (updateInfo.getSecurityPatchState() ==
      SystemUpdateInfo.SECURITY_PATCH_STATE_TRUE) {
    // Perhaps install because this is a security patch.
    // ...
  }
}

Quando um sistema tem mais de um DPC, por exemplo, perfis de trabalho em dispositivos totalmente gerenciados, o proprietário do dispositivo e o proprietário do perfil recebem o callback.

Atualizar políticas

O proprietário de um dispositivo pode controlar quando as atualizações são instaladas definindo uma política de atualização local do sistema para um dispositivo. A política de atualização do sistema pode ser de três tipos:

Automático
Instala as atualizações do sistema assim que elas ficam disponíveis (sem interação do usuário). A definição desse tipo de política instala imediatamente todas as atualizações pendentes que podem ser adiadas ou aguardando uma janela de manutenção.
Com janela
Instala atualizações do sistema durante uma janela de manutenção diária (sem interação do usuário). Defina o início e o fim da janela de manutenção diária, como minutos de do dia, ao criar uma nova política em janela.
Adiado
Adia a instalação de atualizações do sistema por 30 dias. Após o período de 30 dias, o sistema solicita que o usuário do dispositivo instale a atualização.

Períodos de adiamento

O sistema limita cada atualização a um adiamento de 30 dias. O período começa quando o sistema adia a atualização pela primeira vez, e a definição de novas políticas de adiamento não prorroga o período.

Além do adiamento, o Android pode não conseguir instalar uma atualização para outros por alguns motivos, como falta de conectividade, espaço em disco insuficiente ou pouca bateria.

O sistema redefinirá o timer de 30 dias caso ocorra uma atualização diferente. disponíveis durante o período. Assim, os administradores de TI têm a chance de testar o sistema combinado atualizações. Após 30 dias sem uma nova atualização, o sistema solicita que o usuário instale todas as atualizações pendentes. Mais tarde, quando uma nova atualização do sistema se tornar disponível, o período de 30 dias começa novamente.

Como definir uma política

É possível definir políticas de atualização no Android 8.0 (nível 26 da API) ou versões mais recentes. Para especificar quando o dispositivo precisa instalar atualizações do sistema, crie uma instância de SystemUpdatePolicy usando um dos três tipos descritos acima. Para definir uma política, o proprietário do dispositivo chama o método DevicePolicyManager setSystemUpdatePolicy(). O código a seguir exemplo mostra como fazer isso. Para conferir um exemplo de política com janelas, consulte a documentação do SystemUpdatePolicy.

Kotlin

// Create the system update policy to postpone installation for 30 days.
val policy = SystemUpdatePolicy.createPostponeInstallPolicy()

// Get a DevicePolicyManager instance to set the policy on the device.
val dpm = context.getSystemService(Context.DEVICE_POLICY_SERVICE)
        as DevicePolicyManager
val adminName = getComponentName(context)

// Set the policy.
dpm.setSystemUpdatePolicy(adminName, policy)

Java

// Create the system update policy to postpone installation for 30 days.
SystemUpdatePolicy policy = SystemUpdatePolicy.createPostponeInstallPolicy();

// Get a DevicePolicyManager instance to set the policy on the device.
DevicePolicyManager dpm = (DevicePolicyManager) context
    .getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName adminName = getComponentName(context);

// Set the policy.
dpm.setSystemUpdatePolicy(adminName, policy);

As instâncias de política não podem ser alteradas depois de criadas. Para mudar quando um dispositivo instalar atualizações, poderá criar e definir uma nova política. Para remover uma política de um dispositivo, chame setSystemUpdatePolicy() transmitindo null como o argumento policy. Depois que o DPC remove uma política, o usuário do dispositivo recebe notificações sobre as atualizações do sistema disponíveis.

Os apps podem chamar getSystemUpdatePolicy() para receber a política atual do dispositivo. Se esse método retornar null, significa que uma política não está definida no momento.

Períodos de congelamento

Para congelar a versão do SO em períodos críticos, como feriados ou outros momentos de pico, os proprietários de dispositivos podem suspender as atualizações do sistema por até 90 dias. Quando um dispositivo está em um período de congelamento, ele se comporta da seguinte maneira:

  • O dispositivo não recebe notificações sobre atualizações pendentes do sistema.
  • As atualizações do sistema para o SO não são instaladas.
  • Os usuários do dispositivo não podem verificar manualmente as atualizações do sistema nas configurações.

O sistema aplica um buffer obrigatório de 60 dias após qualquer período de congelamento definido para evitar que o dispositivo fique indefinidamente nessa condição. Lembre-se de que o congelamento do sistema podem impedir que os dispositivos recebam atualizações críticas.

Figura 1. Dois períodos de congelamento definidos para um dispositivo
Calendário mostrando dois períodos de congelamento em um ano com reservas de 60 dias.

Você define períodos de congelamento em uma política de atualização. Não é possível definir períodos de congelamento sem a definição de uma política. Quando o dispositivo estiver fora dos períodos de congelamento definidos, o um comportamento normal (automático, em janelas ou adiado) será aplicado.

Como definir um período de congelamento

É possível definir períodos de congelamento no Android 9 (nível 28 da API) ou versões mais recentes. O proprietário do dispositivo define um período de congelamento em uma política de atualização do sistema antes de definir a política para o dispositivo. As etapas são:

  1. Crie uma política de atualização do sistema nova (ou a atual).
  2. Defina os períodos de congelamento na política chamando setFreezePeriods().
  3. Defina a política e congele os períodos para o dispositivo chamando setSystemUpdatePolicy()

Como o período de congelamento é repetido anualmente, as datas de início e término da são representados pelos valores de mês e dia. A data de início precisa começar pelo menos 60 dias após o término de qualquer período de congelamento anterior. O exemplo a seguir mostra como você pode definir dois períodos de congelamento para uma política de atualização do sistema existente:

Kotlin

// Get the existing policy from the DevicePolicyController instance.
val policy = dpm.systemUpdatePolicy ?: return

try {
    // Set the two annual freeze periods on the policy for our retail
    // point-of-sale devices.
    val summerSale = FreezePeriod(
            MonthDay.of(6, 1),
            MonthDay.of(7, 31)) // Jun 1 - Jul 31 inclusive
    val winterSale = FreezePeriod(
            MonthDay.of(11, 20),
            MonthDay.of(1, 12)) // Nov 20 - Jan 12 inclusive
    policy.freezePeriods = Arrays.asList(summerSale, winterSale)

    // Set the policy again to activate the freeze periods.
    dpm.setSystemUpdatePolicy(adminName, policy)

} catch (e: SystemUpdatePolicy.ValidationFailedException) {
    // There must be previous periods recorded on the device because
    // summerSale and winterSale don’t overlap and are separated by more
    // than 60 days. Report the overlap ...
}

Java

// Get the existing policy from the DevicePolicyController instance.
SystemUpdatePolicy policy = dpm.getSystemUpdatePolicy();

try {
  // Set the two annual freeze periods on the policy for our
  // retail point-of-sale devices.
  FreezePeriod summerSale = new FreezePeriod(
      MonthDay.of(6, 1),
      MonthDay.of(7, 31)); // Jun 1 - Jul 31 inclusive
  FreezePeriod winterSale = new FreezePeriod(
      MonthDay.of(11, 20),
      MonthDay.of(1, 12)); // Nov 20 - Jan 12 inclusive
  policy.setFreezePeriods(Arrays.asList(summerSale, winterSale));

  // Don’t forget to set the policy again to activate the freeze periods.
  dpm.setSystemUpdatePolicy(adminName, policy);

} catch (SystemUpdatePolicy.ValidationFailedException e) {
  // There must be previous periods recorded on the device because summerSale
  // and winterSale don’t overlap and are separated by more than 60 days.
  // Report the overlap ...
}

Tanto a data de início quanto a de término são inclusivas. Se o dia de início for posterior que o dia de término (como winterSale no exemplo anterior), o congelamento se estende até o ano seguinte.

Ao definir congelamento períodos em uma política de atualização do sistema, o Android testa estes requisitos:

  • Nenhum período de congelamento é maior que 90 dias.
  • O intervalo entre os períodos de congelamento é de pelo menos 60 dias.
  • Os períodos de congelamento não se sobrepõem.
  • Não há períodos de congelamento duplicados.

Ao definir a política de atualização do sistema para um dispositivo, o Android repete esses testes e inclui todos os períodos de congelamento atuais ou anteriores do dispositivo.

O Android gera uma SystemUpdatePolicy.ValidationFailedException quando em algum desses testes.

Para receber uma lista de períodos de congelamento definidos anteriormente em um objeto de política de atualização do sistema, todos os apps instalados podem chamar SystemUpdatePolicy.getFreezePeriods(). O exemplo a seguir chama esse método para registrar os períodos de congelamento de um dispositivo:

Kotlin

// Log any freeze periods that might be set on a system update policy.
dpm.systemUpdatePolicy?.freezePeriods?.forEach {
    Log.i(TAG, "Freeze period: $it")
}

Java

// Log any freeze periods that might be set on a system update policy.
SystemUpdatePolicy currentPolicy = dpm.getSystemUpdatePolicy();
if (currentPolicy != null) { // A policy might not be set.
  for (FreezePeriod freezePeriod : currentPolicy.getFreezePeriods()) {
    Log.i(TAG, "Freeze period: " + freezePeriod.toString());
  }
}

Anos bissextos

O Android usa o calendário ISO 8601 (também chamado de calendário gregoriano) para calcular períodos de congelamento e ignora anos bissextos. Isso significa que 29 de fevereiro não é reconhecida como uma data válida e é tratada como se fosse 28 de fevereiro. Portanto, 29 de fevereiro não é contado ao calcular a duração de uma pausa período

Desenvolvimento e teste

Enquanto desenvolve e testa o recurso de atualização do sistema do seu DPC, você pode precisamos criar muitos períodos de congelamento. Como o Android verifica um intervalo de 60 dias entre períodos de congelamento anteriores, talvez não seja possível definir um novo período de congelamento sem limpar o registro de períodos anteriores. Para limpar o registro do período de congelamento do dispositivo, execute o seguinte comando no shell do Android Debug Bridge (adb):

adb shell dpm clear-freeze-period-record

Para confirmar que um dispositivo está em um período de congelamento, verifique se a interface do usuário para atualizações do sistema está desativada.

Atualizações do sistema do Google Play (Mainline)

As atualizações do sistema do Google Play (também chamadas de atualizações de Mainline) são: baixado automaticamente, mas o dispositivo precisa ser reiniciado para ser instalado. Esses atualizações automáticas não acionam uma reinicialização automática. Em vez disso, elas são instaladas a próxima reinicialização do usuário, administrador ou política iniciada. As reinicializações acionadas pela política de atualização do sistema instalam a atualização do sistema associada do Google/OEM e todas as atualizações do sistema do Google Play baixadas anteriormente.

As atualizações do sistema do Google Play também podem ser instaladas manualmente. Configurações > Sobre > Versão do Android > Atualização do sistema do Google Play.

Reverter uma atualização

Em alguns casos, a ferramenta Reversões de atualizações do sistema do Google Play (GPSUR) pode ser usado para recuperar o estado do dispositivo devido a uma atualização do sistema do Google Play problemática e instalação. Esta ferramenta deve ser utilizada por usuários avançados ou quando instruído a fazer pela equipe de suporte, já que pode resultar em perda de dados. Veja como usar a ferramenta GPSUR:

  1. Se você tiver o Android Debug Bridge (adb) em execução na máquina, interrompa o serviço adb antes de prosseguir para que ele não interfira no processo de reversão. Para interromper o adb, execute adb kill-server.
  2. Abra a ferramenta GPSUR.
  3. Clique em Permitir acesso ao adb para que a ferramenta possa se comunicar com o dispositivo de teste pelo adb.
  4. Clique em Adicionar novo dispositivo.
  5. Selecione seu dispositivo na lista e clique em Conectar. A lista pode não conter o nome completo do dispositivo.
  6. Na tela do seu dispositivo, selecione Sempre permitir neste computador e clique em Clique em OK para aceitar a conexão da depuração USB.
  7. Selecione o dispositivo conectado no navegador.
  8. O texto do botão na página deve mudar de Nenhuma reversão disponível para Reverta atualizações recentes se houver reversões disponíveis no dispositivo. Clique em Reverter atualizações recentes.
  9. Leia os avisos no modal Confirm Rollback e clique em Confirm.
  10. Aguarde a conclusão da reversão. Quando a reversão for concluída, uma caixa de diálogo Rollback Successful vai aparecer e o dispositivo será reiniciado. Agora você pode desconectar o dispositivo.

Outros recursos

Para saber mais sobre as atualizações do sistema, leia a documentação OTA Updates do Android Open Source Project.