How to create content-provider across user profiles?
android, multi-user, service
Solution
Using android:singleUser="true" with android:exported="true" is the right way to go, but there are some caveats to using this attribute.
First, ActivityManagerService (isSingleton method) will ignore this attribute unless your app has the INTERACT_ACCROSS_USERS permission.
Second (and this is where I think your problem is), your app must also be installed as a privileged app in the priv-app folder ('LOCAL_PRIVILEGED_MODULE := true' in Android.mk). Otherwise, the PackageParser will clear your 'android:exported' attribute.
if (sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestProvider_singleUser,
false)) {
p.info.flags |= ProviderInfo.FLAG_SINGLE_USER;
if (p.info.exported && (flags & PARSE_IS_PRIVILEGED) == 0) {
Slog.w(TAG, "Provider exported request ignored due to singleUser: "
+ p.className + " at " + mArchiveSourcePath + " "
+ parser.getPositionDescription());
p.info.exported = false;
}
}
NOTE: All of the above applies not just to Providers, but Services and Receivers as well.
UPDATE: It looks like the test for the package being a privileged app is only present in Android 5.0 and later. Earlier versions simply dropped the export attribute.
Problem
For an embedded project building on the AOSP source, I have a big chunk of data in one (system) app that has to be accessible to other apps. Yes, I know: the typical job for a content provider or service, but ... the same data (same single instance of that big chunk) has to be accessible to apps ON ALL USER PROFILES on the device! I already figured out that Android offers an android:singleUser="true" attribute for services, content-providers and receivers, but it has the annoying side-effect that it forces android:exported="false"! Hence I assume that one solution could be to have in my Manifest one content provider using android:singleUser="true" and a second one which is android:exported="true" and have that second just query the first for the actual data that the other app might need, but ... that seems so ugly and in my case - where the app with content-providers and services already exists for single-user Android, it will require quite some changes. I also tried flagging my complete (system) application as android:persistent="true", but this resulted in problems accessing some parts of /data/data where the big chunk of data resides (which I need to debug further to get to the root cause). So, my question: is there any easy / advised way to create a content-provider (and same question for services and receivers in the same app) such that the app really acts as a singleton across multiple users (without being a System Service, since we don't want to affect system stability by running our stuff as part of the SystemServer)?