How Can the Settings App Start an App’s Non-Exported Activity?

Issue

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?

Solution

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.

Answered By – Bobbake4

Leave a Comment