summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/java/android/accounts/AccountManagerService.java2
-rw-r--r--core/java/android/app/ContextImpl.java3
-rw-r--r--core/java/android/content/Context.java8
-rw-r--r--core/java/android/content/ContextWrapper.java5
-rw-r--r--core/java/android/content/pm/PackageParser.java14
-rw-r--r--core/java/android/content/pm/ServiceInfo.java7
-rw-r--r--core/res/AndroidManifest.xml19
-rw-r--r--core/res/res/values/attrs_manifest.xml10
-rw-r--r--core/res/res/values/public.xml5
-rwxr-xr-xcore/res/res/values/strings.xml13
10 files changed, 74 insertions, 12 deletions
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index 22e454f..ba05ee7 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -896,7 +896,7 @@ public class AccountManagerService
private void sendAccountsChangedBroadcast(int userId) {
Log.i(TAG, "the accounts changed, sending broadcast of "
+ ACCOUNTS_CHANGED_INTENT.getAction());
- mContext.sendBroadcast(ACCOUNTS_CHANGED_INTENT, userId);
+ mContext.sendBroadcastToUser(ACCOUNTS_CHANGED_INTENT, userId);
}
public void clearPassword(Account account) {
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 74fce62..3c8a290 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -966,9 +966,8 @@ class ContextImpl extends Context {
}
}
- /** @hide */
@Override
- public void sendBroadcast(Intent intent, int userId) {
+ public void sendBroadcastToUser(Intent intent, int userId) {
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
intent.setAllowFds(false);
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 8597993..af8b213 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -988,12 +988,14 @@ public abstract class Context {
public abstract void sendBroadcast(Intent intent);
/**
- * Same as #sendBroadcast(Intent intent), but for a specific user. Used by the system only.
+ * Same as #sendBroadcast(Intent intent), but for a specific user. This broadcast
+ * can only be sent to receivers that are part of the calling application. It
+ * requires holding the {@link android.Manifest.permission#INTERACT_ACROSS_USERS}
+ * permission.
* @param intent the intent to broadcast
* @param userId user to send the intent to
- * @hide
*/
- public void sendBroadcast(Intent intent, int userId) {
+ public void sendBroadcastToUser(Intent intent, int userId) {
throw new RuntimeException("Not implemented. Must override in a subclass.");
}
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 6b950e0..7738132 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -312,10 +312,9 @@ public class ContextWrapper extends Context {
mBase.sendBroadcast(intent);
}
- /** @hide */
@Override
- public void sendBroadcast(Intent intent, int userId) {
- mBase.sendBroadcast(intent, userId);
+ public void sendBroadcastToUser(Intent intent, int userId) {
+ mBase.sendBroadcastToUser(intent, userId);
}
@Override
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index f8898c1..3ce7c78 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -2703,7 +2703,7 @@ public class PackageParser {
return null;
}
- final boolean setExported = sa.hasValue(
+ boolean setExported = sa.hasValue(
com.android.internal.R.styleable.AndroidManifestService_exported);
if (setExported) {
s.info.exported = sa.getBoolean(
@@ -2729,6 +2729,18 @@ public class PackageParser {
false)) {
s.info.flags |= ServiceInfo.FLAG_ISOLATED_PROCESS;
}
+ if (sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestService_singleUser,
+ false)) {
+ s.info.flags |= ServiceInfo.FLAG_SINGLE_USER;
+ if (s.info.exported) {
+ Slog.w(TAG, "Service exported request ignored due to singleUser: "
+ + s.className + " at " + mArchiveSourcePath + " "
+ + parser.getPositionDescription());
+ s.info.exported = false;
+ }
+ setExported = true;
+ }
sa.recycle();
diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java
index 7ee84ab..1aaceb4 100644
--- a/core/java/android/content/pm/ServiceInfo.java
+++ b/core/java/android/content/pm/ServiceInfo.java
@@ -49,6 +49,13 @@ public class ServiceInfo extends ComponentInfo
public static final int FLAG_ISOLATED_PROCESS = 0x0002;
/**
+ * Bit in {@link #flags}: If set, a single instance of the service will
+ * run for all users on the device. Set from the
+ * {@link android.R.attr#singleUser} attribute.
+ */
+ public static final int FLAG_SINGLE_USER = 0x0004;
+
+ /**
* Options that have been set in the service declaration in the
* manifest.
* These include:
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9253f24..d636713 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -760,6 +760,25 @@
android:label="@string/permlab_getTasks"
android:description="@string/permdesc_getTasks" />
+ <!-- Allows an application to call APIs that allow it to do interactions
+ across the users on the device, using singleton services and
+ user-targeted broadcasts. This permission is not available to
+ third party applications. -->
+ <permission android:name="android.permission.INTERACT_ACROSS_USERS"
+ android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
+ android:protectionLevel="signature|system|development"
+ android:label="@string/permlab_interactAcrossUsers"
+ android:description="@string/permdesc_interactAcrossUsers" />
+
+ <!-- @hide Fuller form of {@link android.Manifest.permission#INTERACT_ACROSS_USERS}
+ that removes restrictions on where broadcasts can be sent and allows other
+ types of interactions. -->
+ <permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"
+ android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
+ android:protectionLevel="signature"
+ android:label="@string/permlab_interactAcrossUsersFull"
+ android:description="@string/permdesc_interactAcrossUsersFull" />
+
<!-- Allows an application to get full detailed information about
recently running tasks, with full fidelity to the real state.
@hide -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index f971d39..8bc1e79 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1275,6 +1275,16 @@
that is isolated from the rest of the system. The only communication
with it is through the Service API (binding and starting). -->
<attr name="isolatedProcess" format="boolean" />
+ <!-- If set to true, a single instance of this service will run for
+ all users. That instance will run as user 0, the default/primary
+ user. When the app running in processes for other users interacts
+ with this service (by binding to it, starting it, etc) they will
+ always interact with the instance running for user 0. Enabling
+ single user mode forces "exported" of the service to be false, to
+ avoid introducing multi-user security bugs. You must hold the
+ permission {@link android.Manifest.permission#INTERACT_ACROSS_USERS} in order
+ to use this feature. -->
+ <attr name="singleUser" format="boolean" />
</declare-styleable>
<!-- The <code>receiver</code> tag declares an
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index b9b8a1b..4881a94 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3660,7 +3660,7 @@
<public type="style" name="Widget.DeviceDefault.Light.MediaRouteButton" id="0x010301d8" />
<!-- ===============================================================
- Resources added in version 17 of the platform (Jelly Bean MRx?)
+ Resources added in version 17 of the platform (Jelly Bean MR1)
=============================================================== -->
<eat-comment />
<public type="attr" name="supportsRtl" />
@@ -3679,5 +3679,6 @@
<public type="attr" name="layout_alignParentEnd" />
<public type="attr" name="listPreferredItemPaddingStart" />
<public type="attr" name="listPreferredItemPaddingEnd" />
-
+ <public type="attr" name="singleUser" />
+
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index b757fe8..b369744 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -543,6 +543,19 @@
about currently and recently running tasks. This may allow the app to
discover information about which applications are used on the device.</string>
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE] -->
+ <string name="permlab_interactAcrossUsers">interact across users</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE] -->
+ <string name="permdesc_interactAcrossUsers">Allows the app to perform actions
+ across different users on the device. Malicious apps may use this to violate
+ the protection between users.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE] -->
+ <string name="permlab_interactAcrossUsersFull">full license to interact across users</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE] -->
+ <string name="permdesc_interactAcrossUsersFull">Allows all possible interactions across
+ users.</string>
+
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=50] -->
<string name="permlab_getDetailedTasks">retrieve details of running apps</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE] -->