4 апреля 2018 г.

Изменения поведений в Android P. Часть 1: от доступа к датчикам до возможных проблем взаимодействия с сетью

    Эта статья является переводом первой половины вот этой: https://developer.android.com/preview/behavior-changes.html. Как всегда, я рекомендую читать оригинал.


    В Android P есть множество изменений поведения системы и большая их часть скажется на всех приложениях, вне зависимости от заявленного в них target. Разумеется, есть и такие изменения, которые будут применены только к тем приложениям, в которых объявлена поддержка Android P. Для максимальной ясности описания, эта запись будет разделена на несколько частей. В первой статье будет описана часть изменений, применимых ко всем приложениям, во второй статье будет продолжение описания этих изменений. В третьей статье будут описаны те изменения, которые коснутся приложений, заявивших поддержку Android P.

    Все изменения, описанные ниже, будут применены ко всем приложениям, работающими на Android P, вне зависимости от того, заявили они поддержку этой версии Android или нет. Каждый разработчик должен ознакомиться с этим списком и подумать, затрагивает ли каждое из изменений какое-либо из его приложений.


Доступ к данным и устройствам ввода для фоновых приложений

    В Android P ужесточены правила сохранения приватности пользователя, в том числе путём ограничения возможности фоновых приложений получать доступ к пользовательскому вводу и данным сенсоров. Если ваше приложение работает в фоне, то Android P наложит на него следующие ограничения:
    Если вашему приложению нужно ловить события датчиков, предусмотрите на Android P запуск сервиса переднего плана.
    Замечание: Это изменение не затрагивает приложения, вызывающие flush() в экземпляре SensorManager.

Защита устройства

    Устройства, работающие под Android P, поддерживают перевыпуск ключей и защиту системных вызовов. Эти изменения повышаю безопасность приложений и не важно, какой API level задан в приложении как целевой. Больше информации об этих изменениях смотрите на странице Security Behavior Changes.

Крипография

    В Android P появилось несколько изменений в реализации и работе криптографических алгоритмов.

Реализация криптоалгоритмов и их параметров в Conscrypt

    В Android P, в Conscrypt появились новые реализации параметров алгоритмов, например: AES, DESEDE, OAEP и EC. Некоторые алгоритмы, а также версии этих параметров от The Bouncy Castle объявлены устаревшими.
    Замечание: В Conscrypt реализации EC параметра поддерживаются только именованные кривые.

    Если ваше приложение имеет таргет на Android 8.1 (API level 27) или ниже, то вы будете получать предупреждения при запросах к устаревшим реализациям алгоритмов от Bouncy Castle. Если вы выставите таргет на Android P, то такие запросы будут бросать NoSuchAlgorithmException.

Другие изменения

    Вот ещё некоторые изменения в криптографии в Android P:
  • Если при использовании PBE ключей Bouncy Castle ожидает вектор инициализации (initialization vector (IV)), а приложение его не предоставляет, вы словите предупреждение
  • Реализация шифрования ARC4 в Conscrypt позволяет вам определить либо ARC4/ECB/NoPadding, либо ARC4/NONE/NoPadding
  • Поставщик The Crypto Java Cryptography Architecture (JCA) был удалён. Так что теперь если вы попытаетесь сделать вызов SecureRandom.getInstance("SHA1PRNG", "Crypto"), возникнет исключение NoSuchProviderException
  • Если ваше приложение парсит RSA ключи из буферов, которые больше структуры ключа, исключения больше возникать не будет

