summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ActivityManagerInternal.java5
-rw-r--r--core/java/android/app/IActivityManager.aidl1
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java23
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java35
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java18
5 files changed, 82 insertions, 0 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index e3909f965283..0881db039f77 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -518,6 +518,11 @@ public abstract class ActivityManagerInternal {
Notification notification, int id, String pkg, @UserIdInt int userId);
/**
+ * Un-foreground all foreground services in the given app.
+ */
+ public abstract void makeServicesNonForeground(String pkg, @UserIdInt int userId);
+
+ /**
* If the given app has any FGSs whose notifications are in the given channel,
* stop them.
*/
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 47e481099045..658c1309b94e 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -278,6 +278,7 @@ interface IActivityManager {
List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState();
boolean clearApplicationUserData(in String packageName, boolean keepState,
in IPackageDataObserver observer, int userId);
+ void makeServicesNonForeground(in String packageName, int userId);
@UnsupportedAppUsage
void forceStopPackage(in String packageName, int userId);
boolean killPids(in int[] pids, in String reason, boolean secure);
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 1997897046d9..b5623be0e731 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -5110,6 +5110,29 @@ public final class ActiveServices {
return didSomething;
}
+ void makeServicesNonForegroundLocked(final String pkg, final @UserIdInt int userId) {
+ final ServiceMap smap = mServiceMap.get(userId);
+ if (smap != null) {
+ ArrayList<ServiceRecord> fgsList = new ArrayList<>();
+ for (int i = 0; i < smap.mServicesByInstanceName.size(); i++) {
+ final ServiceRecord sr = smap.mServicesByInstanceName.valueAt(i);
+ if (sr.appInfo.packageName.equals(pkg) && sr.isForeground) {
+ fgsList.add(sr);
+ }
+ }
+
+ final int numServices = fgsList.size();
+ if (DEBUG_FOREGROUND_SERVICE) {
+ Slog.i(TAG_SERVICE, "Forcing " + numServices + " services out of foreground in u"
+ + userId + "/" + pkg);
+ }
+ for (int i = 0; i < numServices; i++) {
+ final ServiceRecord sr = fgsList.get(i);
+ setServiceForegroundInnerLocked(sr, 0, null, Service.STOP_FOREGROUND_REMOVE, 0);
+ }
+ }
+ }
+
void forceStopPackageLocked(String packageName, int userId) {
ServiceMap smap = mServiceMap.get(userId);
if (smap != null && smap.mActiveForegroundApps.size() > 0) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index f6c110655e51..30745985951a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3751,6 +3751,29 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
+ public void makeServicesNonForeground(final String packageName, int userId) {
+ if (checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
+ != PackageManager.PERMISSION_GRANTED) {
+ String msg = "Permission Denial: makeServicesNonForeground() from pid="
+ + Binder.getCallingPid()
+ + ", uid=" + Binder.getCallingUid()
+ + " requires " + android.Manifest.permission.MANAGE_ACTIVITY_TASKS;
+ Slog.w(TAG, msg);
+ throw new SecurityException(msg);
+ }
+
+ final int callingPid = Binder.getCallingPid();
+ userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
+ userId, true, ALLOW_FULL_ONLY, "makeServicesNonForeground", null);
+ final long callingId = Binder.clearCallingIdentity();
+ try {
+ makeServicesNonForegroundUnchecked(packageName, userId);
+ } finally {
+ Binder.restoreCallingIdentity(callingId);
+ }
+ }
+
+ @Override
public void forceStopPackage(final String packageName, int userId) {
if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
!= PackageManager.PERMISSION_GRANTED) {
@@ -4058,6 +4081,13 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
+ private void makeServicesNonForegroundUnchecked(final String packageName,
+ final @UserIdInt int userId) {
+ synchronized (this) {
+ mServices.makeServicesNonForegroundLocked(packageName, userId);
+ }
+ }
+
@GuardedBy("this")
private void forceStopPackageLocked(final String packageName, int uid, String reason) {
forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
@@ -16399,6 +16429,11 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
+ public void makeServicesNonForeground(String pkg, int userId) {
+ ActivityManagerService.this.makeServicesNonForegroundUnchecked(pkg, userId);
+ }
+
+ @Override
public void stopForegroundServicesForChannel(String pkg, int userId,
String channelId) {
synchronized (ActivityManagerService.this) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 685d606f8d41..0f7163987b2c 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -229,6 +229,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
return runBugReport(pw);
case "force-stop":
return runForceStop(pw);
+ case "stop-fgs":
+ return runStopForegroundServices(pw);
case "fgs-notification-rate-limit":
return runFgsNotificationRateLimit(pw);
case "crash":
@@ -1105,6 +1107,22 @@ final class ActivityManagerShellCommand extends ShellCommand {
return 0;
}
+ int runStopForegroundServices(PrintWriter pw) throws RemoteException {
+ int userId = UserHandle.USER_SYSTEM;
+
+ String opt;
+ while ((opt = getNextOption()) != null) {
+ if (opt.equals("--user")) {
+ userId = UserHandle.parseUserArg(getNextArgRequired());
+ } else {
+ getErrPrintWriter().println("Error: Unknown option: " + opt);
+ return -1;
+ }
+ }
+ mInterface.makeServicesNonForeground(getNextArgRequired(), userId);
+ return 0;
+ }
+
int runFgsNotificationRateLimit(PrintWriter pw) throws RemoteException {
final String toggleValue = getNextArgRequired();
final boolean enable;