Loading core/java/android/app/IActivityManager.aidl +3 −0 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.app.GrantedUriPermission; import android.app.IApplicationThread; import android.app.IApplicationThread; import android.app.IActivityController; import android.app.IActivityController; import android.app.IAppTask; import android.app.IAppTask; import android.app.IForegroundServiceObserver; import android.app.IInstrumentationWatcher; import android.app.IInstrumentationWatcher; import android.app.IProcessObserver; import android.app.IProcessObserver; import android.app.IServiceConnection; import android.app.IServiceConnection; Loading Loading @@ -279,6 +280,8 @@ interface IActivityManager { boolean clearApplicationUserData(in String packageName, boolean keepState, boolean clearApplicationUserData(in String packageName, boolean keepState, in IPackageDataObserver observer, int userId); in IPackageDataObserver observer, int userId); void makeServicesNonForeground(in String packageName, int userId); void makeServicesNonForeground(in String packageName, int userId); /** Returns {@code false} if the callback could not be registered, {@true} otherwise. */ boolean registerForegroundServiceObserver(in IForegroundServiceObserver callback); @UnsupportedAppUsage @UnsupportedAppUsage void forceStopPackage(in String packageName, int userId); void forceStopPackage(in String packageName, int userId); boolean killPids(in int[] pids, in String reason, boolean secure); boolean killPids(in int[] pids, in String reason, boolean secure); Loading core/java/android/app/IForegroundServiceObserver.aidl 0 → 100644 +31 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.app; /** * Notify the client of all changes to services' foreground state. * @param serviceToken unique identifier for a service instance * @param packageName identifies the app hosting the service * @param userId identifies the started user in which the app is running * @param isForeground whether the service is in the "foreground" mode now, i.e. * whether it is an FGS * * @hide */ oneway interface IForegroundServiceObserver { void onForegroundStateChanged(in IBinder serviceToken, in String packageName, int userId, boolean isForeground); } core/java/android/app/OWNERS +1 −0 Original line number Original line Diff line number Diff line Loading @@ -15,6 +15,7 @@ per-file IActivityController.aidl = file:/services/core/java/com/android/server/ per-file IActivityManager.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IActivityManager.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IApplicationThread.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IApplicationThread.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IAppTraceRetriever.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IAppTraceRetriever.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IForegroundServiceObserver.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IInstrumentationWatcher.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IInstrumentationWatcher.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IntentService.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IntentService.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IServiceConnection.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IServiceConnection.aidl = file:/services/core/java/com/android/server/am/OWNERS Loading services/core/java/com/android/server/am/ActiveServices.java +70 −1 Original line number Original line Diff line number Diff line Loading @@ -90,6 +90,7 @@ import android.app.AppOpsManager; import android.app.ForegroundServiceDidNotStartInTimeException; import android.app.ForegroundServiceDidNotStartInTimeException; import android.app.ForegroundServiceStartNotAllowedException; import android.app.ForegroundServiceStartNotAllowedException; import android.app.IApplicationThread; import android.app.IApplicationThread; import android.app.IForegroundServiceObserver; import android.app.IServiceConnection; import android.app.IServiceConnection; import android.app.Notification; import android.app.Notification; import android.app.NotificationManager; import android.app.NotificationManager; Loading Loading @@ -128,6 +129,7 @@ import android.os.PowerExemptionManager; import android.os.PowerExemptionManager.ReasonCode; import android.os.PowerExemptionManager.ReasonCode; import android.os.Process; import android.os.Process; import android.os.RemoteCallback; import android.os.RemoteCallback; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemClock; Loading Loading @@ -266,6 +268,12 @@ public final class ActiveServices { */ */ final SparseLongArray mFgsDeferralEligible = new SparseLongArray(); final SparseLongArray mFgsDeferralEligible = new SparseLongArray(); /** * Foreground service observers: track what apps have FGSes */ final RemoteCallbackList<IForegroundServiceObserver> mFgsObservers = new RemoteCallbackList<>(); /** /** * Map of services that are asked to be brought up (start/binding) but not ready to. * Map of services that are asked to be brought up (start/binding) but not ready to. */ */ Loading Loading @@ -1382,6 +1390,10 @@ public final class ActiveServices { return false; return false; } } /** * Put the named service into the foreground mode */ @GuardedBy("mAm") public void setServiceForegroundLocked(ComponentName className, IBinder token, public void setServiceForegroundLocked(ComponentName className, IBinder token, int id, Notification notification, int flags, int foregroundServiceType) { int id, Notification notification, int flags, int foregroundServiceType) { final int userId = UserHandle.getCallingUserId(); final int userId = UserHandle.getCallingUserId(); Loading Loading @@ -1746,6 +1758,7 @@ public final class ActiveServices { /** /** * @param id Notification ID. Zero === exit foreground state for the given service. * @param id Notification ID. Zero === exit foreground state for the given service. */ */ @GuardedBy("mAm") private void setServiceForegroundInnerLocked(final ServiceRecord r, int id, private void setServiceForegroundInnerLocked(final ServiceRecord r, int id, Notification notification, int flags, int foregroundServiceType) { Notification notification, int flags, int foregroundServiceType) { if (id != 0) { if (id != 0) { Loading Loading @@ -1981,6 +1994,7 @@ public final class ActiveServices { } } // Even if the service is already a FGS, we need to update the notification, // Even if the service is already a FGS, we need to update the notification, // so we need to call it again. // so we need to call it again. signalForegroundServiceObserversLocked(r); r.postNotification(); r.postNotification(); if (r.app != null) { if (r.app != null) { updateServiceForegroundLocked(psr, true); updateServiceForegroundLocked(psr, true); Loading Loading @@ -2060,6 +2074,7 @@ public final class ActiveServices { r.mFgsExitTime > r.mFgsEnterTime r.mFgsExitTime > r.mFgsEnterTime ? (int)(r.mFgsExitTime - r.mFgsEnterTime) : 0); ? (int)(r.mFgsExitTime - r.mFgsEnterTime) : 0); r.mFgsNotificationWasDeferred = false; r.mFgsNotificationWasDeferred = false; signalForegroundServiceObserversLocked(r); resetFgsRestrictionLocked(r); resetFgsRestrictionLocked(r); mAm.updateForegroundServiceUsageStats(r.name, r.userId, false); mAm.updateForegroundServiceUsageStats(r.name, r.userId, false); if (r.app != null) { if (r.app != null) { Loading Loading @@ -4552,7 +4567,8 @@ public final class ActiveServices { } } cancelForegroundNotificationLocked(r); cancelForegroundNotificationLocked(r); if (r.isForeground) { final boolean exitingFg = r.isForeground; if (exitingFg) { decActiveForegroundAppLocked(smap, r); decActiveForegroundAppLocked(smap, r); synchronized (mAm.mProcessStats.mLock) { synchronized (mAm.mProcessStats.mLock) { ServiceState stracker = r.getTracker(); ServiceState stracker = r.getTracker(); Loading @@ -4578,6 +4594,11 @@ public final class ActiveServices { r.foregroundId = 0; r.foregroundId = 0; r.foregroundNoti = null; r.foregroundNoti = null; resetFgsRestrictionLocked(r); resetFgsRestrictionLocked(r); // Signal FGS observers *after* changing the isForeground state, and // only if this was an actual state change. if (exitingFg) { signalForegroundServiceObserversLocked(r); } // Clear start entries. // Clear start entries. r.clearDeliveredStartsLocked(); r.clearDeliveredStartsLocked(); Loading Loading @@ -5133,6 +5154,54 @@ public final class ActiveServices { } } } } @GuardedBy("mAm") private void signalForegroundServiceObserversLocked(ServiceRecord r) { final int num = mFgsObservers.beginBroadcast(); for (int i = 0; i < num; i++) { try { mFgsObservers.getBroadcastItem(i).onForegroundStateChanged(r, r.appInfo.packageName, r.userId, r.isForeground); } catch (RemoteException e) { // Will be unregistered automatically by RemoteCallbackList's dead-object // tracking, so nothing we need to do here. } } mFgsObservers.finishBroadcast(); } @GuardedBy("mAm") boolean registerForegroundServiceObserverLocked(final int callingUid, IForegroundServiceObserver callback) { // We always tell the newly-registered observer about any current FGSes. The // most common case for this is a SysUI crash & relaunch; it needs to // reconstruct its tracking of stoppable-FGS-hosting apps. try { final int mapSize = mServiceMap.size(); for (int mapIndex = 0; mapIndex < mapSize; mapIndex++) { final ServiceMap smap = mServiceMap.valueAt(mapIndex); if (smap != null) { final int numServices = smap.mServicesByInstanceName.size(); for (int i = 0; i < numServices; i++) { final ServiceRecord sr = smap.mServicesByInstanceName.valueAt(i); if (sr.isForeground && callingUid == sr.appInfo.uid) { callback.onForegroundStateChanged(sr, sr.appInfo.packageName, sr.userId, true); } } } } // Callback is fine, go ahead and record it mFgsObservers.register(callback); } catch (RemoteException e) { // Whoops, something wrong with the callback. Don't register it, and // report error back to the caller. Slog.e(TAG_SERVICE, "Bad FGS observer from uid " + callingUid); return false; } return true; } void forceStopPackageLocked(String packageName, int userId) { void forceStopPackageLocked(String packageName, int userId) { ServiceMap smap = mServiceMap.get(userId); ServiceMap smap = mServiceMap.get(userId); if (smap != null && smap.mActiveForegroundApps.size() > 0) { if (smap != null && smap.mActiveForegroundApps.size() > 0) { Loading services/core/java/com/android/server/am/ActivityManagerService.java +25 −2 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST; import static android.Manifest.permission.FILTER_EVENTS; import static android.Manifest.permission.FILTER_EVENTS; import static android.Manifest.permission.INTERACT_ACROSS_USERS; import static android.Manifest.permission.INTERACT_ACROSS_USERS; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.Manifest.permission.MANAGE_ACTIVITY_TASKS; import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND; import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND; import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND; import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND; import static android.app.ActivityManager.INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS; import static android.app.ActivityManager.INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS; Loading Loading @@ -168,6 +169,7 @@ import android.app.ContentProviderHolder; import android.app.IActivityController; import android.app.IActivityController; import android.app.IActivityManager; import android.app.IActivityManager; import android.app.IApplicationThread; import android.app.IApplicationThread; import android.app.IForegroundServiceObserver; import android.app.IInstrumentationWatcher; import android.app.IInstrumentationWatcher; import android.app.INotificationManager; import android.app.INotificationManager; import android.app.IProcessObserver; import android.app.IProcessObserver; Loading Loading @@ -3754,12 +3756,12 @@ public class ActivityManagerService extends IActivityManager.Stub @Override @Override public void makeServicesNonForeground(final String packageName, int userId) { public void makeServicesNonForeground(final String packageName, int userId) { if (checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) if (checkCallingPermission(MANAGE_ACTIVITY_TASKS) != PackageManager.PERMISSION_GRANTED) { != PackageManager.PERMISSION_GRANTED) { String msg = "Permission Denial: makeServicesNonForeground() from pid=" String msg = "Permission Denial: makeServicesNonForeground() from pid=" + Binder.getCallingPid() + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() + ", uid=" + Binder.getCallingUid() + " requires " + android.Manifest.permission.MANAGE_ACTIVITY_TASKS; + " requires " + MANAGE_ACTIVITY_TASKS; Slog.w(TAG, msg); Slog.w(TAG, msg); throw new SecurityException(msg); throw new SecurityException(msg); } } Loading @@ -3775,6 +3777,27 @@ public class ActivityManagerService extends IActivityManager.Stub } } } } @Override public boolean registerForegroundServiceObserver(IForegroundServiceObserver callback) { final int callingUid = Binder.getCallingUid(); final int permActivityTasks = checkCallingPermission(MANAGE_ACTIVITY_TASKS); final int permAcrossUsersFull = checkCallingPermission(INTERACT_ACROSS_USERS_FULL); if (permActivityTasks != PackageManager.PERMISSION_GRANTED || permAcrossUsersFull != PERMISSION_GRANTED) { String msg = "Permission Denial: registerForegroundServiceObserver() from pid=" + Binder.getCallingPid() + ", uid=" + callingUid + " requires " + MANAGE_ACTIVITY_TASKS + " and " + INTERACT_ACROSS_USERS_FULL; Slog.w(TAG, msg); throw new SecurityException(msg); } synchronized (this) { return mServices.registerForegroundServiceObserverLocked(callingUid, callback); } } @Override @Override public void forceStopPackage(final String packageName, int userId) { public void forceStopPackage(final String packageName, int userId) { if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) Loading Loading
core/java/android/app/IActivityManager.aidl +3 −0 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.app.GrantedUriPermission; import android.app.IApplicationThread; import android.app.IApplicationThread; import android.app.IActivityController; import android.app.IActivityController; import android.app.IAppTask; import android.app.IAppTask; import android.app.IForegroundServiceObserver; import android.app.IInstrumentationWatcher; import android.app.IInstrumentationWatcher; import android.app.IProcessObserver; import android.app.IProcessObserver; import android.app.IServiceConnection; import android.app.IServiceConnection; Loading Loading @@ -279,6 +280,8 @@ interface IActivityManager { boolean clearApplicationUserData(in String packageName, boolean keepState, boolean clearApplicationUserData(in String packageName, boolean keepState, in IPackageDataObserver observer, int userId); in IPackageDataObserver observer, int userId); void makeServicesNonForeground(in String packageName, int userId); void makeServicesNonForeground(in String packageName, int userId); /** Returns {@code false} if the callback could not be registered, {@true} otherwise. */ boolean registerForegroundServiceObserver(in IForegroundServiceObserver callback); @UnsupportedAppUsage @UnsupportedAppUsage void forceStopPackage(in String packageName, int userId); void forceStopPackage(in String packageName, int userId); boolean killPids(in int[] pids, in String reason, boolean secure); boolean killPids(in int[] pids, in String reason, boolean secure); Loading
core/java/android/app/IForegroundServiceObserver.aidl 0 → 100644 +31 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.app; /** * Notify the client of all changes to services' foreground state. * @param serviceToken unique identifier for a service instance * @param packageName identifies the app hosting the service * @param userId identifies the started user in which the app is running * @param isForeground whether the service is in the "foreground" mode now, i.e. * whether it is an FGS * * @hide */ oneway interface IForegroundServiceObserver { void onForegroundStateChanged(in IBinder serviceToken, in String packageName, int userId, boolean isForeground); }
core/java/android/app/OWNERS +1 −0 Original line number Original line Diff line number Diff line Loading @@ -15,6 +15,7 @@ per-file IActivityController.aidl = file:/services/core/java/com/android/server/ per-file IActivityManager.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IActivityManager.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IApplicationThread.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IApplicationThread.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IAppTraceRetriever.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IAppTraceRetriever.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IForegroundServiceObserver.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IInstrumentationWatcher.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IInstrumentationWatcher.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IntentService.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IntentService.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IServiceConnection.aidl = file:/services/core/java/com/android/server/am/OWNERS per-file IServiceConnection.aidl = file:/services/core/java/com/android/server/am/OWNERS Loading
services/core/java/com/android/server/am/ActiveServices.java +70 −1 Original line number Original line Diff line number Diff line Loading @@ -90,6 +90,7 @@ import android.app.AppOpsManager; import android.app.ForegroundServiceDidNotStartInTimeException; import android.app.ForegroundServiceDidNotStartInTimeException; import android.app.ForegroundServiceStartNotAllowedException; import android.app.ForegroundServiceStartNotAllowedException; import android.app.IApplicationThread; import android.app.IApplicationThread; import android.app.IForegroundServiceObserver; import android.app.IServiceConnection; import android.app.IServiceConnection; import android.app.Notification; import android.app.Notification; import android.app.NotificationManager; import android.app.NotificationManager; Loading Loading @@ -128,6 +129,7 @@ import android.os.PowerExemptionManager; import android.os.PowerExemptionManager.ReasonCode; import android.os.PowerExemptionManager.ReasonCode; import android.os.Process; import android.os.Process; import android.os.RemoteCallback; import android.os.RemoteCallback; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemClock; Loading Loading @@ -266,6 +268,12 @@ public final class ActiveServices { */ */ final SparseLongArray mFgsDeferralEligible = new SparseLongArray(); final SparseLongArray mFgsDeferralEligible = new SparseLongArray(); /** * Foreground service observers: track what apps have FGSes */ final RemoteCallbackList<IForegroundServiceObserver> mFgsObservers = new RemoteCallbackList<>(); /** /** * Map of services that are asked to be brought up (start/binding) but not ready to. * Map of services that are asked to be brought up (start/binding) but not ready to. */ */ Loading Loading @@ -1382,6 +1390,10 @@ public final class ActiveServices { return false; return false; } } /** * Put the named service into the foreground mode */ @GuardedBy("mAm") public void setServiceForegroundLocked(ComponentName className, IBinder token, public void setServiceForegroundLocked(ComponentName className, IBinder token, int id, Notification notification, int flags, int foregroundServiceType) { int id, Notification notification, int flags, int foregroundServiceType) { final int userId = UserHandle.getCallingUserId(); final int userId = UserHandle.getCallingUserId(); Loading Loading @@ -1746,6 +1758,7 @@ public final class ActiveServices { /** /** * @param id Notification ID. Zero === exit foreground state for the given service. * @param id Notification ID. Zero === exit foreground state for the given service. */ */ @GuardedBy("mAm") private void setServiceForegroundInnerLocked(final ServiceRecord r, int id, private void setServiceForegroundInnerLocked(final ServiceRecord r, int id, Notification notification, int flags, int foregroundServiceType) { Notification notification, int flags, int foregroundServiceType) { if (id != 0) { if (id != 0) { Loading Loading @@ -1981,6 +1994,7 @@ public final class ActiveServices { } } // Even if the service is already a FGS, we need to update the notification, // Even if the service is already a FGS, we need to update the notification, // so we need to call it again. // so we need to call it again. signalForegroundServiceObserversLocked(r); r.postNotification(); r.postNotification(); if (r.app != null) { if (r.app != null) { updateServiceForegroundLocked(psr, true); updateServiceForegroundLocked(psr, true); Loading Loading @@ -2060,6 +2074,7 @@ public final class ActiveServices { r.mFgsExitTime > r.mFgsEnterTime r.mFgsExitTime > r.mFgsEnterTime ? (int)(r.mFgsExitTime - r.mFgsEnterTime) : 0); ? (int)(r.mFgsExitTime - r.mFgsEnterTime) : 0); r.mFgsNotificationWasDeferred = false; r.mFgsNotificationWasDeferred = false; signalForegroundServiceObserversLocked(r); resetFgsRestrictionLocked(r); resetFgsRestrictionLocked(r); mAm.updateForegroundServiceUsageStats(r.name, r.userId, false); mAm.updateForegroundServiceUsageStats(r.name, r.userId, false); if (r.app != null) { if (r.app != null) { Loading Loading @@ -4552,7 +4567,8 @@ public final class ActiveServices { } } cancelForegroundNotificationLocked(r); cancelForegroundNotificationLocked(r); if (r.isForeground) { final boolean exitingFg = r.isForeground; if (exitingFg) { decActiveForegroundAppLocked(smap, r); decActiveForegroundAppLocked(smap, r); synchronized (mAm.mProcessStats.mLock) { synchronized (mAm.mProcessStats.mLock) { ServiceState stracker = r.getTracker(); ServiceState stracker = r.getTracker(); Loading @@ -4578,6 +4594,11 @@ public final class ActiveServices { r.foregroundId = 0; r.foregroundId = 0; r.foregroundNoti = null; r.foregroundNoti = null; resetFgsRestrictionLocked(r); resetFgsRestrictionLocked(r); // Signal FGS observers *after* changing the isForeground state, and // only if this was an actual state change. if (exitingFg) { signalForegroundServiceObserversLocked(r); } // Clear start entries. // Clear start entries. r.clearDeliveredStartsLocked(); r.clearDeliveredStartsLocked(); Loading Loading @@ -5133,6 +5154,54 @@ public final class ActiveServices { } } } } @GuardedBy("mAm") private void signalForegroundServiceObserversLocked(ServiceRecord r) { final int num = mFgsObservers.beginBroadcast(); for (int i = 0; i < num; i++) { try { mFgsObservers.getBroadcastItem(i).onForegroundStateChanged(r, r.appInfo.packageName, r.userId, r.isForeground); } catch (RemoteException e) { // Will be unregistered automatically by RemoteCallbackList's dead-object // tracking, so nothing we need to do here. } } mFgsObservers.finishBroadcast(); } @GuardedBy("mAm") boolean registerForegroundServiceObserverLocked(final int callingUid, IForegroundServiceObserver callback) { // We always tell the newly-registered observer about any current FGSes. The // most common case for this is a SysUI crash & relaunch; it needs to // reconstruct its tracking of stoppable-FGS-hosting apps. try { final int mapSize = mServiceMap.size(); for (int mapIndex = 0; mapIndex < mapSize; mapIndex++) { final ServiceMap smap = mServiceMap.valueAt(mapIndex); if (smap != null) { final int numServices = smap.mServicesByInstanceName.size(); for (int i = 0; i < numServices; i++) { final ServiceRecord sr = smap.mServicesByInstanceName.valueAt(i); if (sr.isForeground && callingUid == sr.appInfo.uid) { callback.onForegroundStateChanged(sr, sr.appInfo.packageName, sr.userId, true); } } } } // Callback is fine, go ahead and record it mFgsObservers.register(callback); } catch (RemoteException e) { // Whoops, something wrong with the callback. Don't register it, and // report error back to the caller. Slog.e(TAG_SERVICE, "Bad FGS observer from uid " + callingUid); return false; } return true; } void forceStopPackageLocked(String packageName, int userId) { void forceStopPackageLocked(String packageName, int userId) { ServiceMap smap = mServiceMap.get(userId); ServiceMap smap = mServiceMap.get(userId); if (smap != null && smap.mActiveForegroundApps.size() > 0) { if (smap != null && smap.mActiveForegroundApps.size() > 0) { Loading
services/core/java/com/android/server/am/ActivityManagerService.java +25 −2 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST; import static android.Manifest.permission.FILTER_EVENTS; import static android.Manifest.permission.FILTER_EVENTS; import static android.Manifest.permission.INTERACT_ACROSS_USERS; import static android.Manifest.permission.INTERACT_ACROSS_USERS; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.Manifest.permission.MANAGE_ACTIVITY_TASKS; import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND; import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND; import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND; import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND; import static android.app.ActivityManager.INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS; import static android.app.ActivityManager.INSTR_FLAG_DISABLE_HIDDEN_API_CHECKS; Loading Loading @@ -168,6 +169,7 @@ import android.app.ContentProviderHolder; import android.app.IActivityController; import android.app.IActivityController; import android.app.IActivityManager; import android.app.IActivityManager; import android.app.IApplicationThread; import android.app.IApplicationThread; import android.app.IForegroundServiceObserver; import android.app.IInstrumentationWatcher; import android.app.IInstrumentationWatcher; import android.app.INotificationManager; import android.app.INotificationManager; import android.app.IProcessObserver; import android.app.IProcessObserver; Loading Loading @@ -3754,12 +3756,12 @@ public class ActivityManagerService extends IActivityManager.Stub @Override @Override public void makeServicesNonForeground(final String packageName, int userId) { public void makeServicesNonForeground(final String packageName, int userId) { if (checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS) if (checkCallingPermission(MANAGE_ACTIVITY_TASKS) != PackageManager.PERMISSION_GRANTED) { != PackageManager.PERMISSION_GRANTED) { String msg = "Permission Denial: makeServicesNonForeground() from pid=" String msg = "Permission Denial: makeServicesNonForeground() from pid=" + Binder.getCallingPid() + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() + ", uid=" + Binder.getCallingUid() + " requires " + android.Manifest.permission.MANAGE_ACTIVITY_TASKS; + " requires " + MANAGE_ACTIVITY_TASKS; Slog.w(TAG, msg); Slog.w(TAG, msg); throw new SecurityException(msg); throw new SecurityException(msg); } } Loading @@ -3775,6 +3777,27 @@ public class ActivityManagerService extends IActivityManager.Stub } } } } @Override public boolean registerForegroundServiceObserver(IForegroundServiceObserver callback) { final int callingUid = Binder.getCallingUid(); final int permActivityTasks = checkCallingPermission(MANAGE_ACTIVITY_TASKS); final int permAcrossUsersFull = checkCallingPermission(INTERACT_ACROSS_USERS_FULL); if (permActivityTasks != PackageManager.PERMISSION_GRANTED || permAcrossUsersFull != PERMISSION_GRANTED) { String msg = "Permission Denial: registerForegroundServiceObserver() from pid=" + Binder.getCallingPid() + ", uid=" + callingUid + " requires " + MANAGE_ACTIVITY_TASKS + " and " + INTERACT_ACROSS_USERS_FULL; Slog.w(TAG, msg); throw new SecurityException(msg); } synchronized (this) { return mServices.registerForegroundServiceObserverLocked(callingUid, callback); } } @Override @Override public void forceStopPackage(final String packageName, int userId) { public void forceStopPackage(final String packageName, int userId) { if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) Loading