Изменения в совместимости для приложений

    Чтобы приложения были стабильнее и обеспечивали хорошую изкоробочную совместимость с новыми версиям ОС, Android P начинает ограничивать использование некоторых не SDK-шных методов и полей. Эти ограничения будут накладываться вне зависимости от способов доступа к методам и полям: напрямую, через рефлексию или через JNI. В Developer Preview 1 ваши приложения всё ещё будут иметь доступ к защищаемым интерфейсам. Пока система при попытках доступа будет просто показывать тост (всплывающее уведомление), чтобы вы понимали, что в этих местах скоро будут серьёзные изменения. То есть если ваше приложение показывает подобный тост, вам необходимо найти другой способ иметь нужную функциональность, но не пытаться получить доступ к защищённым интерфейсам. Если вы понимаете, что никакого другого способа получить такую функциональность не существует, вы можете завести баг с запросом отменить ограничение.

    Статья Restrictions on Non-SDK Interfaces содержит больше важной информации и будет дополняться. Вам необходимо ознакомиться с ней, дабы быть уверенным, что ваше приложение не потеряет существующую функциональность.

Обновления ICU библиотек

    Версия библиотеки ICU (прим. перев.: International Components for Unicode) была обновлена до ICU 60. В Android 8.0 (API level 26) и 8.1 (API level 27) была версия ICU 58.

    ICU используется для предоставления публичных API ниже пакета android.icu. То есть сам Android использует её для поддержки разных языков и форматов. Например, она используется в андроидовской реализации классов java.util, java.text и android.text.format. В этом релизе содержится много маленьких, но полезных изменений, таких как поддержка Emoji 5.0 и улучшения форматов даты/времени, как это описано в описании релизов ICU 59 и ICU 60. Вам стоит обратить внимание на следующие моменты:
  • Изменён способ обработки часовых поясов:
    • Лучшая поддержка GTM и UTC. Больше UTC не является синонимом GMT
      Теперь ICU отдаёт переведённые названия зон GMT и UTC. Это изменение затрагивает форматирование и парсинг для зон "GMT", "Etc/GMT", "UTC", "Etc/UTC" и "Zulu" средствами android.icu
    • Теперь java.text.SimpleDateFormat использует ICU для отображения имён UTC /GMT, что означает:
      • Форматирование zzzz во многих локалях генерирует длинную локализованную строку. Ранее возвращалась строка "UTC" для UTC и строки типа "GMT+00:00" для GMT)
      • Парсинг zzzz распознаёт строки типа "Universal Coordinated Time" и "Greenwich Mean Time"
      • В приложении могут быть проблемы совместимости, если в них заложено, что zzzz во всех языках отдаёт "UTC" или "GMT+00:00"
    • Изменилось поведение java.text.DateFormatSymbols.getZoneStrings():
      • Подобно SimpleDateFormat, UTC и GMT теперь имеют и длинные имена. GMT+00:00 стал вариантом имён для временных зон с DST (прим. перев.: Daylight Saving Time — летнее время. Т.е. те тайм зоны, где переводят стрелки часов) в зоне UTC (вроде "UTC", "Etc/UTC" и "Zulu"). Его использование, в случае, если нет никаких доступных имён, предпочтительнее, чем просто хардкод строки UTC
      • ID некоторых зон корректно распознаются как синонимы других зон. То есть Android найдёт строки для устаревших ID зон, например Eire, тогда как раньше этого бы не произошло
    • Asia/Hanoi более не является распознаваемой зоной. По этой причине java.util.TimeZones.getAvailableIds() не вернёт это значение, а java.util.TimeZone.getTimeZone() не распознает его. Такое поведение согласуется с текущим поведением android.icu
  • Метод android.icu.text.NumberFormat.getInstance(ULocale, PLURALCURRENCYSTYLE).parse(String) может бросать исключение ParseException даже если вы пытаетесь распарсить нормальную валюту. Избежать этой проблемы можно, если для PLURALCURRENCYSTYLE использовать NumberFormat.parseCurrency, доступный с Android 7.0 (API level 24).

  Создание зашифрованных файлов средствами Android более не поддерживается



  • Создание зашифрованных файлов (Android secure encrypted files (ASECs)) появилось в Android 2.2 (API level 8) для поддержки появившейся тогда фичи «установка/перенос приложений на SD карту». В Android 6.0 (API level 23) эта функциональность была объявлена устаревшей, а на замену ей была представлена фича “adoptable SD card”
  • В Android 8.0 (API level 26) возможность устанавливать приложения в ASEC была окончательно заблокирована. В Developer Preview функциональность ASEC полностью удалена

