Background
I'm working on an Android app that controls the screen rotation. The app is available on the Google Play store. To control the screen rotation, the app disables system auto rotation and changes the values of USER_ROTATION. The source code is available via Mercurial/hg.
Problem
While the app works fine on my phone, a rooted Sony Xperia M, it crashes on a friend's Samsung Galaxy S3 running Android 4.3. The crash occurs outside of my code, so I don't get a crash report in the Google Play Store, and the stack trace only shows external code that I don't have access to.
java.lang.SecurityException: Permission Denial: get/set setting for user asks to run as user -2 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL at android.os.Parcel.readException(Parcel.java:1431) at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:185) at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137) at android.content.ContentProviderProxy.call(ContentProviderNative.java:602) at android.provider.Settings$NameValueCache.getStringForUser(Settings.java:934) at android.provider.Settings$System.getStringForUser(Settings.java:1162) at android.provider.Settings$System.getIntForUser(Settings.java:1232) at com.android.internal.policy.impl.WindowOrientationListener$ScreenOrientationEventListenerImpl.onSensorChanged(WindowOrientationListener.java:501) at android.hardware.SystemSensorManager$SensorE
This stack trace implies that the system auto rotation is still running. It also shows the OS code is trying to read an int system setting as a particular user after receiving a screen orientation change event. So I suspect the problem is related to me disabling ACCELEROMETER_ROTATION or changing USER_ROTATION, both of which are int
system settings.
Troubleshooting
- I checked other questions about this error. Most of them only explain what the error means without providing any solution. I couldn't find any with the exact same call stack trace.
- I checked the AOSP code for
WindowOrientationListener
, but it doesn't contain the inner class in which the error occurs,ScreenOrientationEventListenerImpl
. The Samsung phone probably uses a custom version of the code, most likely in part because it has a non-AOSP feature, Smart Rotation. - I don't think my code is doing any user-specific stuff; it's just using normal Android APIs.
- I tested the app on a non-rooted Sony Xperia M and a Sony Xperia Ray, and it was fine on them.
- I tested the app on 4 different Samsung Galaxy S3s using Samsung Remote Test Lab.
- I tried to find the source code where the error is occurring. I found a smali file, which at a glance indicates that it's trying to read the setting
"intelligent_rotation_mode"
as user-0x2
, which is interesting since I'm not touching that presumably-Samsung-specific setting. I also downloaded a copy of the official source code, but it didn't seem to contain the relevant file.
The app was using a local copy of
com.android.internal.policy.impl.WindowOrientationListener
from AOSP. However, the local copy was still using the original package,com.android.internal.policy.impl
. It turned out that when the app tried to use this local copy of the class, it was actually using the original system version with the same fully-qualified name. So the problem was the app was accidentally directly using the phone's built-inWindowOrientationListener
.