2

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.
Community
  • 1
  • 1
Sam
  • 40,644
  • 36
  • 176
  • 219
  • is your phone (the one that works" rooted? – Jeffrey Blattman Nov 24 '14 at 22:03
  • @JeffreyBlattman, yes. I also tested it on a Sony Xperia Ray running CyanogenMod, and it worked on that, too. (I don't know if CyanogenMod comes with root; I guess it might.) Do you think the root is covering up the problem? I figure the official Samsungs that I remotely tested on wouldn't be rooted. Also, I have SuperSU installed, so shouldn't it have prompted me if the app tried to do anything root-related? – Sam Nov 24 '14 at 22:06
  • 2
    yes, absolutely. it seems that the operation you are invoking requires a permission that is normally not granted to apps running without root. the specific error is hard to parse, but it seems like something is checking that the calling user ID is the same as it's user ID, and if not, is not granting the permission. – Jeffrey Blattman Nov 24 '14 at 22:12
  • @JeffreyBlattman, yeah; if you look at the bottom of the stack trace, you can see that the OS is trying to `getIntForUser` in response to the phone's orientation changing. So it seems that something I've done is causing that operation to fail for some reason. – Sam Nov 25 '14 at 00:05

1 Answers1

2

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-in WindowOrientationListener.

Sam
  • 40,644
  • 36
  • 176
  • 219
  • 1
    @MrsEd, I just changed the package name of `WindowOrientationListener` to my own package. – Sam Nov 24 '15 at 20:11