Created
April 11, 2014 23:43
-
-
Save brendanzagaeski/10510015 to your computer and use it in GitHub Desktop.
Using the app "Move" feature on some Android phones leads to broken permissions on `lib/` directory
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Using the app "Move" feature on some Android phones leads to broken permissions on `lib/` directory | |
Starting around Android 15 (Ice Cream Sandwich), or possibly earlier, the "Move to SD" feature on Android underwent some changes. Many modern phones do not support the feature at all. Others support it, but inconsistently (see also [1]). | |
[1] http://beranger.org/2013/06/14/android-storage-what-nobody-bothered-to-tell-you/ | |
On an HTC One X running Android 4.1.1, moving an app to USB Storage and then back to internal storage changes the permissions of the app's `/data/data/package_name/lib` directory, breaking the app if it depends on native libraries. This problem affects Xamarin.Android apps and Java NDK apps alike. | |
## Results for the Java "hello-jni" example that comes with the Android NDK | |
### `lib/` directory permissions before moving the app | |
$ adb shell ls -ld /data/data/com.example.hellojni/lib | |
drwxr-xr-x system system 2014-04-11 17:58 lib | |
### `lib/` directory permissions after moving the app to USB storage | |
$ adb shell ls -ld /data/data/com.example.hellojni/lib | |
lrwxrwxrwx system system 2014-04-11 18:04 lib -> /mnt/asec/com.example.hellojni-1/lib | |
### `lib/` directory permissions after moving the app _back_ to internal storage | |
$ adb shell ls -ld /data/data/com.example.hellojni/lib | |
drwx------ system system 2014-04-11 18:05 lib | |
### Running the app | |
If you try to run the app after this last step, it fails with: | |
> E/AndroidRuntime( 7398): Caused by: java.lang.UnsatisfiedLinkError: Couldn't load hello-jni: findLibrary returned null | |
## Attempted workarounds that fail | |
Unfortunately, it's not possible to fix these file permissions without rooting the device. Even the app itself is not allowed to change the permissions: | |
$ adb shell run-as com.example.hellojni chmod 755 /data/data/com.example.hellojni/lib | |
Unable to chmod /data/data/com.example.hellojni/lib: Operation not permitted | |
Moreover, there's not even a way to get around the problem by keeping an extra copy of the library somewhere else because the system will only allow apps to load native libraries from the `/data/data/` directory. Attempting to load a library from another location via `System.load()` results in a slightly different error: | |
> E/AndroidRuntime(13155): Caused by: java.lang.UnsatisfiedLinkError: Cannot load library: load_segments[906]: 253 failed to map segment from 'libhello-jni.so' | |
(See http://stackoverflow.com/questions/6291087/android-load-library-error-failed-to-map-segment) | |
## Conclusions | |
This appears to be a bug in the operating system. One small silver lining is that moving the app _back_ to the USB Storage (a.k.a. "phone storage") allows the app to work again. Long story short, for users who want to move apps that use native libraries (including Xamarin.Android apps) back to the internal storage on these "buggy" devices, they will need to reinstall them. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment