CommonsWare
CommonsWare

Reputation: 1007474

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

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:

Upvotes: 17

Views: 3105

Answers (2)

Maurice Lam
Maurice Lam

Reputation: 1794

While @Bobbake4's answer that the check is based on UID is correct,

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.

I believe the first part about LOCAL_PRIVILEGED_MODULE is irrelevant. The directory location doesn't control which UID Settings get, but instead that is set by the sharedUserId in the manifest. As noted in the documentation, this only works if the app is signed using the same certificate as the platform.

Upvotes: 0

Bobbake4
Bobbake4

Reputation: 24857

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.

Upvotes: 9

Related Questions