0

We have implemented Android M's Direct Share support in our app but getting SecurityException when we try to access content provider in our ChooserTargetService implementation. We don’t want to set “exported=true” for content provider….so seems like we need to invoke grantUriPermission(). What’s not clear, if this is the correct approach, is what package name to pass in to this (have tried various ones unsuccessfully).

Following is exception we get:

W Binder  : Caught a RuntimeException from the binder stub implementation.
W Binder  : java.lang.SecurityException: Permission Denial: reading <my content provider> uri     <content provider uri> from pid=0, uid=1000 requires the provider be exported, or grantUriPermission()
W Binder  :     at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:605)
W Binder  :     at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:480)
W Binder  :     at android.content.ContentProvider$Transport.query(ContentProvider.java:211)
W Binder  :     at android.content.ContentResolver.query(ContentResolver.java:491)
W Binder  :     at android.content.ContentResolver.query(ContentResolver.java:434)
W Binder  :     at <my package>.MyChooserTargetService.onGetChooserTargets(MyChooserTargetService.java:66)
W Binder  :     at android.service.chooser.ChooserTargetService$IChooserTargetServiceWrapper.getChooserTargets(ChooserTargetService.java:147)
W Binder  :     at android.service.chooser.IChooserTargetService$Stub.onTransact(IChooserTargetService.java:67)
W Binder  :     at android.os.Binder.execTransact(Binder.java:453)
John O'Reilly
  • 10,000
  • 4
  • 41
  • 63

2 Answers2

1

I had the same problem (see my comment) and have since found a solution to this particular problem.

TL;DR

Set your provider to exported=true and add the following line to its manifest section:

android:permission="android.permission.BIND_CHOOSER_TARGET_SERVICE"

so it looks a bit like:

<provider
    android:name=".db.MyContentProvider"
    android:authorities="@string/authority"
    android:exported="true"
    android:readPermission="android.permission.BIND_CHOOSER_TARGET_SERVICE"/>

Longer version

You can set your ContentProvider to exported=true without worrying about other apps accessing your data so long as you also have a permission (or readPermission or writePermission) set for your provider1.

The difficulty, of course, is to know how to give your ChooserTargetService a permission since you don't control what permissions it requests as it runs on the android system's binder thread.

However, there is one permission that we know only the android system's Direct Share chooser can obtain: android.permission.BIND_CHOOSER_TARGET_SERVICE. This permission is secured by signature so can't be obtained by anything other than a system process.

The only thing I'm wondering is what is stopping another App implementing its own ChooserTargetService, gaining the permission and using your ContentProvider? Well, I checked that but it seems the system doesn't allow it via a SecurityException...which is good, but still puzzling to me!

Community
  • 1
  • 1
aoemerson
  • 147
  • 9
0

So, found solution in following....in particular: "If a Thread is started by any component of the application that has the provider, then you can access the ContentProvider without any SecurityException."

How would a thread created by an app be considered a different app from the app's ContentProvider?

Community
  • 1
  • 1
John O'Reilly
  • 10,000
  • 4
  • 41
  • 63
  • Hi John, could you expand on this answer a little bit please, maybe some sample code? I basically have **exactly** the same issue as you but I can't get to a solution from the link you posted. I understand the reason behind the `SecurityException` but I don't know how to grant the Binder process permission to access my `ContentProvider`. TIA! – aoemerson Jul 01 '16 at 15:49
  • 1
    @aoemerson I created Thread (t) in which I made the call to getContentResolver().query() and then ran t.start(); t.join(); – John O'Reilly Jul 02 '16 at 18:52