Изменения в TestSuiteBuilder

    Метод addRequirements() класса TestSuiteBuilder удален, а сам класс TestSuiteBuilder объявляется устаревшим. Метод addRequirements() требовал от разработчиков передавать аргументы, типы которых скрыты API, что делало API некорректными.

Библиотеки тестирования удалены из фреймворка

    До Android 8.1 (API level 27) включительно фреймворк Android предоставлял несколько классов, к примеру ActivityInstrumentationTestCase2, которые вы могли использовать для создания тестов в ваших приложениях. Эти классы доступны во время компиляции, если при сборке есть зависимость от android.jar. Такая встроенная архитектура для тестирования хотя и удобна, но она требует зависимости от той версии JUnit, которая предоставляется android.jar. Это может принести проблемы сборки и тестов, если есть необходимость использовать другую версию JUnit.

    Так что классы тестов были удалены их Android P. Тем не менее, библиотеки тестирования всё ещё доступны как опциональные зависимости. На странице The Legacy testing libraries описано, как использовать их в Android P.

    Чтобы больше узнать о тестировании Android приложений, смотрите Testing Apps on Android.

Java UTF декодер

    В Android по умолчанию используется UTF-8. Последовательность байтов UTF-8 может быть декодирована конструктором String, к примеру String(byte[] bytes). В Android P декодер UTF-8 строгий и следует стандартам Unicode, а именно:
  • Теперь не кратчайшая форма UTF-8, вроде <C0, AF>, рассматривается как некорректная (прим. перев.: ill-formed: https://unicode.org/reports/tr36/#Ill-Formed_Subsequences)
  • Суррогатная форма UTF-8, к примеру U+D800..U+DFFF, также рассматривается как некорректная
  • Наибольшая подчасть заменяется на U+FFFD. К примеру, в последовательности байтов "41 C0 AF 41 F4 80 80 41", наибольшие подчасти это "C0", "AF" и "F4 80 80". "F4 80 80" может быть представлена подпоследовательностью "F4 80 80 80", но вот "C0" не может быть представлен никакой последовательностью корректно сформированной последовательности. Потому на выходе должно быть "A\ufffd\ufffdA\ufffdA"
  • Для декодирования модифицированной последовательности UTF-8 / CESU-8 в Android P, используйте метод DataInputStream.readUTF() или JNI метод NewStringUTF()

Проверка сетевого имени по сертификату


    RFC 2818 описывает два способа сопоставления доменого имени с сертификатом: использование доступных имён внутри поля subjectAltName (SAN) или, если оно отсутствует, использование commonName (CN).

    Однако в RFC 2818 использование CN было объявлено устаревшим. По этой причине Android больше не будет пытаться использовать CN. Для проверки сетевого имени сервер должен предоставить сертификат с правильным SAN. Сертификаты, не имеющие SAN, совпадающим с сетевым именем, более не будут считаться доверенными.

Поиск сетевых адресов может приводить к проблемам сетевого взаимодействия

    Операции поиска сетевых адресов, которым требуется разрешение сетевых имён (что вызвает сетевые I/O), являются блокирующими. Блокирующие операции в основном потоке могут приводить к паузам и зависаниям.

    Класс StrictMode — это инструмент разработчика, позволяющий находить проблемы в коде. Теперь StrictMode может определять сетевые проблемы в сценарии разрешения сетевых имён при поиске сетевых адресов.

    Разработчикам нельзя распространять приложения со включенным StrictMode. В противном случае при использовании методов detectNetwork() или detectAll() (применение политики детектирования сетевых проблем) в приложениях могут возникать новые исключения, вроде NetworkOnMainThreadException.

    Разрешение числовых IP адресов не является блокирующей операцией и оно работает точно также, как и на версиях до Android P.

Комментариев нет:

Отправить комментарий