Reputation: 10485
Fellow Developers!
I have a sync adapter in my app and a corresponding sync service. I have declared everything, including the sync service, according to Google example code. The greater picture looks something like this:
<service
android:name="com.myapp.SyncService"
android:exported="true"
android:process=":sync">
<intent-filter>
<action
android:name="android.content.SyncAdapter"/>
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/syncadapter" />
</service>
While it makes sense to set the android:exported
attribute to true
on the service (enabling the Android system to reach it), I'm a bit puzzled on how to tie it down in terms of access rights. I don't want anyone else but my app and the Android system to have access to the service.
Maybe a bit naively I have created my own permission for this:
<permission
android:name="com.myapp.permission.SYNC_ADAPTER"
android:protectionLevel="signatureOrSystem" />
But reading up a bit on the protectionLevel
makes me wonder even more. Google says:
Please avoid using this option [...] "signatureOrSystem" permission is used for certain special situations where multiple vendors have applications built into a system image and need to share specific features explicitly because they are being built together.
The described scenario is far from my use case. The question then remains:
How do I secure my sync service so that the Android system, but no third party apps, can access it?
Any clarification would be greatly appreciated!
Upvotes: 11
Views: 962
Reputation: 3737
You can safely set exported=false
for both services
SyncAdapter
AccountAuthenticator
intentsThe system can still call the SyncAdapter
Service via intents.
exported
guideIf
false
, the activity can be launched ... [by] privileged system components.
I.e. you don't need to struggle with exported=true.
targetVersion: 30
)targetVersion: 31
)Old answer
The following is (for me) irrelevant as the above works.
I interpreted the replies in this thread this way:
Requesting this permission (see example) in an exported
service (see below) should only allow apps signed with your signature - and the system - to call this service.
If you use exported=false
then the system cannot call your service, i.e. Synchronization won't start if your app is closed(?)
<permission
android:name="com.myapp.USE_SYNC_AND_AUTHENTICATOR"
android:protectionLevel="signature" />
<application>
<!-- Export sync and auth to allow the Android System to call them. -->
<!-- Protect it using a signature permission. -->
<service
android:name="com.myapp.SyncService"
android:exported="true"
android:process=":sync"
android:permission="com.myapp.USE_SYNC_AND_AUTHENTICATOR">
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/sync_adapter" />
</service>
<service>..authenticator..</service>
</application>
Upvotes: 1
Reputation: 1
The 'signature' protection level should be sufficient for your use case, which grants access to the system package. 'signatureOrSystem' also grants access to apps built into the system image.
Source code: see grantSignaturePermission()
method
https://android.googlesource.com/platform/frameworks/base/+/a029ea1/services/java/com/android/server/pm/PackageManagerService.java
Upvotes: 0
Reputation: 1746
It doesn't look like there is a SyncAdapter permission. I'm guessing that we can safely ignore the error. See the bug filed here: https://code.google.com/p/android/issues/detail?id=37280
Upvotes: 0
Reputation: 359
beworker is quite right. I have used signature permission and the system is able to sync without any trouble.
Upvotes: 3
Reputation: 6410
I have the same problem. Looking at this example source code here as a guide https://android.googlesource.com/platform/packages/apps/Exchange/+/ics-mr0/AndroidManifest.xml it seems to be that the sync adapters have plainly exported="true" without any permissions.
Upvotes: 0