summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2018-01-19 17:44:46 -0800
committerDianne Hackborn <hackbod@google.com>2018-03-05 16:59:21 -0800
commitdd027b3ab2087f4ccaf4e9d72472327f27789a1d (patch)
tree1f937eaea62c46d7f3758ccb73835acfa3c77ee9
parent081d3d2d89e7f73d01260ab92114814718614bea (diff)
Fix issue #72116995: Add permission guarding Service#startForeground
Now requires permission if targeting P. Note that this is a separate permission from the existing one that is required for instant apps to use foreground services. The reason for this is that their semantics are different (the instant apps permission is associated with an app op for control over what the app is allowed, while the regular app permission is just a normal permission that is always granted and only there for auditing of apps), and there are probably going to be cases where a developer will want to use a foreground service in the full version of their app but not as an instant app. Bug: 72116995 Test: atest CtsAppTestCases Change-Id: I883c9515c307ed8e39f0bf888c4045944c8183ac
-rw-r--r--api/current.txt1
-rw-r--r--core/java/android/app/Service.java12
-rw-r--r--core/java/android/os/Build.java8
-rw-r--r--core/res/AndroidManifest.xml9
-rw-r--r--core/res/res/values/strings.xml5
-rw-r--r--core/tests/coretests/AndroidManifest.xml1
-rw-r--r--packages/MtpDocumentsProvider/AndroidManifest.xml1
-rw-r--r--packages/Shell/AndroidManifest.xml1
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java22
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java14
-rw-r--r--services/tests/servicestests/AndroidManifest.xml1
-rw-r--r--tests/FrameworkPerf/AndroidManifest.xml1
-rw-r--r--tests/OneMedia/AndroidManifest.xml1
13 files changed, 55 insertions, 22 deletions
diff --git a/api/current.txt b/api/current.txt
index 01117c9c2716..21ceeda92d98 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -73,6 +73,7 @@ package android {
field public static final java.lang.String DUMP = "android.permission.DUMP";
field public static final java.lang.String EXPAND_STATUS_BAR = "android.permission.EXPAND_STATUS_BAR";
field public static final java.lang.String FACTORY_TEST = "android.permission.FACTORY_TEST";
+ field public static final java.lang.String FOREGROUND_SERVICE = "android.permission.FOREGROUND_SERVICE";
field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
field public static final java.lang.String GET_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED";
field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index 256c47934dc5..ea0fd75bec90 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -471,14 +471,6 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
* {@link #onStart} and returns either {@link #START_STICKY}
* or {@link #START_STICKY_COMPATIBILITY}.
*
- * <p>If you need your application to run on platform versions prior to API
- * level 5, you can use the following model to handle the older {@link #onStart}
- * callback in that case. The <code>handleCommand</code> method is implemented by
- * you as appropriate:
- *
- * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/ForegroundService.java
- * start_compatibility}
- *
* <p class="caution">Note that the system calls this on your
* service's main thread. A service's main thread is the same
* thread where UI operations take place for Activities running in the
@@ -687,6 +679,10 @@ public abstract class Service extends ContextWrapper implements ComponentCallbac
* {@link #startService(Intent)} first to tell the system it should keep the service running,
* and then use this method to tell it to keep it running harder.</p>
*
+ * <p>Apps targeting API {@link android.os.Build.VERSION_CODES#P} or later must request
+ * the permission {@link android.Manifest.permission#FOREGROUND_SERVICE} in order to use
+ * this API.</p>
+ *
* @param id The identifier for this notification as per
* {@link NotificationManager#notify(int, Notification)
* NotificationManager.notify(int, Notification)}; must not be 0.
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 6d8831bccdba..df6ce8e85601 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -896,6 +896,14 @@ public class Build {
/**
* P.
+ *
+ * <p>Applications targeting this or a later release will get these
+ * new changes in behavior:</p>
+ * <ul>
+ * <li>{@link android.app.Service#startForeground Service.startForeground} requires
+ * that apps hold the permission
+ * {@link android.Manifest.permission#FOREGROUND_SERVICE}.</li>
+ * </ul>
*/
public static final int P = CUR_DEVELOPMENT; // STOPSHIP Replace with the real version.
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 5e12e7e10884..6c2db7647841 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3827,6 +3827,15 @@
<permission android:name="android.permission.INSTANT_APP_FOREGROUND_SERVICE"
android:protectionLevel="signature|development|instant|appop" />
+ <!-- Allows a regular application to use {@link android.app.Service#startForeground
+ Service.startForeground}.
+ <p>Protection level: normal
+ -->
+ <permission android:name="android.permission.FOREGROUND_SERVICE"
+ android:description="@string/permdesc_foregroundService"
+ android:label="@string/permlab_foregroundService"
+ android:protectionLevel="normal|instant" />
+
<!-- @SystemApi Allows to access all app shortcuts.
@hide -->
<permission android:name="android.permission.ACCESS_SHORTCUTS"
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index d59ba1822f47..1d36f3f1a38b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -927,6 +927,11 @@
<string name="permdesc_persistentActivity" product="default">Allows the app to make parts of itself persistent in memory. This can limit memory available to other apps slowing down the phone.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_foregroundService">run foreground service</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_foregroundService">Allows the app to make use of foreground services.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_getPackageSize">measure app storage space</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_getPackageSize">Allows the app to retrieve its code, data, and cache sizes</string>
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 7d5c60aa292b..53c22f624e8c 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -51,6 +51,7 @@
<uses-permission android:name="android.permission.CLEAR_APP_USER_DATA" />
<uses-permission android:name="android.permission.DELETE_CACHE_FILES" />
<uses-permission android:name="android.permission.DOWNLOAD_CACHE_NON_PURGEABLE" />
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.INJECT_EVENTS" />
diff --git a/packages/MtpDocumentsProvider/AndroidManifest.xml b/packages/MtpDocumentsProvider/AndroidManifest.xml
index 8d79f62f21d7..c0a59b3badbf 100644
--- a/packages/MtpDocumentsProvider/AndroidManifest.xml
+++ b/packages/MtpDocumentsProvider/AndroidManifest.xml
@@ -3,6 +3,7 @@
package="com.android.mtp"
android:sharedUserId="android.media">
<uses-feature android:name="android.hardware.usb.host" />
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.MANAGE_USB" />
<application android:label="@string/app_label">
<provider
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index d284bf9076e1..97ea0aac1807 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -44,6 +44,7 @@
<uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
<uses-permission android:name="android.permission.MANAGE_USB" />
<uses-permission android:name="android.permission.USE_RESERVED_DISK" />
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<!-- System tool permissions granted to the shell. -->
<uses-permission android:name="android.permission.REAL_GET_TASKS" />
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 0c6746e15988..26f83f560c5c 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -1043,20 +1043,14 @@ public final class ActiveServices {
throw new SecurityException("Instant app " + r.appInfo.packageName
+ " does not have permission to create foreground services");
default:
- try {
- if (AppGlobals.getPackageManager().checkPermission(
- android.Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE,
- r.appInfo.packageName, UserHandle.getUserId(r.appInfo.uid))
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Instant app " + r.appInfo.packageName
- + " does not have permission to create foreground"
- + "services");
- }
- } catch (RemoteException e) {
- throw new SecurityException("Failed to check instant app permission." ,
- e);
- }
- }
+ mAm.enforcePermission(
+ android.Manifest.permission.INSTANT_APP_FOREGROUND_SERVICE,
+ r.app.pid, r.appInfo.uid, "startForeground");
+ }
+ } else if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.P) {
+ mAm.enforcePermission(
+ android.Manifest.permission.FOREGROUND_SERVICE,
+ r.app.pid, r.appInfo.uid, "startForeground");
}
if (r.fgRequired) {
if (DEBUG_SERVICE || DEBUG_BACKGROUND_CHECK) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 76564537ca68..3c058fc492fb 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -8973,6 +8973,20 @@ public class ActivityManagerService extends IActivityManager.Stub
/**
* This can be called with or without the global lock held.
*/
+ void enforcePermission(String permission, int pid, int uid, String func) {
+ if (checkPermission(permission, pid, uid) == PackageManager.PERMISSION_GRANTED) {
+ return;
+ }
+
+ String msg = "Permission Denial: " + func + " from pid=" + pid + ", uid=" + uid
+ + " requires " + permission;
+ Slog.w(TAG, msg);
+ throw new SecurityException(msg);
+ }
+
+ /**
+ * This can be called with or without the global lock held.
+ */
void enforceCallerIsRecentsOrHasPermission(String permission, String func) {
if (!mRecentTasks.isCallerRecents(Binder.getCallingUid())) {
enforceCallingPermission(permission, func);
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 568d7a733a19..372b8ccbdd7b 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -61,6 +61,7 @@
<uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WATCH_APPOPS" />
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<!-- Uses API introduced in O (26) -->
<uses-sdk android:minSdkVersion="1"
diff --git a/tests/FrameworkPerf/AndroidManifest.xml b/tests/FrameworkPerf/AndroidManifest.xml
index 2591aaf8f1a6..d62ef9ec210c 100644
--- a/tests/FrameworkPerf/AndroidManifest.xml
+++ b/tests/FrameworkPerf/AndroidManifest.xml
@@ -1,5 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.frameworkperf">
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-sdk android:minSdkVersion="5" />
diff --git a/tests/OneMedia/AndroidManifest.xml b/tests/OneMedia/AndroidManifest.xml
index c6824ecea976..8697f1b085bf 100644
--- a/tests/OneMedia/AndroidManifest.xml
+++ b/tests/OneMedia/AndroidManifest.xml
@@ -5,6 +5,7 @@
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="19"/>
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />