Android N lets you link an activity of yours into your app's page in
Settings. Just add an <intent-filter>
for android.intent.action.APPLICATION_PREFERENCES
. Android N's Settings app will look for the activity in your app that
has that <intent-filter>
. If Settings finds one, it will add a gear
icon to your app's page in Settings, and if the user taps the gear, they
will be taken to your designated activity.
I was worried about security, and so I filed an issue, looking for a permission we could use with android:permission
to allow Settings to start our activity, but not allow other apps to start our activity (e.g., WRITE_SECURE_SETTINGS
).
cketti then pointed out that you could just mark the activity as not exported, via android:exported="false"
. Much to my surprise, this works.
How can the Settings app start an activity that is marked as not exported?
I can certainly see there being a permission that controls this. However, a quick read of the Settings app's manifest (master branch, n-developer-preview-5 branch) didn't turn up anything obvious.
So:
Is there a permission that allows an app to start a non-exported component of another app? If so, which is it?
If not, how is Settings pulling this off?
I would guess there is nothing in the manifest that gives an app the permission to call exported activities. I believe the way it's accomplishing this is by setting LOCAL_PRIVILEGED_MODULE := true
in the Android.mk file for the Settings application. This flag will give an application system level permissions and place it in the system/priv-app/
directory during OS compile time.
If you look at frameworks/base/core/java/android/app/ActivityManager.java
for the method checkComponentPermission
you can see that if the UID is that of the SYSTEM, component permission is granted regardless of the exported setting.