Где в рамках платформы проверяются разрешения приложений с мгновенным запуском Android?

Другие вопросы по этой теме были заданы здесь:

Классы для проверки разрешений Android

как проверяются разрешения безопасности Android при запуске -время?

Как Android применяет разрешения?

Но ни один из них не отвечает на то, что я пытаюсь выяснить. Я хочу знать, где именно я могу найти функции или методы, которые буквально проверяют разрешения, которые я запрашиваю, чтобы узнать, разрешено ли мне иметь это разрешение. В частности, я хочу узнать, что происходит с разрешениями Android Instant Apps, поскольку IA разрешает только часть всех разрешений Android (список можно найти здесь https://developer.android.com/topic/google-play-instant/faqs).

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

Я хочу понять и посмотреть, где это происходит, исходный код этих проверок, особенно для Instant Apps. Я начал с функции checkSelfPermissions(), используемой при реализации разрешений среды выполнения Android. Благодаря функции трассировки вызова функции в Android Studio и внешней ссылке (http://androidxref.com) я вернулся к насколько это возможно, пока не нашел файл Context.java (http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/content/Context.java), в котором есть объявления прототипа с комментариями для каждой функции.

public abstract int checkPermission(@NonNull Разрешение строки, int pid, int uid);

Я просто не знаю, где найти определения с фактическим телом функции и кодом для нее. В Context.java их нет. И я думаю, что я все больше и больше спускаюсь в кроличью нору и слишком низкоуровневый с этим: http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/java/android/content/pm/PackageManager.java#532

http://androidxref.com/8.1.0_r33/xref/frameworks/native/libs/binder/IPermissionController.cpp#39

http://androidxref.com/8.1.0_r33/xref/frameworks/native/libs/binder/IPermissionController.cpp#39

особенно последние два, которые я не только не знаю, на правильном ли я пути с ними, но я пытаюсь выяснить, что функция remote()->transact сейчас и где она определена, но мы находимся в Android Родная территория С++ теперь...

Любая помощь или указатели будут очень признательны, ведь не так уж сложно просто просмотреть исходный код AOSP, верно?


person Emilian Cebuc    schedule 08.08.2018    source источник
comment
Начните здесь: androidxref.com/8.1.0_r33/ и developers.google.com/android/reference/com/ гугл/андроид/gms/   -  person TWL    schedule 10.08.2018
comment
Боюсь, это было не очень полезно, потому что, в конце концов, вы в основном дали мне ссылки на то же самое, на что я уже смотрел, но я ценю эту мысль, в конце концов я решил проблему (см. мой собственный ответ ниже, если интересно)   -  person Emilian Cebuc    schedule 26.08.2018


Ответы (1)


Для дальнейшего использования, в конце концов мне удалось это решить. Это заняло намного больше времени, чем я думал, но, как это бывает со многими вещами, ответ был намного проще, чем я думал. Оказывается, да, я определенно спускался по многим кроличьим норам, но только до определенного момента. Весь этот процесс поиска был на самом деле полезен для понимания того, где должен лежать ответ.

Таким образом, первым шагом был успешный поиск реальных правильных «низкоуровневых» реализаций проверки разрешений или действий по предоставлению разрешений, а функции — grantRuntimePermission и checkUidPermission, обе в классе PackageManagerService.java. Вот интересные моменты каждой функции: http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java#5655

http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java#5335

Именно там выполняются проверки, но система каким-то образом уже «знает» о разрешении и о том, является ли оно временем выполнения или нет, мгновенным или нет. Важный момент (который также как бы намекнул мне, что в конце концов я нашел ответ) — посмотреть на созданные объекты BasePermission.

Я обнаружил, что ОС Android обрабатывает разрешения более модульным образом, где каждое разрешение не остается простой строкой для проверки, а преобразуется в независимый объект BasePermission. Это придает ему более определенную важность, поскольку эти объекты теперь содержат, помимо имени разрешения, такие атрибуты, как имя sourcePackage, тип разрешения, UID которому принадлежит разрешение и, что наиболее важно, protectionLevel среди прочих. Вот класс BasePermission.java:

http://androidxref.com/8.1.0_r33/xref/frameworks/base/services/core/java/com/android/server/pm/BasePermission.java#23

Казалось, что объекты BasePermission создаются в каждом приложении на основе этого приложения. Таким образом, в контексте приложения с мгновенным запуском ОС Android присваивает уровень разрешения каждому отдельному объекту разрешения соответственно, когда узнает, что приложение в данном случае является мгновенным. Вот важный фрагмент кода:

if (isUidInstantApp) {
   BasePermission bp = mSettings.mPermissions.get(permName);
   if (bp != null && bp.isInstant()) {
       return PackageManager.PERMISSION_GRANTED;
   }
} else {
   return PackageManager.PERMISSION_GRANTED;
}

Таким образом, можно увидеть, как он создает объект BasePermission на основе permName из списка/массива предварительно созданных объектов разрешений (mSettings.mPermissions), которые Система каким-то образом создает только для текущего приложения. Это отвечает только на вопрос «где выполняется проверка разрешений?» вопрос, но теперь проблема в том, "откуда система знает, как создавать объекты BasePermission и назначать каждому из них правильный уровень защиты?". Первоначально я совершенно не мог найти, где заполняется список «mPermissions». И тут меня осенило: на самом деле мне не нужно было этого знать.

Все разрешения Android и их имена определены в глобальном файле AndroidManifest.xml. Всякий раз, когда вы используете разрешения в коде своего приложения, вы вызываете строку Manifest.permission.PERMISSION_NAME, верно? Я думал, что манифест будет содержать только имена каждого разрешения, объявленные в виде строки. Чего я не ожидал, так это того, что единственная другая крошечная часть информации, объявляемая манифестом, это (как вы уже догадались)... значение protectionLevel для каждого разрешения. Для каждого разрешения будет указано, является ли оно «нормальным» разрешением, а не «опасным», а также может ли оно использоваться для мгновенных приложений или нет. И, как и ожидалось, только 10 (на момент написания этой статьи) определенных разрешений для мгновенных приложений из официальных документов имели атрибут «мгновенный» помимо других доступных уровней защиты. Вот один из них: http://androidxref.com/8.1.0_r33/xref/frameworks/base/core/res/AndroidManifest.xml#773

Именно так система знает, как создавать объекты BasePermission, где бы она это ни делала. И там был белый список, который я искал.

Даже если бы я посмотрел на манифест как на первый шаг в своем исследовании, я, вероятно, не знал бы, что ответ был прямо передо мной. Знание объектов BasePermission имело решающее значение для понимания того, как реализована модель разрешений и проверки.

Следующим шагом теперь было бы найти, где именно система создает объект базового разрешения на основе этих строк уровня защиты в манифесте. Я предполагаю, что должна быть ассоциация этих строк с двоичным целым числом, таким как «нормальный» или «нормальный | мгновенный», число, которое затем используется классом BasePermission для построения уровня защиты объектов и в конечном итоге определяет, являются ли они мгновенное.

person Emilian Cebuc    schedule 26.08.2018