SecurityException: отказ в разрешении

Фон

Я работаю над приложением для Android, которое управляет поворотом экрана. Приложение доступно в магазине Google Play. Чтобы управлять поворотом экрана, приложение отключает автоматический поворот системы и изменяет значения USER_ROTATION. Исходный код доступен через Mercurial/hg.

Проблема

Хотя приложение отлично работает на моем телефоне Sony Xperia M с рут-правами, оно вылетает на Samsung Galaxy S3 друга под управлением Android 4.3. Сбой происходит за пределами моего кода, поэтому я не получаю отчет о сбое в магазине Google Play, а трассировка стека показывает только внешний код, к которому у меня нет доступа.

java.lang.SecurityException: Отказ в разрешении: получить/установить настройку для пользователя, который запрашивает запуск от имени пользователя -2, но звонит от пользователя 0; для этого требуется android.permission.INTERACT_ACROSS_USERS_FULL в android.os.Parcel.readException(Parcel.java:1431) в android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:185) в android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java: 137) в android.content.ContentProviderProxy.call(ContentProviderNative.java:602) в android.provider.Settings$NameValueCache.getStringForUser(Settings.java:934) в android.provider.Settings$System.getStringForUser(Settings.java:1162) ) в android.provider.Settings$System.getIntForUser(Settings.java:1232) в com.android.internal.policy.impl.WindowOrientationListener$ScreenOrientationEventListenerImpl.onSensorChanged(WindowOrientationListener.java:501) в android.hardware.SystemSensorManager$SensorE

Эта трассировка стека означает, что автоматическая ротация системы все еще работает. Это также показывает, что код ОС пытается прочитать системную настройку int от имени конкретного пользователя после получения события изменения ориентации экрана. Поэтому я подозреваю, что проблема связана с тем, что я отключил ACCELEROMETER_ROTATION или изменить USER_ROTATION, оба из которых < a href="http://developer.android.com/reference/android/provider/Settings.System.html#putInt(android.content.ContentResolver,%20java.lang.String,%20int)" rel="nofollow noreferrer ">int системные настройки.

Исправление проблем

  • Я проверил другие вопросы об этой ошибке. Большинство из них только объясняют, что означает ошибка, не предлагая никакого решения. Я не смог найти ни одного с точно такой же трассировкой стека вызовов.
  • Я проверил код AOSP для WindowOrientationListener, но он не содержит внутреннего класса, в котором возникает ошибка, ScreenOrientationEventListenerImpl. Телефон Samsung, вероятно, использует пользовательскую версию кода, скорее всего, отчасти потому, что он имеет функцию, отличную от AOSP, Умная ротация.
  • Я не думаю, что мой код делает что-то конкретное для пользователя; это просто использование обычных Android API.
  • Я протестировал приложение на Sony Xperia M без рута и Sony Xperia Ray, и на них все было в порядке.
  • Я протестировал приложение на 4 разных устройствах Samsung Galaxy S3, используя Samsung Remote Test Lab.
  • Я попытался найти исходный код, в котором возникает ошибка. Я нашел файл smali, который на первый взгляд указывает на то, что он пытается прочитать параметр "intelligent_rotation_mode" от имени пользователя -0x2, что интересно, поскольку я не касаюсь этого предположительно специфичная для Samsung настройка. Я также скачал копию официального исходного кода, но похоже, он не содержал соответствующего файла.

person Sam    schedule 24.11.2014    source источник
comment
ваш телефон (тот, который работает рутирован?   -  person Jeffrey Blattman    schedule 25.11.2014
comment
@JeffreyBlattman, да. Я также протестировал его на Sony Xperia Ray с CyanogenMod, и он тоже работал. (Я не знаю, поставляется ли CyanogenMod с рутом; думаю, да.) Как вы думаете, рут скрывает проблему? Я полагаю, что официальные Samsung, на которых я удаленно тестировал, не будут рутированы. Кроме того, у меня установлен SuperSU, поэтому разве он не должен был спрашивать меня, пыталось ли приложение сделать что-либо, связанное с root-правами?   -  person Sam    schedule 25.11.2014
comment
Да, конечно. кажется, что операция, которую вы вызываете, требует разрешения, которое обычно не предоставляется приложениям, работающим без root. Конкретную ошибку трудно разобрать, но кажется, что что-то проверяет, совпадает ли идентификатор вызывающего пользователя с его идентификатором пользователя, а если нет, то не предоставляет разрешение.   -  person Jeffrey Blattman    schedule 25.11.2014
comment
@JeffreyBlattman, да; если вы посмотрите на нижнюю часть трассировки стека, вы увидите, что ОС пытается getIntForUser в ответ на изменение ориентации телефона. Таким образом, кажется, что что-то, что я сделал, по какой-то причине привело к сбою этой операции.   -  person Sam    schedule 25.11.2014


Ответы (1)


Приложение использовало локальную копию com.android.internal.policy.impl.WindowOrientationListener из AOSP. Однако локальная копия по-прежнему использовала исходный пакет com.android.internal.policy.impl. Оказалось, что когда приложение пыталось использовать эту локальную копию класса, оно на самом деле использовало исходную системную версию с тем же полным именем. Таким образом, проблема заключалась в том, что приложение случайно напрямую использовало встроенный в телефон WindowOrientationListener.

person Sam    schedule 26.11.2014
comment
@MrsEd, я только что изменил имя пакета WindowOrientationListener на свой собственный пакет. - person Sam; 24.11.2015