After going through several posts I figured out I could send the intent with the following line of code (second line used for debugging):
int ret = system("am broadcast -a android.intent.action.MIKE_ACCESSED --user 0");
__android_log_print(ANDROID_LOG_DEBUG, "gxp18", "Shell command returned %i", ret);
Unfortunately, this returns always (No matter what is the command used in the system("...")):
Shell command returned 32512
Interestingly, I can successfully send the intent through adb using:
adb shell am broadcast -a android.intent.action.MIKE_ACCESSED
Notice! I am not using NDK. The piece of code I reported in the post is a modification of a portion of code in the Android Framework. In particular, it is part of one of the Android services. I am working with the AOSP and modifying part of the source code.
As I remembered, you cannot execute am command directly in your app due to the permission check in Android 5.0 version.
These two scenarios are different. The command you execute from shell has the shell UID and GID, which is like following.
uid=2000(shell) gid=2000(shell) groups=1003(graphics),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats) context=u:r:shell:s0
The command you do in your code with system()
call is executed with your app's UID and GID which has less permissions in comparison with shell UID and GID.
So you will end with a failed code. You could optimize your design to send this intent from your Java code. If you insist to do in your JNI, a better solution might be calling a static void method in your own Application
. In that way, you don't have to worry about the Context
which isn't accessible in JNI most of time.
public class MyApplication extends Application {
private static Context context;
@Override
public void onCreate() {
super.onCreate();
context = this;
}
public static void sendIntent() {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.google.com"));
context.startActivity(intent);
}
}
1) Disable SELinux (Set in Permissive mode)
2) Modify ActivityManagerNative.java to bypass userId check
Enjoy :)