Управление обновлениями системы

В этом руководстве разработчика объясняется, как ваш контроллер политики устройства (DPC) может управлять обновлениями системы Android от имени пользователя устройства.

Введение

Устройства Android могут получать и устанавливать обновления системы и прикладного программного обеспечения по беспроводной сети (OTA). Android уведомляет пользователя устройства о доступности обновления системы, и пользователь устройства может установить обновление немедленно или позже.

Используя ваш ЦОД, ИТ-администратор может управлять обновлениями системы для пользователя устройства. ЦОД могут владеть полностью управляемым устройством (так называемым владельцем устройства) или рабочим профилем (так называемым владельцем профиля). В таблице 1 показано, как владельцы устройств могут управлять обновлениями системы, а владельцы профилей могут только сообщать информацию об обновлениях системы.

Таблица 1. Задачи, доступные ЦОД, зависят от режима владельца

Задача Владелец устройства Владелец профиля
Проверьте наличие ожидающих обновлений системы
Получайте обратные вызовы, когда становятся доступны новые обновления системы.
Установите локальную политику обновлений, чтобы контролировать, когда Android устанавливает обновления системы.
Замораживание версии ОС в критические периоды

Проверьте наличие ожидающих обновлений

Ожидаемое обновление — это обновление системы для устройства, которое еще не установлено. Ваш ЦОД может помочь ИТ-администраторам проверить, на каких устройствах имеются ожидающие обновления системы, и, возможно, попросить пользователей устройств как можно скорее установить критические обновления.

Владельцы устройств и владельцев профилей, работающих под управлением Android 8.0 (уровень API 26) или выше, могут проверить, имеется ли на устройстве ожидающее обновление системы. Вызовите DevicePolicyManager.getPendingSystemUpdate() , который возвращает null если устройство обновлено. Если ожидается обновление системы, метод возвращает информацию об обновлении.

Узнайте больше о ожидающем обновлении

После вызова getPendingSystemUpdate() вы можете проверить возвращаемое значение SystemUpdateInfo , чтобы узнать больше об ожидающем обновлении. В следующем примере показано, как можно узнать, когда ожидающее обновление впервые стало доступно для устройства:

Котлин

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

Ява

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

Системные обратные вызовы

Когда обновление становится доступным, система Android уведомляет владельцев устройств о новом обновлении. В Android 8.0 и выше система также уведомляет владельцев профилей.

В подклассе DeviceAdminReceiver переопределите обратный вызов onSystemUpdatePending() . Вам не нужно регистрироваться или рекламировать свой ЦОД, чтобы получить обратный вызов. Система может вызывать этот метод несколько раз для одного обновления, поэтому перед ответом проверьте статус обновления. Вызовите getPendingSystemUpdate() чтобы узнать больше об обновлении системы в обратном вызове. В следующем примере показано, как это можно сделать:

Котлин

