Since this turned out to be a long read, I’ll start with a very truncated version:
Are native processes not allowed to create/edit files created by their spawning java process regardless of having appropriate location/ permission/ file ownership?
The full question:
My application consists of a set of native binaries compiled with the NDK toolchain and a typical java Android interface. The native programs are packaged in the /assets folder and copied by the java application out into a /data/data/com.domain.app/nativeApplication folder.
There are two native application in question. One which modifies a jpeg created by the java layer, and a second which analyzes that jpeg and returns an int as output. The issue is this: When called by the java layer, the jpeg modifier doesn’t work.
I’ve done a good amount of troubleshooting on it already so I’ll try to dissuade you from some of the obvious potential answers starting with the most obvious.
Correct Compilation:
Through adb shell I can call both of the programs in question, as is, from the phone’s disk. The second image analyzer program runs without a hitch when called either via adb or as designed in the software IF I do the intermediary step manually from adb.
Permissions:
Jpg Permission – The application has permission to write to external storage. I’ve tried to have the file read in from both the SDcard and /data/data/com.domain.app/nativeApp/img/name.jpg; no joy. As stated the second program operates as designed when the image is in either location, if I manually run the first program through adb.
File/Folder Permissions: All of the folders in ~/nativeApplication/* have been created BY the android application itself, it is the owner and it has chmodded all of the sub-directories and files to 777.
Supporting Code:
Calling the jpg converter process:
NativeSetup.changePermission("/data/data/com.domain.program/nativeApp/img/img1.jpg");
try {
Process jpegConvert = Runtime.getRuntime().exec("/data/data/com.domain.program/nativeApp/bin/jpegtransformer -opts /data/data/com.domain.program/nativeApp/img/img1.jpg > /data/data/com.domain.program/nativeApp/img/img2.jpg");
jpegConvert.waitFor();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
Call used to create the files in ~/nativeApp/*
private static void copyFile(String assetPath, String localPath, Context context) {
try {
InputStream in = context.getAssets().open(assetPath);
FileOutputStream out = new FileOutputStream(localPath);
int read;
byte[] buffer = new byte[4096];
while ((read = in.read(buffer)) > 0) {
out.write(buffer, 0, read);
}
chmod call: (it works according to ls -l through adb)
static void changePermission(String localPath) {
try {
Process chmod = Runtime.getRuntime().exec("/system/bin/chmod 777 " +localPath);
chmod.waitFor();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
out.close();
in.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Permissions of the file the program can’t edit and then output a changed copy:
~/nativeApp/img $ ls -l
-rwxrwxrwx app_89 app_89 93061 2011-07-23 18:38 img1.jpg
Permission of the application that can’t edit the above jpg:
~/nativeApp/bin $ ls -l jpegtransformer
-rwxrwxrwx app_89 app_89 95268 2011-07-23 18:01 jpegtransformer
Permissions of folders in ~/nativeApp/
~/nativeApp $ ls -l
drwxrwxrwx app_89 app_89 2011-07-23 17:57 bin
drwxrwxrwx app_89 app_89 2011-07-23 18:27 img
Theories:
At this point my only viable theory is that there is some android policy not governed by chmod which is keeping the jpegtransformer from editing the image when called by the java layer. Since the image analyzer doesn’t change the image I imagine it skirts this? Are native processes not allowed to create files? Any ideas would be great. Sorry for the long read.
-SS
I think your problem is not related to permissions – you try to redirect the output using
>, while this is a shell operator and does not work from java. grab the process output stream and write it to a file using Java standard file I/O API.Though I’m not sure this is the problem, you shouldn’t have problem to modify files in your app folder and the issue I described is an issue I met more than once.