Отключили ли последние обновления Android белый список оптимизации заряда батареи?

TL; DR

Приведены ли обновления безопасности для Android 7.1.2 от 5 июня 2017 г. к тому, что Android начал игнорировать белый список оптимизации батареи (то есть то, что позволяет приложению отключать режим Doze)?

И если да, то как теперь приложение может программно отключить режим Doze, если у него есть вариант использования, который требует, чтобы ЦП и Wi-Fi были постоянно активными?

Контекст

У меня есть приложение для Android, которое поддерживает трансляцию локальных аудиофайлов в сетевой приемник Chromecast (с использованием встроенного HTTP-сервера для потоковой передачи содержимого файла на приемник).

Чтобы это работало на Android M (с точки зрения отсутствия прерывания сеанса Chromecast, когда устройство транслирует звук, но в остальном бездействует), мне пришлось использовать подход из этот ответ, чтобы отключить режим дремоты.

В частности, в моем AndroidManifest.xml у меня есть:

<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />

... и следующий код выполняется всякий раз, когда устанавливается сеанс Chromecast:

if (Build.VERSION.SDK_INT >= 23) {
    String packageName = context.getPackageName();
    PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
    if (! pm.isIgnoringBatteryOptimizations(packageName)) {
        //reguest that Doze mode be disabled
        Intent intent = new Intent();
        intent.setAction(
            Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
        intent.setData(Uri.parse("package:" + packageName));

        context.startActivity(intent);
    }

}

... и я также получаю блокировки пробуждения / Wi-Fi стандартным способом, пока активно воспроизведение Chromecast:

PowerManager powerManager = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "myapp-cast-server-cpu");
wakeLock.acquire();

WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "myapp-cast-server-net");
wifiLock.acquire(); 

Приложение появляется в белом списке батарей, и всего несколько недель назад все работало нормально. Однако теперь приложение попадает в режим Doze.

Устройство тестирования не изменилось; это Google Pixel под управлением Android 7.1.2. Единственное изменение программного обеспечения - это то, что я установил исправления безопасности от 5 июня 2017 года.

Системный журнал Android сообщает следующее (при активной трансляции):

06-16 17:44:24.842 1095-1150/? I/DreamManagerService: Entering dreamland.
06-16 17:44:24.846 1095-1145/? I/DreamController: Starting dream: name=ComponentInfo{com.android.systemui/com.android.systemui.doze.DozeService}, isTest=false, canDoze=true, userId=0

В этот момент (после задержки в несколько секунд) вызывается мой метод Chromecast onConnectionSuspended() со значением CAUSE_NETWORK_LOST. Что, конечно, было бы потому, что режим Doze отключил Wi-Fi.

Приведены ли обновления безопасности для Android 7.1.2 от 5 июня 2017 г. к тому, что Android начал игнорировать белый список оптимизации батареи (то есть то, что позволяет приложению отключать режим Doze)?

И если да, то как теперь приложение может программно отключить режим Doze, если у него есть вариант использования, который требует, чтобы ЦП и Wi-Fi были постоянно активными?

Изменить

Вот минимальный пример проекта, демонстрирующего проблему (по крайней мере, на моем Google Pixel):

https://github.com/adam-roth/droid-doze-test

Вот результат, который я получил, запустив тест на своем Pixel:

введите здесь описание изображения


person aroth    schedule 16.06.2017    source источник
comment
Приведены ли обновления безопасности Android 7.1.2 от 5 июня 2017 г. к тому, чтобы Android начал игнорировать белый список оптимизации батареи - если это так, это должно быть ошибкой. Если вы можете создать простой тестовый пример, сообщите о проблеме. Мне, например, было бы интересно увидеть это.   -  person CommonsWare    schedule 16.06.2017
comment
Я не знаю о тестовом примере (это похоже на крутой холм, по которому нужно подняться, чтобы доказать, что есть ошибка), но я могу подтвердить, что то же приложение, работающее на более старом устройстве (Sony Xperia) , не работает Убейте сеть / ЦП, пока приложение удерживает блокировки пробуждения / Wi-Fi.   -  person aroth    schedule 22.06.2017
comment
это похоже на крутой холм, по которому нужно подняться, чтобы доказать, что есть ошибка - тогда, пожалуйста, не жалуйтесь, когда люди не могут вам помочь, если проблема медленно решается и т. д. Например, возможно, проблема не в универсальный, но ограничивается Google Pixel или ограничивается Google Pixel при подключении к точке доступа Wi-Fi определенной марки или чему-то более узкому, что подходит для вашей ситуации. Без воспроизводимости ваш анализ - это точка данных, а не призыв к действию.   -  person CommonsWare    schedule 22.06.2017
comment
Я не помню, чтобы жаловался; просто спрашиваю. Хотя я предполагаю, что есть люди, чья работа - буквально предотвращать появление подобных ошибок и исправлять их, когда они появляются. Для одного из них было бы наиболее подходящим предложить минимальный тестовый набор. Заставить Chromecast работать - только мое хобби. Но ... на самом деле требуется очень мало кода, помимо того, что написано в посте. Убедитесь в этом сами.   -  person aroth    schedule 22.06.2017
comment
Этот код, похоже, не демонстрирует симптом, который вы определили (что, конечно, может быть связано с тем, что режим Doze отключил Wi-Fi). Каково ожидаемое поведение вашего кода и в чем разница в этом поведении, когда было применено это конкретное обновление безопасности?   -  person CommonsWare    schedule 22.06.2017
comment
Ожидаемое поведение заключается в том, что Doze не срабатывает (пока таймер работает), о чем свидетельствует выдача сообщения logcat, такого как DreamController: Starting dream: name=ComponentInfo{com.android.systemui/com.android.systemui.doze.DozeService}, isTest=false, canDoze=true, userId=0. На самом деле происходит выдача сообщения (обязательно отключите фильтрацию при просмотре вывода logcat). Я не уверен, как сделать его более понятным, не делая код менее простым. Режим дремоты не должен запускаться, потому что приложение находится в белом списке и удерживает блокировки пробуждения. Режим дремоты запускается. Это ошибка.   -  person aroth    schedule 22.06.2017
comment
Ожидаемое поведение состоит в том, что Doze не срабатывает - предполагается, что Doze срабатывает. Цитируя документацию, приложение, которое в белом списке могут использовать сеть и удерживать частичную блокировку пробуждения во время дремоты и ожидания приложений. Однако другие ограничения по-прежнему применяются к приложению из белого списка, как и к другим приложениям. Если приложение из белого списка имеет выдающийся WifiLock, я ожидаю, что Wi-Fi останется включенным. Вы видите, как он выключается; это то, что я надеюсь каким-то образом воспроизвести   -  person CommonsWare    schedule 22.06.2017
comment
Честная оценка; сеанс Chromecast всегда умирает вскоре после того, как это сообщение появляется в полном приложении, поэтому я предполагаю, что они коррелированы (то есть сообщение и потеря Wi-Fi). Но это предположение. Я добавил в тестовый пример медленную фоновую загрузку файла, которая должна оказаться более убедительной. Первый запуск и загрузка действительно была прервана. Второй прогон сейчас для подтверждения. Изменить: второй прогон также не удался.   -  person aroth    schedule 22.06.2017
comment
И github обновлен, если вы хотите попробовать еще раз.   -  person aroth    schedule 22.06.2017
comment
Позвольте нам продолжить это обсуждение в чате.   -  person aroth    schedule 22.06.2017
comment
Я не могу воспроизвести вашу проблему на своем Pixel, на котором также есть июньские исправления. Я нажал кнопку "Получить" и добавил ваше приложение в белый список. Я снова нажал кнопку получения, увидел, что счетчик запустился, и отложил устройство в сторону. 15 минут спустя счетчик и загрузка продолжают работать, несмотря на появление DreamController сообщений. Я проделал это дважды, каждый раз с одним и тем же результатом.   -  person CommonsWare    schedule 23.06.2017
comment
Интересно. У меня это всегда терпит неудачу, постоянно около 9:00. У меня были пробеги от 7:00 до 11:30, но никогда не было успешной загрузки. Может тогда какая-то настройка на моем девайсе? Я уже подтвердил, что режим энергосбережения отключен, и очистил кеш приложения. На что еще я должен посмотреть?   -  person aroth    schedule 23.06.2017
comment
но никогда не было успешной загрузки - обратите внимание, что загрузка продолжалась в моих тестах через 15 минут, но ни разу я не позволил ей завершиться. Я не был уверен, сколько времени это займет. Может тогда какая-то настройка на моем девайсе? -- возможно. Я только что понял, что Wi-Fi моего Pixel настроен на постоянное включение Wi-Fi во время сна. Я не помню, чтобы вручную менял это на этом устройстве, но, возможно, я это сделал. Что у вас установлено? (Настройки ›WiFi› (значок шестеренки)).   -  person CommonsWare    schedule 23.06.2017
comment
Мой тоже был установлен на «Всегда». Но поскольку было ясно, что Wi-Fi на самом деле периодически отключается, я решил пройтись и включить / выключить все параметры энергосбережения. Когда я это сделал, приложение "Настройки" разбилось. После того, как вы вернули его и переключили все параметры питания, теперь он, похоже, работает правильно. Странно, но похоже, что что-то не так с настройками устройства. По-прежнему возможна ошибка, хотя сейчас неясно, какие начальные условия необходимы для ее запуска. Патч безопасности не кажется вероятным виновником.   -  person aroth    schedule 23.06.2017