/**
 * 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.
        // ...
    }
}

Ява

/**
 * 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.
    // ...
  }
}

Если в системе имеется более одного DPC, например рабочие профили на полностью управляемых устройствах, обратный вызов получают как владелец устройства, так и владелец профиля.

Обновить политики

Владелец устройства может контролировать время установки обновлений, настроив политику обновления локальной системы для устройства. Политика обновления системы может быть одного из трех типов:

Автоматический
Устанавливает обновления системы, как только они становятся доступными (без взаимодействия с пользователем). Установка этого типа политики немедленно устанавливает все ожидающие обновления, которые могут быть отложены или ждут периода обслуживания.
оконный
Устанавливает обновления системы во время ежедневного периода обслуживания (без взаимодействия с пользователем). При создании новой оконной политики задайте начало и конец периода ежедневного обслуживания в минутах дня.
Перенесенный
Откладывает установку обновлений системы на 30 дней. По истечении 30-дневного периода система предложит пользователю устройства установить обновление.

Периоды отсрочки

Система ограничивает каждое обновление одной 30-дневной отсрочкой. Период начинается, когда система впервые откладывает обновление, и установка новых политик отсрочки не продлит этот период.

Помимо отсрочки, Android может не иметь возможности установить обновление по другим причинам, например, из-за отсутствия подключения, недостаточного места на диске или низкого заряда батареи.

Система сбрасывает таймер 30-дневной отсрочки, если в течение этого периода становится доступно другое обновление, что дает ИТ-администраторам возможность опробовать объединенные системные обновления. По прошествии 30 дней без новых обновлений система предлагает пользователю установить все ожидающие обновления. Позже, когда станет доступно новое обновление системы, 30-дневный период начинается снова.

Как установить политику

Вы можете установить политики обновления в Android 8.0 (уровень API 26) или более поздней версии. Чтобы указать, когда устройство должно устанавливать обновления системы, создайте экземпляр SystemUpdatePolicy используя один из трех типов, описанных выше. Чтобы установить политику, владелец вашего устройства вызывает метод DevicePolicyManager setSystemUpdatePolicy() . В следующем примере кода показано, как это можно сделать. Чтобы увидеть пример оконной политики, посмотрите документацию SystemUpdatePolicy .

Котлин

// 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)

Ява

// 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);

Экземпляры политики нельзя изменить после их создания. Чтобы изменить время установки обновлений на устройстве, вы можете создать и настроить новую политику. Чтобы удалить политику с устройства, вызовите setSystemUpdatePolicy() передав null в качестве аргумента policy . После того как ваш ЦОД удалит политику, пользователь устройства увидит уведомления о любых доступных обновлениях системы.

Приложения могут вызывать getSystemUpdatePolicy() чтобы получить текущую политику для устройства. Если этот метод возвращает null , это означает, что политика в настоящее время не установлена.

Периоды заморозки

Чтобы заморозить версию ОС в критические периоды, например, в праздники или в другое загруженное время, владельцы устройств могут приостановить обновления системы на срок до 90 дней. Когда устройство находится в периоде зависания, оно ведет себя следующим образом:

  • Устройство не получает никаких уведомлений об ожидающих обновлениях системы.
  • Системные обновления ОС не устанавливаются.
  • Пользователи устройств не могут вручную проверять наличие обновлений системы в настройках.

Система обеспечивает обязательный 60-дневный буферный период после любых определенных периодов заморозки, чтобы предотвратить заморозку устройства на неопределенный срок. Помните, что заморозка обновлений системы может помешать устройствам получать критические обновления.

Рисунок 1. Для устройства установлены два периода заморозки
Календарь, показывающий два периода заморозки в году с 60-дневными буферами.

Вы устанавливаете периоды заморозки в политике обновления. Вы не можете установить периоды заморозки без настройки политики. Если устройство находится вне установленных вами периодов заморозки, применяется обычное поведение политики (автоматическое, оконное или отложенное).

Как установить период заморозки

Вы можете установить периоды заморозки в Android 9 (уровень API 28) или выше. Владелец устройства устанавливает период заморозки политики обновления системы перед настройкой политики для устройства. Шаги:

  1. Создайте новую (или получите текущую) политику обновления системы.
  2. Установите периоды заморозки политики, вызвав setFreezePeriods() .
  3. Установите политику и периоды заморозки для устройства, вызвав setSystemUpdatePolicy() .

Поскольку период замораживания повторяется ежегодно, даты начала и окончания периода представлены значениями месяца и дня. День начала должен начаться как минимум через 60 дней после окончания любого предыдущего периода заморозки. В следующем примере показано, как можно установить два периода заморозки для существующей политики обновления системы:

Котлин

// 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 ...
}

Ява

// 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 ...
}

И день начала, и день окончания включены в стоимость. Если день начала больше дня окончания (например, winterSale в предыдущем примере), период заморозки продлевается на следующий год.

При настройке периодов заморозки в политике обновления системы Android проверяет соответствие следующим требованиям:

  • Никакой период заморозки не превышает 90 дней.
  • Интервал между периодами заморозков составляет не менее 60 дней.
  • Периоды заморозки не пересекаются.
  • Повторяющихся периодов заморозки нет.

При настройке политики обновления системы для устройства Android повторяет эти тесты и включает все текущие или прошлые периоды зависания устройства.

Android выдает исключение SystemUpdatePolicy.ValidationFailedException , если какой-либо из этих тестов не пройден.

Чтобы получить список периодов заморозки, ранее установленных для объекта политики обновления системы, все установленные приложения могут вызвать SystemUpdatePolicy.getFreezePeriods() . В следующем примере этот метод вызывается для регистрации периодов зависания устройства:

Котлин

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

Ява

// 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());
  }
}

Високосные годы

Android использует календарь ISO 8601 (также называемый григорианским календарем) для расчета периодов заморозки и игнорирует високосные годы. Это означает, что 29 февраля не считается действительной датой и рассматривается как 28 февраля. Поэтому 29 февраля не учитывается при расчете продолжительности периода заморозки.

Разработка и тестирование

Пока вы разрабатываете и тестируете функцию обновления системы вашего ЦОД, вам может потребоваться создать множество периодов заморозки. Поскольку Android проверяет 60-дневный интервал между прошлыми периодами заморозки, возможно, вы не сможете установить новый период заморозки, не очистив предварительно записи прошлых периодов. Чтобы очистить запись периода зависания устройства, выполните следующую команду в оболочке Android Debug Bridge (adb):

adb shell dpm clear-freeze-period-record

Вы можете убедиться, что устройство находится в периоде зависания, проверив, что пользовательский интерфейс для обновлений системы отключен.

Обновления системы Google Play (основная версия)

Обновления системы Google Play (также называемые обновлениями Mainline) загружаются автоматически, но для их установки требуется перезагрузка устройства. Эти обновления не вызывают автоматическую перезагрузку и вместо этого устанавливаются при следующей перезагрузке, инициированной пользователем, администратором или политикой. При перезагрузке, вызванной политикой обновления системы, будет установлено соответствующее обновление системы Google/OEM и все ранее загруженные обновления системы Google Play.

Обновления системы Google Play также можно установить вручную, выбрав «Настройки» > «О программе» > «Версия Android» > «Обновление системы Google Play» .

Откатить обновление

В некоторых случаях инструмент отката обновления системы Google Play (GPSUR) можно использовать для восстановления состояния устройства из-за проблемной установки обновления системы Google Play. Этот инструмент следует использовать опытным пользователям или по указанию персонала службы поддержки, поскольку это может привести к потере данных. Вот как использовать инструмент GPSUR:

  1. Если на вашем компьютере запущен Android Debug Bridge (adb) , остановите службу adb, прежде чем продолжить, чтобы она не мешала процессу отката. Чтобы остановить adb, запустите adb kill-server .
  2. Откройте инструмент GPSUR .
  3. Нажмите «Разрешить доступ ADB» , чтобы разрешить инструменту взаимодействовать с вашим тестовым устройством через adb.
  4. Нажмите Добавить новое устройство .
  5. Выберите свое устройство из списка и нажмите «Подключиться» . Этот список может не содержать полное имя устройства.
  6. На экране вашего устройства выберите «Всегда разрешать с этого компьютера» и нажмите «ОК» , чтобы принять подключение для отладки USB.
  7. Выберите подключенное устройство в браузере.
  8. Текст кнопки на странице должен измениться с «Откат не доступен» на «Откатить последние обновления», если на вашем устройстве доступны откаты. Нажмите «Откатить последние обновления» .
  9. Прочтите предупреждения в модальном окне «Подтвердить откат» и нажмите «Подтвердить» .
  10. Дождитесь завершения отката. После завершения появится модальное окно «Откат успешен» , и устройство перезагрузится. Теперь можно безопасно отключить устройство.

Дополнительные ресурсы

Чтобы узнать больше об обновлениях системы, прочтите документацию по OTA-обновлениям проекта Android Open Source Project.