Loading core/res/res/values/config.xml +1 −1 Original line number Diff line number Diff line Loading @@ -5796,7 +5796,7 @@ <!-- The types of state where we'll exempt its battery usage during that state. The state here must be one or a combination of STATE_TYPE_* in BaseAppStateTracker. --> <integer name="config_bg_current_drain_exempted_types">9</integer> <integer name="config_bg_current_drain_exempted_types">25</integer> <!-- The behavior when an app has the permission ACCESS_BACKGROUND_LOCATION granted, whether or not the system will use a higher threshold towards its background battery usage Loading services/core/java/com/android/server/am/AppFGSTracker.java +138 −19 Original line number Diff line number Diff line Loading @@ -32,18 +32,22 @@ import static com.android.server.am.BaseAppStateTracker.ONE_HOUR; import android.annotation.NonNull; import android.app.ActivityManagerInternal.ForegroundServiceStateListener; import android.app.IProcessObserver; import android.content.ComponentName; import android.content.Context; import android.content.pm.ServiceInfo.ForegroundServiceType; import android.os.Handler; import android.os.Message; import android.os.PowerExemptionManager.ReasonCode; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; import android.provider.DeviceConfig; import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.TimeUtils; import com.android.internal.annotations.GuardedBy; Loading @@ -53,7 +57,6 @@ import com.android.server.am.AppFGSTracker.PackageDurations; import com.android.server.am.BaseAppStateEventsTracker.BaseAppStateEventsPolicy; import com.android.server.am.BaseAppStateTimeEvents.BaseTimeEvent; import com.android.server.am.BaseAppStateTracker.Injector; import com.android.server.notification.NotificationManagerInternal; import java.io.PrintWriter; import java.lang.reflect.Constructor; Loading @@ -72,11 +75,14 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac private final MyHandler mHandler; @GuardedBy("mLock") private final UidProcessMap<ArraySet<Integer>> mFGSNotificationIDs = new UidProcessMap<>(); private final UidProcessMap<SparseBooleanArray> mFGSNotificationIDs = new UidProcessMap<>(); // Unlocked since it's only accessed in single thread. private final ArrayMap<PackageDurations, Long> mTmpPkgDurations = new ArrayMap<>(); @VisibleForTesting final NotificationListener mNotificationListener = new NotificationListener(); final IProcessObserver.Stub mProcessObserver = new IProcessObserver.Stub() { @Override public void onForegroundActivitiesChanged(int pid, int uid, boolean fg) { Loading Loading @@ -116,6 +122,8 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac static final int MSG_FOREGROUND_SERVICES_CHANGED = 2; static final int MSG_FOREGROUND_SERVICES_NOTIFICATION_UPDATED = 3; static final int MSG_CHECK_LONG_RUNNING_FGS = 4; static final int MSG_NOTIFICATION_POSTED = 5; static final int MSG_NOTIFICATION_REMOVED = 6; private final AppFGSTracker mTracker; Loading Loading @@ -146,6 +154,12 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac case MSG_CHECK_LONG_RUNNING_FGS: mTracker.checkLongRunningFgs(); break; case MSG_NOTIFICATION_POSTED: mTracker.handleNotificationPosted((String) msg.obj, msg.arg1, msg.arg2); break; case MSG_NOTIFICATION_REMOVED: mTracker.handleNotificationRemoved((String) msg.obj, msg.arg1, msg.arg2); break; } } } Loading Loading @@ -223,20 +237,37 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac private void handleForegroundServiceNotificationUpdated(String packageName, int uid, int notificationId) { synchronized (mLock) { SparseBooleanArray notificationIDs = mFGSNotificationIDs.get(uid, packageName); if (notificationId > 0) { ArraySet<Integer> notificationIDs = mFGSNotificationIDs.get(uid, packageName); if (notificationIDs == null) { notificationIDs = new ArraySet<>(); notificationIDs = new SparseBooleanArray(); mFGSNotificationIDs.put(uid, packageName, notificationIDs); } notificationIDs.add(notificationId); notificationIDs.put(notificationId, false); } else if (notificationId < 0) { final ArraySet<Integer> notificationIDs = mFGSNotificationIDs.get(uid, packageName); if (notificationIDs != null) { notificationIDs.remove(-notificationId); if (notificationIDs.isEmpty()) { final int indexOfKey = notificationIDs.indexOfKey(-notificationId); if (indexOfKey >= 0) { final boolean wasVisible = notificationIDs.valueAt(indexOfKey); notificationIDs.removeAt(indexOfKey); if (notificationIDs.size() == 0) { mFGSNotificationIDs.remove(uid, packageName); } // Walk through the list of FGS notification IDs and see if there are any // visible ones. for (int i = notificationIDs.size() - 1; i >= 0; i--) { if (notificationIDs.valueAt(i)) { // Still visible, nothing to do. return; } } if (wasVisible) { // That was the last visible notification, notify the listeners. notifyListenersOnStateChange(uid, packageName, false, SystemClock.elapsedRealtime(), STATE_TYPE_FGS_WITH_NOTIFICATION); } } } } } Loading @@ -244,20 +275,74 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac @GuardedBy("mLock") private boolean hasForegroundServiceNotificationsLocked(String packageName, int uid) { final ArraySet<Integer> notificationIDs = mFGSNotificationIDs.get(uid, packageName); if (notificationIDs == null || notificationIDs.isEmpty()) { final SparseBooleanArray notificationIDs = mFGSNotificationIDs.get(uid, packageName); if (notificationIDs == null || notificationIDs.size() == 0) { return false; } final NotificationManagerInternal nm = mInjector.getNotificationManagerInternal(); final int userId = UserHandle.getUserId(uid); for (int i = notificationIDs.size() - 1; i >= 0; i--) { if (nm.isNotificationShown(packageName, null, notificationIDs.valueAt(i), userId)) { if (notificationIDs.valueAt(i)) { return true; } } return false; } private void handleNotificationPosted(String pkgName, int uid, int notificationId) { synchronized (mLock) { final SparseBooleanArray notificationIDs = mFGSNotificationIDs.get(uid, pkgName); final int indexOfKey; if (notificationIDs == null || (indexOfKey = notificationIDs.indexOfKey(notificationId)) < 0) { return; } if (notificationIDs.valueAt(indexOfKey)) { // It's already visible. return; } boolean anyVisible = false; // Walk through the list of FGS notification IDs and see if there are any visible ones. for (int i = notificationIDs.size() - 1; i >= 0; i--) { if (notificationIDs.valueAt(i)) { anyVisible = true; break; } } notificationIDs.setValueAt(indexOfKey, true); if (!anyVisible) { // We didn't have any visible FGS notifications but now we have one, // let the listeners know. notifyListenersOnStateChange(uid, pkgName, true, SystemClock.elapsedRealtime(), STATE_TYPE_FGS_WITH_NOTIFICATION); } } } private void handleNotificationRemoved(String pkgName, int uid, int notificationId) { synchronized (mLock) { final SparseBooleanArray notificationIDs = mFGSNotificationIDs.get(uid, pkgName); final int indexOfKey; if (notificationIDs == null || (indexOfKey = notificationIDs.indexOfKey(notificationId)) < 0) { return; } if (!notificationIDs.valueAt(indexOfKey)) { // It's already invisible. return; } notificationIDs.setValueAt(indexOfKey, false); // Walk through the list of FGS notification IDs and see if there are any visible ones. for (int i = notificationIDs.size() - 1; i >= 0; i--) { if (notificationIDs.valueAt(i)) { // Still visible, nothing to do. return; } } // Nothing is visible now, let the listeners know. notifyListenersOnStateChange(uid, pkgName, false, SystemClock.elapsedRealtime(), STATE_TYPE_FGS_WITH_NOTIFICATION); } } @GuardedBy("mLock") private void scheduleDurationCheckLocked(long now) { // Look for the active FGS with longest running time till now. Loading Loading @@ -374,7 +459,19 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac synchronized (mLock) { scheduleDurationCheckLocked(SystemClock.elapsedRealtime()); } try { mNotificationListener.registerAsSystemService(mContext, new ComponentName(mContext, NotificationListener.class), UserHandle.USER_ALL); } catch (RemoteException e) { // Intra-process call, should never happen. } } else { try { mNotificationListener.unregisterAsSystemService(); } catch (RemoteException e) { // Intra-process call, should never happen. } mHandler.removeMessages(MyHandler.MSG_CHECK_LONG_RUNNING_FGS); synchronized (mLock) { mPkgEvents.clear(); Loading Loading @@ -436,9 +533,9 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac boolean hasForegroundServiceNotifications(int uid) { synchronized (mLock) { final SparseArray<ArrayMap<String, ArraySet<Integer>>> map = final SparseArray<ArrayMap<String, SparseBooleanArray>> map = mFGSNotificationIDs.getMap(); final ArrayMap<String, ArraySet<Integer>> pkgs = map.get(uid); final ArrayMap<String, SparseBooleanArray> pkgs = map.get(uid); if (pkgs != null) { for (int i = pkgs.size() - 1; i >= 0; i--) { if (hasForegroundServiceNotificationsLocked(pkgs.keyAt(i), uid)) { Loading @@ -463,7 +560,7 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac pw.println("APPS WITH ACTIVE FOREGROUND SERVICES:"); prefix = " " + prefix; synchronized (mLock) { final SparseArray<ArrayMap<String, ArraySet<Integer>>> map = final SparseArray<ArrayMap<String, SparseBooleanArray>> map = mFGSNotificationIDs.getMap(); if (map.size() == 0) { pw.print(prefix); Loading @@ -472,7 +569,7 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac for (int i = 0, size = map.size(); i < size; i++) { final int uid = map.keyAt(i); final String uidString = UserHandle.formatUid(uid); final ArrayMap<String, ArraySet<Integer>> pkgs = map.valueAt(i); final ArrayMap<String, SparseBooleanArray> pkgs = map.valueAt(i); for (int j = 0, numOfPkgs = pkgs.size(); j < numOfPkgs; j++) { final String pkgName = pkgs.keyAt(j); pw.print(prefix); Loading Loading @@ -622,6 +719,28 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac } } @VisibleForTesting class NotificationListener extends NotificationListenerService { @Override public void onNotificationPosted(StatusBarNotification sbn, RankingMap map) { if (DEBUG_BACKGROUND_FGS_TRACKER) { Slog.i(TAG, "Notification posted: " + sbn); } mHandler.obtainMessage(MyHandler.MSG_NOTIFICATION_POSTED, sbn.getUid(), sbn.getId(), sbn.getPackageName()).sendToTarget(); } @Override public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap, int reason) { if (DEBUG_BACKGROUND_FGS_TRACKER) { Slog.i(TAG, "Notification removed: " + sbn); } mHandler.obtainMessage(MyHandler.MSG_NOTIFICATION_REMOVED, sbn.getUid(), sbn.getId(), sbn.getPackageName()).sendToTarget(); } } static final class AppFGSPolicy extends BaseAppStateEventsPolicy<AppFGSTracker> { /** * Whether or not we should enable the monitoring on abusive FGS. Loading services/core/java/com/android/server/am/BaseAppStateTracker.java +8 −3 Original line number Diff line number Diff line Loading @@ -64,13 +64,15 @@ public abstract class BaseAppStateTracker<T extends BaseAppStatePolicy> { static final int STATE_TYPE_MEDIA_SESSION = 1; static final int STATE_TYPE_FGS_MEDIA_PLAYBACK = 1 << 1; static final int STATE_TYPE_FGS_LOCATION = 1 << 2; static final int STATE_TYPE_PERMISSION = 1 << 3; static final int STATE_TYPE_NUM = 4; static final int STATE_TYPE_FGS_WITH_NOTIFICATION = 1 << 3; static final int STATE_TYPE_PERMISSION = 1 << 4; static final int STATE_TYPE_NUM = 5; static final int STATE_TYPE_INDEX_MEDIA_SESSION = 0; static final int STATE_TYPE_INDEX_FGS_MEDIA_PLAYBACK = 1; static final int STATE_TYPE_INDEX_FGS_LOCATION = 2; static final int STATE_TYPE_INDEX_PERMISSION = 3; static final int STATE_TYPE_INDEX_FGS_WITH_NOTIFICATION = 3; static final int STATE_TYPE_INDEX_PERMISSION = 4; protected final AppRestrictionController mAppRestrictionController; protected final Injector<T> mInjector; Loading Loading @@ -129,6 +131,9 @@ public abstract class BaseAppStateTracker<T extends BaseAppStatePolicy> { case STATE_TYPE_FGS_LOCATION: sb.append("FGS_LOCATION"); break; case STATE_TYPE_FGS_WITH_NOTIFICATION: sb.append("FGS_NOTIFICATION"); break; case STATE_TYPE_PERMISSION: sb.append("PERMISSION"); break; Loading services/tests/mockingservicestests/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ <uses-permission android:name="android.permission.WAKE_LOCK"/> <uses-permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD"/> <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" /> <!-- needed by MasterClearReceiverTest to display a system dialog --> <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"/> Loading services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java +109 −39 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/res/res/values/config.xml +1 −1 Original line number Diff line number Diff line Loading @@ -5796,7 +5796,7 @@ <!-- The types of state where we'll exempt its battery usage during that state. The state here must be one or a combination of STATE_TYPE_* in BaseAppStateTracker. --> <integer name="config_bg_current_drain_exempted_types">9</integer> <integer name="config_bg_current_drain_exempted_types">25</integer> <!-- The behavior when an app has the permission ACCESS_BACKGROUND_LOCATION granted, whether or not the system will use a higher threshold towards its background battery usage Loading
services/core/java/com/android/server/am/AppFGSTracker.java +138 −19 Original line number Diff line number Diff line Loading @@ -32,18 +32,22 @@ import static com.android.server.am.BaseAppStateTracker.ONE_HOUR; import android.annotation.NonNull; import android.app.ActivityManagerInternal.ForegroundServiceStateListener; import android.app.IProcessObserver; import android.content.ComponentName; import android.content.Context; import android.content.pm.ServiceInfo.ForegroundServiceType; import android.os.Handler; import android.os.Message; import android.os.PowerExemptionManager.ReasonCode; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; import android.provider.DeviceConfig; import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.TimeUtils; import com.android.internal.annotations.GuardedBy; Loading @@ -53,7 +57,6 @@ import com.android.server.am.AppFGSTracker.PackageDurations; import com.android.server.am.BaseAppStateEventsTracker.BaseAppStateEventsPolicy; import com.android.server.am.BaseAppStateTimeEvents.BaseTimeEvent; import com.android.server.am.BaseAppStateTracker.Injector; import com.android.server.notification.NotificationManagerInternal; import java.io.PrintWriter; import java.lang.reflect.Constructor; Loading @@ -72,11 +75,14 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac private final MyHandler mHandler; @GuardedBy("mLock") private final UidProcessMap<ArraySet<Integer>> mFGSNotificationIDs = new UidProcessMap<>(); private final UidProcessMap<SparseBooleanArray> mFGSNotificationIDs = new UidProcessMap<>(); // Unlocked since it's only accessed in single thread. private final ArrayMap<PackageDurations, Long> mTmpPkgDurations = new ArrayMap<>(); @VisibleForTesting final NotificationListener mNotificationListener = new NotificationListener(); final IProcessObserver.Stub mProcessObserver = new IProcessObserver.Stub() { @Override public void onForegroundActivitiesChanged(int pid, int uid, boolean fg) { Loading Loading @@ -116,6 +122,8 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac static final int MSG_FOREGROUND_SERVICES_CHANGED = 2; static final int MSG_FOREGROUND_SERVICES_NOTIFICATION_UPDATED = 3; static final int MSG_CHECK_LONG_RUNNING_FGS = 4; static final int MSG_NOTIFICATION_POSTED = 5; static final int MSG_NOTIFICATION_REMOVED = 6; private final AppFGSTracker mTracker; Loading Loading @@ -146,6 +154,12 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac case MSG_CHECK_LONG_RUNNING_FGS: mTracker.checkLongRunningFgs(); break; case MSG_NOTIFICATION_POSTED: mTracker.handleNotificationPosted((String) msg.obj, msg.arg1, msg.arg2); break; case MSG_NOTIFICATION_REMOVED: mTracker.handleNotificationRemoved((String) msg.obj, msg.arg1, msg.arg2); break; } } } Loading Loading @@ -223,20 +237,37 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac private void handleForegroundServiceNotificationUpdated(String packageName, int uid, int notificationId) { synchronized (mLock) { SparseBooleanArray notificationIDs = mFGSNotificationIDs.get(uid, packageName); if (notificationId > 0) { ArraySet<Integer> notificationIDs = mFGSNotificationIDs.get(uid, packageName); if (notificationIDs == null) { notificationIDs = new ArraySet<>(); notificationIDs = new SparseBooleanArray(); mFGSNotificationIDs.put(uid, packageName, notificationIDs); } notificationIDs.add(notificationId); notificationIDs.put(notificationId, false); } else if (notificationId < 0) { final ArraySet<Integer> notificationIDs = mFGSNotificationIDs.get(uid, packageName); if (notificationIDs != null) { notificationIDs.remove(-notificationId); if (notificationIDs.isEmpty()) { final int indexOfKey = notificationIDs.indexOfKey(-notificationId); if (indexOfKey >= 0) { final boolean wasVisible = notificationIDs.valueAt(indexOfKey); notificationIDs.removeAt(indexOfKey); if (notificationIDs.size() == 0) { mFGSNotificationIDs.remove(uid, packageName); } // Walk through the list of FGS notification IDs and see if there are any // visible ones. for (int i = notificationIDs.size() - 1; i >= 0; i--) { if (notificationIDs.valueAt(i)) { // Still visible, nothing to do. return; } } if (wasVisible) { // That was the last visible notification, notify the listeners. notifyListenersOnStateChange(uid, packageName, false, SystemClock.elapsedRealtime(), STATE_TYPE_FGS_WITH_NOTIFICATION); } } } } } Loading @@ -244,20 +275,74 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac @GuardedBy("mLock") private boolean hasForegroundServiceNotificationsLocked(String packageName, int uid) { final ArraySet<Integer> notificationIDs = mFGSNotificationIDs.get(uid, packageName); if (notificationIDs == null || notificationIDs.isEmpty()) { final SparseBooleanArray notificationIDs = mFGSNotificationIDs.get(uid, packageName); if (notificationIDs == null || notificationIDs.size() == 0) { return false; } final NotificationManagerInternal nm = mInjector.getNotificationManagerInternal(); final int userId = UserHandle.getUserId(uid); for (int i = notificationIDs.size() - 1; i >= 0; i--) { if (nm.isNotificationShown(packageName, null, notificationIDs.valueAt(i), userId)) { if (notificationIDs.valueAt(i)) { return true; } } return false; } private void handleNotificationPosted(String pkgName, int uid, int notificationId) { synchronized (mLock) { final SparseBooleanArray notificationIDs = mFGSNotificationIDs.get(uid, pkgName); final int indexOfKey; if (notificationIDs == null || (indexOfKey = notificationIDs.indexOfKey(notificationId)) < 0) { return; } if (notificationIDs.valueAt(indexOfKey)) { // It's already visible. return; } boolean anyVisible = false; // Walk through the list of FGS notification IDs and see if there are any visible ones. for (int i = notificationIDs.size() - 1; i >= 0; i--) { if (notificationIDs.valueAt(i)) { anyVisible = true; break; } } notificationIDs.setValueAt(indexOfKey, true); if (!anyVisible) { // We didn't have any visible FGS notifications but now we have one, // let the listeners know. notifyListenersOnStateChange(uid, pkgName, true, SystemClock.elapsedRealtime(), STATE_TYPE_FGS_WITH_NOTIFICATION); } } } private void handleNotificationRemoved(String pkgName, int uid, int notificationId) { synchronized (mLock) { final SparseBooleanArray notificationIDs = mFGSNotificationIDs.get(uid, pkgName); final int indexOfKey; if (notificationIDs == null || (indexOfKey = notificationIDs.indexOfKey(notificationId)) < 0) { return; } if (!notificationIDs.valueAt(indexOfKey)) { // It's already invisible. return; } notificationIDs.setValueAt(indexOfKey, false); // Walk through the list of FGS notification IDs and see if there are any visible ones. for (int i = notificationIDs.size() - 1; i >= 0; i--) { if (notificationIDs.valueAt(i)) { // Still visible, nothing to do. return; } } // Nothing is visible now, let the listeners know. notifyListenersOnStateChange(uid, pkgName, false, SystemClock.elapsedRealtime(), STATE_TYPE_FGS_WITH_NOTIFICATION); } } @GuardedBy("mLock") private void scheduleDurationCheckLocked(long now) { // Look for the active FGS with longest running time till now. Loading Loading @@ -374,7 +459,19 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac synchronized (mLock) { scheduleDurationCheckLocked(SystemClock.elapsedRealtime()); } try { mNotificationListener.registerAsSystemService(mContext, new ComponentName(mContext, NotificationListener.class), UserHandle.USER_ALL); } catch (RemoteException e) { // Intra-process call, should never happen. } } else { try { mNotificationListener.unregisterAsSystemService(); } catch (RemoteException e) { // Intra-process call, should never happen. } mHandler.removeMessages(MyHandler.MSG_CHECK_LONG_RUNNING_FGS); synchronized (mLock) { mPkgEvents.clear(); Loading Loading @@ -436,9 +533,9 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac boolean hasForegroundServiceNotifications(int uid) { synchronized (mLock) { final SparseArray<ArrayMap<String, ArraySet<Integer>>> map = final SparseArray<ArrayMap<String, SparseBooleanArray>> map = mFGSNotificationIDs.getMap(); final ArrayMap<String, ArraySet<Integer>> pkgs = map.get(uid); final ArrayMap<String, SparseBooleanArray> pkgs = map.get(uid); if (pkgs != null) { for (int i = pkgs.size() - 1; i >= 0; i--) { if (hasForegroundServiceNotificationsLocked(pkgs.keyAt(i), uid)) { Loading @@ -463,7 +560,7 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac pw.println("APPS WITH ACTIVE FOREGROUND SERVICES:"); prefix = " " + prefix; synchronized (mLock) { final SparseArray<ArrayMap<String, ArraySet<Integer>>> map = final SparseArray<ArrayMap<String, SparseBooleanArray>> map = mFGSNotificationIDs.getMap(); if (map.size() == 0) { pw.print(prefix); Loading @@ -472,7 +569,7 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac for (int i = 0, size = map.size(); i < size; i++) { final int uid = map.keyAt(i); final String uidString = UserHandle.formatUid(uid); final ArrayMap<String, ArraySet<Integer>> pkgs = map.valueAt(i); final ArrayMap<String, SparseBooleanArray> pkgs = map.valueAt(i); for (int j = 0, numOfPkgs = pkgs.size(); j < numOfPkgs; j++) { final String pkgName = pkgs.keyAt(j); pw.print(prefix); Loading Loading @@ -622,6 +719,28 @@ final class AppFGSTracker extends BaseAppStateDurationsTracker<AppFGSPolicy, Pac } } @VisibleForTesting class NotificationListener extends NotificationListenerService { @Override public void onNotificationPosted(StatusBarNotification sbn, RankingMap map) { if (DEBUG_BACKGROUND_FGS_TRACKER) { Slog.i(TAG, "Notification posted: " + sbn); } mHandler.obtainMessage(MyHandler.MSG_NOTIFICATION_POSTED, sbn.getUid(), sbn.getId(), sbn.getPackageName()).sendToTarget(); } @Override public void onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap, int reason) { if (DEBUG_BACKGROUND_FGS_TRACKER) { Slog.i(TAG, "Notification removed: " + sbn); } mHandler.obtainMessage(MyHandler.MSG_NOTIFICATION_REMOVED, sbn.getUid(), sbn.getId(), sbn.getPackageName()).sendToTarget(); } } static final class AppFGSPolicy extends BaseAppStateEventsPolicy<AppFGSTracker> { /** * Whether or not we should enable the monitoring on abusive FGS. Loading
services/core/java/com/android/server/am/BaseAppStateTracker.java +8 −3 Original line number Diff line number Diff line Loading @@ -64,13 +64,15 @@ public abstract class BaseAppStateTracker<T extends BaseAppStatePolicy> { static final int STATE_TYPE_MEDIA_SESSION = 1; static final int STATE_TYPE_FGS_MEDIA_PLAYBACK = 1 << 1; static final int STATE_TYPE_FGS_LOCATION = 1 << 2; static final int STATE_TYPE_PERMISSION = 1 << 3; static final int STATE_TYPE_NUM = 4; static final int STATE_TYPE_FGS_WITH_NOTIFICATION = 1 << 3; static final int STATE_TYPE_PERMISSION = 1 << 4; static final int STATE_TYPE_NUM = 5; static final int STATE_TYPE_INDEX_MEDIA_SESSION = 0; static final int STATE_TYPE_INDEX_FGS_MEDIA_PLAYBACK = 1; static final int STATE_TYPE_INDEX_FGS_LOCATION = 2; static final int STATE_TYPE_INDEX_PERMISSION = 3; static final int STATE_TYPE_INDEX_FGS_WITH_NOTIFICATION = 3; static final int STATE_TYPE_INDEX_PERMISSION = 4; protected final AppRestrictionController mAppRestrictionController; protected final Injector<T> mInjector; Loading Loading @@ -129,6 +131,9 @@ public abstract class BaseAppStateTracker<T extends BaseAppStatePolicy> { case STATE_TYPE_FGS_LOCATION: sb.append("FGS_LOCATION"); break; case STATE_TYPE_FGS_WITH_NOTIFICATION: sb.append("FGS_NOTIFICATION"); break; case STATE_TYPE_PERMISSION: sb.append("PERMISSION"); break; Loading
services/tests/mockingservicestests/AndroidManifest.xml +1 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ <uses-permission android:name="android.permission.WAKE_LOCK"/> <uses-permission android:name="android.permission.OVERRIDE_COMPAT_CHANGE_CONFIG_ON_RELEASE_BUILD"/> <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" /> <!-- needed by MasterClearReceiverTest to display a system dialog --> <uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW"/> Loading
services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java +109 −39 File changed.Preview size limit exceeded, changes collapsed. Show changes