Loading apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java +14 −0 Original line number Diff line number Diff line Loading @@ -280,6 +280,20 @@ public interface AppStandbyInternal { */ boolean shouldNoteResponseEventForAllBroadcastSessions(); /** * Returns the list of roles whose holders are exempted from the requirement of starting * a response event after receiving a broadcast. */ @NonNull List<String> getBroadcastResponseExemptedRoles(); /** * Returns the list of permissions whose holders are exempted from the requirement of starting * a response event after receiving a broadcast. */ @NonNull List<String> getBroadcastResponseExemptedPermissions(); /** * Return the last known value corresponding to the {@code key} from * {@link android.provider.DeviceConfig#NAMESPACE_APP_STANDBY} in AppStandbyController. Loading apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +73 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,7 @@ import android.os.UserHandle; import android.provider.DeviceConfig; import android.provider.Settings.Global; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.IndentingPrintWriter; Loading Loading @@ -420,6 +421,26 @@ public class AppStandbyController volatile boolean mNoteResponseEventForAllBroadcastSessions = ConstantsObserver.DEFAULT_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS; /** * List of roles whose holders are exempted from the requirement of starting * a response event after receiving a broadcast. * * The list of roles will be separated by '|' in the string. */ volatile String mBroadcastResponseExemptedRoles = ConstantsObserver.DEFAULT_BROADCAST_RESPONSE_EXEMPTED_ROLES; volatile List<String> mBroadcastResponseExemptedRolesList = Collections.EMPTY_LIST; /** * List of permissions whose holders are exempted from the requirement of starting * a response event after receiving a broadcast. * * The list of permissions will be separated by '|' in the string. */ volatile String mBroadcastResponseExemptedPermissions = ConstantsObserver.DEFAULT_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS; volatile List<String> mBroadcastResponseExemptedPermissionsList = Collections.EMPTY_LIST; /** * Map of last known values of keys in {@link DeviceConfig#NAMESPACE_APP_STANDBY}. * Loading Loading @@ -1959,6 +1980,18 @@ public class AppStandbyController return mNoteResponseEventForAllBroadcastSessions; } @Override @NonNull public List<String> getBroadcastResponseExemptedRoles() { return mBroadcastResponseExemptedRolesList; } @Override @NonNull public List<String> getBroadcastResponseExemptedPermissions() { return mBroadcastResponseExemptedPermissionsList; } @Override @Nullable public String getAppStandbyConstant(@NonNull String key) { Loading Loading @@ -2311,6 +2344,14 @@ public class AppStandbyController pw.print(mNoteResponseEventForAllBroadcastSessions); pw.println(); pw.print(" mBroadcastResponseExemptedRoles"); pw.print(mBroadcastResponseExemptedRoles); pw.println(); pw.print(" mBroadcastResponseExemptedPermissions"); pw.print(mBroadcastResponseExemptedPermissions); pw.println(); pw.println(); pw.print("mAppIdleEnabled="); pw.print(mAppIdleEnabled); pw.print(" mAllowRestrictedBucket="); Loading Loading @@ -2795,6 +2836,10 @@ public class AppStandbyController "broadcast_sessions_with_response_duration_ms"; private static final String KEY_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS = "note_response_event_for_all_broadcast_sessions"; private static final String KEY_BROADCAST_RESPONSE_EXEMPTED_ROLES = "brodacast_response_exempted_roles"; private static final String KEY_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS = "brodacast_response_exempted_permissions"; public static final long DEFAULT_CHECK_IDLE_INTERVAL_MS = COMPRESS_TIME ? ONE_MINUTE : 4 * ONE_HOUR; Loading Loading @@ -2837,6 +2882,11 @@ public class AppStandbyController 2 * ONE_MINUTE; public static final boolean DEFAULT_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS = true; private static final String DEFAULT_BROADCAST_RESPONSE_EXEMPTED_ROLES = ""; private static final String DEFAULT_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS = ""; private final TextUtils.SimpleStringSplitter mStringPipeSplitter = new TextUtils.SimpleStringSplitter('|'); ConstantsObserver(Handler handler) { super(handler); Loading Loading @@ -2989,6 +3039,20 @@ public class AppStandbyController KEY_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS, DEFAULT_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS); break; case KEY_BROADCAST_RESPONSE_EXEMPTED_ROLES: mBroadcastResponseExemptedRoles = properties.getString( KEY_BROADCAST_RESPONSE_EXEMPTED_ROLES, DEFAULT_BROADCAST_RESPONSE_EXEMPTED_ROLES); mBroadcastResponseExemptedRolesList = splitPipeSeparatedString( mBroadcastResponseExemptedRoles); break; case KEY_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS: mBroadcastResponseExemptedPermissions = properties.getString( KEY_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS, DEFAULT_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS); mBroadcastResponseExemptedPermissionsList = splitPipeSeparatedString( mBroadcastResponseExemptedPermissions); break; default: if (!timeThresholdsUpdated && (name.startsWith(KEY_PREFIX_SCREEN_TIME_THRESHOLD) Loading @@ -3003,6 +3067,15 @@ public class AppStandbyController } } private List<String> splitPipeSeparatedString(String string) { final List<String> values = new ArrayList<>(); mStringPipeSplitter.setString(string); while (mStringPipeSplitter.hasNext()) { values.add(mStringPipeSplitter.next()); } return values; } private void updateTimeThresholds() { // Query the values as an atomic set. final DeviceConfig.Properties screenThresholdProperties = Loading services/usage/java/com/android/server/usage/BroadcastResponseStatsTracker.java +123 −1 Original line number Diff line number Diff line Loading @@ -23,15 +23,23 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager.ProcessState; import android.app.role.OnRoleHoldersChangedListener; import android.app.role.RoleManager; import android.app.usage.BroadcastResponseStats; import android.content.Context; import android.content.pm.PackageManager; import android.os.SystemClock; import android.os.UserHandle; import android.permission.PermissionManager; import android.util.ArrayMap; import android.util.ArraySet; import android.util.LongArrayQueue; import android.util.Slog; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.BackgroundThread; import com.android.internal.util.CollectionUtils; import com.android.internal.util.IndentingPrintWriter; import java.lang.annotation.Retention; Loading Loading @@ -71,14 +79,33 @@ class BroadcastResponseStatsTracker { private SparseArray<SparseArray<UserBroadcastResponseStats>> mUserResponseStats = new SparseArray<>(); /** * Cache of package names holding exempted roles. * * Contains the mapping of userId -> {roleName -> <packages>} data. */ // TODO: Use SparseArrayMap to simplify the logic. @GuardedBy("mLock") private SparseArray<ArrayMap<String, List<String>>> mExemptedRoleHoldersCache = new SparseArray<>(); private final OnRoleHoldersChangedListener mRoleHoldersChangedListener = this::onRoleHoldersChanged; private AppStandbyInternal mAppStandby; private BroadcastResponseStatsLogger mLogger; private RoleManager mRoleManager; BroadcastResponseStatsTracker(@NonNull AppStandbyInternal appStandby) { mAppStandby = appStandby; mLogger = new BroadcastResponseStatsLogger(); } void onSystemServicesReady(Context context) { mRoleManager = context.getSystemService(RoleManager.class); mRoleManager.addOnRoleHoldersChangedListenerAsUser(BackgroundThread.getExecutor(), mRoleHoldersChangedListener, UserHandle.ALL); } // TODO (206518114): Move all callbacks handling to a handler thread. void reportBroadcastDispatchEvent(int sourceUid, @NonNull String targetPackage, UserHandle targetUser, long idForResponseEvent, Loading @@ -86,10 +113,19 @@ class BroadcastResponseStatsTracker { mLogger.logBroadcastDispatchEvent(sourceUid, targetPackage, targetUser, idForResponseEvent, timestampMs, targetUidProcState); if (targetUidProcState <= mAppStandby.getBroadcastResponseFgThresholdState()) { // No need to track the broadcast response state while the target app is // No need to track the broadcast response stats while the target app is // in the foreground. return; } if (doesPackageHoldExemptedRole(targetPackage, targetUser)) { // Package holds an exempted role, so no need to track the broadcast response stats. return; } if (doesPackageHoldExemptedPermission(targetPackage, targetUser)) { // Package holds an exempted permission, so no need to track the broadcast response // stats return; } synchronized (mLock) { final ArraySet<BroadcastEvent> broadcastEvents = getOrCreateBroadcastEventsLocked(targetPackage, targetUser); Loading Loading @@ -253,6 +289,62 @@ class BroadcastResponseStatsTracker { } } boolean doesPackageHoldExemptedRole(@NonNull String packageName, @NonNull UserHandle user) { final List<String> exemptedRoles = mAppStandby.getBroadcastResponseExemptedRoles(); synchronized (mLock) { for (int i = exemptedRoles.size() - 1; i >= 0; --i) { final String roleName = exemptedRoles.get(i); final List<String> roleHolders = getRoleHoldersLocked(roleName, user); if (CollectionUtils.contains(roleHolders, packageName)) { return true; } } } return false; } boolean doesPackageHoldExemptedPermission(@NonNull String packageName, @NonNull UserHandle user) { final List<String> exemptedPermissions = mAppStandby .getBroadcastResponseExemptedPermissions(); for (int i = exemptedPermissions.size() - 1; i >= 0; --i) { final String permissionName = exemptedPermissions.get(i); if (PermissionManager.checkPackageNamePermission(permissionName, packageName, user.getIdentifier()) == PackageManager.PERMISSION_GRANTED) { return true; } } return false; } @GuardedBy("mLock") @Nullable private List<String> getRoleHoldersLocked(@NonNull String roleName, @NonNull UserHandle user) { ArrayMap<String, List<String>> roleHoldersForUser = mExemptedRoleHoldersCache.get( user.getIdentifier()); if (roleHoldersForUser == null) { roleHoldersForUser = new ArrayMap<>(); mExemptedRoleHoldersCache.put(user.getIdentifier(), roleHoldersForUser); } List<String> roleHolders = roleHoldersForUser.get(roleName); if (roleHolders == null && mRoleManager != null) { roleHolders = mRoleManager.getRoleHoldersAsUser(roleName, user); roleHoldersForUser.put(roleName, roleHolders); } return roleHolders; } private void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) { synchronized (mLock) { final ArrayMap<String, List<String>> roleHoldersForUser = mExemptedRoleHoldersCache.get(user.getIdentifier()); if (roleHoldersForUser == null) { return; } roleHoldersForUser.remove(roleName); } } void onUserRemoved(@UserIdInt int userId) { synchronized (mLock) { mUserBroadcastEvents.remove(userId); Loading @@ -260,6 +352,7 @@ class BroadcastResponseStatsTracker { for (int i = mUserResponseStats.size() - 1; i >= 0; --i) { mUserResponseStats.valueAt(i).remove(userId); } mExemptedRoleHoldersCache.remove(userId); } } Loading Loading @@ -373,6 +466,8 @@ class BroadcastResponseStatsTracker { ipw.println(); dumpResponseStatsLocked(ipw); ipw.println(); dumpRoleHoldersLocked(ipw); ipw.println(); mLogger.dumpLogs(ipw); } Loading Loading @@ -417,5 +512,32 @@ class BroadcastResponseStatsTracker { } ipw.decreaseIndent(); } @GuardedBy("mLock") private void dumpRoleHoldersLocked(@NonNull IndentingPrintWriter ipw) { ipw.println("Role holders:"); ipw.increaseIndent(); for (int userIdx = 0; userIdx < mExemptedRoleHoldersCache.size(); ++userIdx) { final int userId = mExemptedRoleHoldersCache.keyAt(userIdx); final ArrayMap<String, List<String>> roleHoldersForUser = mExemptedRoleHoldersCache.valueAt(userIdx); ipw.println("User " + userId + ":"); ipw.increaseIndent(); for (int roleIdx = 0; roleIdx < roleHoldersForUser.size(); ++roleIdx) { final String roleName = roleHoldersForUser.keyAt(roleIdx); final List<String> holders = roleHoldersForUser.valueAt(roleIdx); ipw.print(roleName + ": "); for (int holderIdx = 0; holderIdx < holders.size(); ++holderIdx) { if (holderIdx > 0) { ipw.print(", "); } ipw.print(holders.get(holderIdx)); } ipw.println(); } ipw.decreaseIndent(); } ipw.decreaseIndent(); } } services/usage/java/com/android/server/usage/UsageStatsService.java +1 −0 Original line number Diff line number Diff line Loading @@ -357,6 +357,7 @@ public class UsageStatsService extends SystemService implements getDpmInternal(); // initialize mShortcutServiceInternal getShortcutServiceInternal(); mResponseStatsTracker.onSystemServicesReady(getContext()); if (ENABLE_KERNEL_UPDATES && KERNEL_COUNTER_FILE.exists()) { try { Loading Loading
apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java +14 −0 Original line number Diff line number Diff line Loading @@ -280,6 +280,20 @@ public interface AppStandbyInternal { */ boolean shouldNoteResponseEventForAllBroadcastSessions(); /** * Returns the list of roles whose holders are exempted from the requirement of starting * a response event after receiving a broadcast. */ @NonNull List<String> getBroadcastResponseExemptedRoles(); /** * Returns the list of permissions whose holders are exempted from the requirement of starting * a response event after receiving a broadcast. */ @NonNull List<String> getBroadcastResponseExemptedPermissions(); /** * Return the last known value corresponding to the {@code key} from * {@link android.provider.DeviceConfig#NAMESPACE_APP_STANDBY} in AppStandbyController. Loading
apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java +73 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,7 @@ import android.os.UserHandle; import android.provider.DeviceConfig; import android.provider.Settings.Global; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.IndentingPrintWriter; Loading Loading @@ -420,6 +421,26 @@ public class AppStandbyController volatile boolean mNoteResponseEventForAllBroadcastSessions = ConstantsObserver.DEFAULT_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS; /** * List of roles whose holders are exempted from the requirement of starting * a response event after receiving a broadcast. * * The list of roles will be separated by '|' in the string. */ volatile String mBroadcastResponseExemptedRoles = ConstantsObserver.DEFAULT_BROADCAST_RESPONSE_EXEMPTED_ROLES; volatile List<String> mBroadcastResponseExemptedRolesList = Collections.EMPTY_LIST; /** * List of permissions whose holders are exempted from the requirement of starting * a response event after receiving a broadcast. * * The list of permissions will be separated by '|' in the string. */ volatile String mBroadcastResponseExemptedPermissions = ConstantsObserver.DEFAULT_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS; volatile List<String> mBroadcastResponseExemptedPermissionsList = Collections.EMPTY_LIST; /** * Map of last known values of keys in {@link DeviceConfig#NAMESPACE_APP_STANDBY}. * Loading Loading @@ -1959,6 +1980,18 @@ public class AppStandbyController return mNoteResponseEventForAllBroadcastSessions; } @Override @NonNull public List<String> getBroadcastResponseExemptedRoles() { return mBroadcastResponseExemptedRolesList; } @Override @NonNull public List<String> getBroadcastResponseExemptedPermissions() { return mBroadcastResponseExemptedPermissionsList; } @Override @Nullable public String getAppStandbyConstant(@NonNull String key) { Loading Loading @@ -2311,6 +2344,14 @@ public class AppStandbyController pw.print(mNoteResponseEventForAllBroadcastSessions); pw.println(); pw.print(" mBroadcastResponseExemptedRoles"); pw.print(mBroadcastResponseExemptedRoles); pw.println(); pw.print(" mBroadcastResponseExemptedPermissions"); pw.print(mBroadcastResponseExemptedPermissions); pw.println(); pw.println(); pw.print("mAppIdleEnabled="); pw.print(mAppIdleEnabled); pw.print(" mAllowRestrictedBucket="); Loading Loading @@ -2795,6 +2836,10 @@ public class AppStandbyController "broadcast_sessions_with_response_duration_ms"; private static final String KEY_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS = "note_response_event_for_all_broadcast_sessions"; private static final String KEY_BROADCAST_RESPONSE_EXEMPTED_ROLES = "brodacast_response_exempted_roles"; private static final String KEY_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS = "brodacast_response_exempted_permissions"; public static final long DEFAULT_CHECK_IDLE_INTERVAL_MS = COMPRESS_TIME ? ONE_MINUTE : 4 * ONE_HOUR; Loading Loading @@ -2837,6 +2882,11 @@ public class AppStandbyController 2 * ONE_MINUTE; public static final boolean DEFAULT_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS = true; private static final String DEFAULT_BROADCAST_RESPONSE_EXEMPTED_ROLES = ""; private static final String DEFAULT_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS = ""; private final TextUtils.SimpleStringSplitter mStringPipeSplitter = new TextUtils.SimpleStringSplitter('|'); ConstantsObserver(Handler handler) { super(handler); Loading Loading @@ -2989,6 +3039,20 @@ public class AppStandbyController KEY_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS, DEFAULT_NOTE_RESPONSE_EVENT_FOR_ALL_BROADCAST_SESSIONS); break; case KEY_BROADCAST_RESPONSE_EXEMPTED_ROLES: mBroadcastResponseExemptedRoles = properties.getString( KEY_BROADCAST_RESPONSE_EXEMPTED_ROLES, DEFAULT_BROADCAST_RESPONSE_EXEMPTED_ROLES); mBroadcastResponseExemptedRolesList = splitPipeSeparatedString( mBroadcastResponseExemptedRoles); break; case KEY_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS: mBroadcastResponseExemptedPermissions = properties.getString( KEY_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS, DEFAULT_BROADCAST_RESPONSE_EXEMPTED_PERMISSIONS); mBroadcastResponseExemptedPermissionsList = splitPipeSeparatedString( mBroadcastResponseExemptedPermissions); break; default: if (!timeThresholdsUpdated && (name.startsWith(KEY_PREFIX_SCREEN_TIME_THRESHOLD) Loading @@ -3003,6 +3067,15 @@ public class AppStandbyController } } private List<String> splitPipeSeparatedString(String string) { final List<String> values = new ArrayList<>(); mStringPipeSplitter.setString(string); while (mStringPipeSplitter.hasNext()) { values.add(mStringPipeSplitter.next()); } return values; } private void updateTimeThresholds() { // Query the values as an atomic set. final DeviceConfig.Properties screenThresholdProperties = Loading
services/usage/java/com/android/server/usage/BroadcastResponseStatsTracker.java +123 −1 Original line number Diff line number Diff line Loading @@ -23,15 +23,23 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.ActivityManager.ProcessState; import android.app.role.OnRoleHoldersChangedListener; import android.app.role.RoleManager; import android.app.usage.BroadcastResponseStats; import android.content.Context; import android.content.pm.PackageManager; import android.os.SystemClock; import android.os.UserHandle; import android.permission.PermissionManager; import android.util.ArrayMap; import android.util.ArraySet; import android.util.LongArrayQueue; import android.util.Slog; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.os.BackgroundThread; import com.android.internal.util.CollectionUtils; import com.android.internal.util.IndentingPrintWriter; import java.lang.annotation.Retention; Loading Loading @@ -71,14 +79,33 @@ class BroadcastResponseStatsTracker { private SparseArray<SparseArray<UserBroadcastResponseStats>> mUserResponseStats = new SparseArray<>(); /** * Cache of package names holding exempted roles. * * Contains the mapping of userId -> {roleName -> <packages>} data. */ // TODO: Use SparseArrayMap to simplify the logic. @GuardedBy("mLock") private SparseArray<ArrayMap<String, List<String>>> mExemptedRoleHoldersCache = new SparseArray<>(); private final OnRoleHoldersChangedListener mRoleHoldersChangedListener = this::onRoleHoldersChanged; private AppStandbyInternal mAppStandby; private BroadcastResponseStatsLogger mLogger; private RoleManager mRoleManager; BroadcastResponseStatsTracker(@NonNull AppStandbyInternal appStandby) { mAppStandby = appStandby; mLogger = new BroadcastResponseStatsLogger(); } void onSystemServicesReady(Context context) { mRoleManager = context.getSystemService(RoleManager.class); mRoleManager.addOnRoleHoldersChangedListenerAsUser(BackgroundThread.getExecutor(), mRoleHoldersChangedListener, UserHandle.ALL); } // TODO (206518114): Move all callbacks handling to a handler thread. void reportBroadcastDispatchEvent(int sourceUid, @NonNull String targetPackage, UserHandle targetUser, long idForResponseEvent, Loading @@ -86,10 +113,19 @@ class BroadcastResponseStatsTracker { mLogger.logBroadcastDispatchEvent(sourceUid, targetPackage, targetUser, idForResponseEvent, timestampMs, targetUidProcState); if (targetUidProcState <= mAppStandby.getBroadcastResponseFgThresholdState()) { // No need to track the broadcast response state while the target app is // No need to track the broadcast response stats while the target app is // in the foreground. return; } if (doesPackageHoldExemptedRole(targetPackage, targetUser)) { // Package holds an exempted role, so no need to track the broadcast response stats. return; } if (doesPackageHoldExemptedPermission(targetPackage, targetUser)) { // Package holds an exempted permission, so no need to track the broadcast response // stats return; } synchronized (mLock) { final ArraySet<BroadcastEvent> broadcastEvents = getOrCreateBroadcastEventsLocked(targetPackage, targetUser); Loading Loading @@ -253,6 +289,62 @@ class BroadcastResponseStatsTracker { } } boolean doesPackageHoldExemptedRole(@NonNull String packageName, @NonNull UserHandle user) { final List<String> exemptedRoles = mAppStandby.getBroadcastResponseExemptedRoles(); synchronized (mLock) { for (int i = exemptedRoles.size() - 1; i >= 0; --i) { final String roleName = exemptedRoles.get(i); final List<String> roleHolders = getRoleHoldersLocked(roleName, user); if (CollectionUtils.contains(roleHolders, packageName)) { return true; } } } return false; } boolean doesPackageHoldExemptedPermission(@NonNull String packageName, @NonNull UserHandle user) { final List<String> exemptedPermissions = mAppStandby .getBroadcastResponseExemptedPermissions(); for (int i = exemptedPermissions.size() - 1; i >= 0; --i) { final String permissionName = exemptedPermissions.get(i); if (PermissionManager.checkPackageNamePermission(permissionName, packageName, user.getIdentifier()) == PackageManager.PERMISSION_GRANTED) { return true; } } return false; } @GuardedBy("mLock") @Nullable private List<String> getRoleHoldersLocked(@NonNull String roleName, @NonNull UserHandle user) { ArrayMap<String, List<String>> roleHoldersForUser = mExemptedRoleHoldersCache.get( user.getIdentifier()); if (roleHoldersForUser == null) { roleHoldersForUser = new ArrayMap<>(); mExemptedRoleHoldersCache.put(user.getIdentifier(), roleHoldersForUser); } List<String> roleHolders = roleHoldersForUser.get(roleName); if (roleHolders == null && mRoleManager != null) { roleHolders = mRoleManager.getRoleHoldersAsUser(roleName, user); roleHoldersForUser.put(roleName, roleHolders); } return roleHolders; } private void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) { synchronized (mLock) { final ArrayMap<String, List<String>> roleHoldersForUser = mExemptedRoleHoldersCache.get(user.getIdentifier()); if (roleHoldersForUser == null) { return; } roleHoldersForUser.remove(roleName); } } void onUserRemoved(@UserIdInt int userId) { synchronized (mLock) { mUserBroadcastEvents.remove(userId); Loading @@ -260,6 +352,7 @@ class BroadcastResponseStatsTracker { for (int i = mUserResponseStats.size() - 1; i >= 0; --i) { mUserResponseStats.valueAt(i).remove(userId); } mExemptedRoleHoldersCache.remove(userId); } } Loading Loading @@ -373,6 +466,8 @@ class BroadcastResponseStatsTracker { ipw.println(); dumpResponseStatsLocked(ipw); ipw.println(); dumpRoleHoldersLocked(ipw); ipw.println(); mLogger.dumpLogs(ipw); } Loading Loading @@ -417,5 +512,32 @@ class BroadcastResponseStatsTracker { } ipw.decreaseIndent(); } @GuardedBy("mLock") private void dumpRoleHoldersLocked(@NonNull IndentingPrintWriter ipw) { ipw.println("Role holders:"); ipw.increaseIndent(); for (int userIdx = 0; userIdx < mExemptedRoleHoldersCache.size(); ++userIdx) { final int userId = mExemptedRoleHoldersCache.keyAt(userIdx); final ArrayMap<String, List<String>> roleHoldersForUser = mExemptedRoleHoldersCache.valueAt(userIdx); ipw.println("User " + userId + ":"); ipw.increaseIndent(); for (int roleIdx = 0; roleIdx < roleHoldersForUser.size(); ++roleIdx) { final String roleName = roleHoldersForUser.keyAt(roleIdx); final List<String> holders = roleHoldersForUser.valueAt(roleIdx); ipw.print(roleName + ": "); for (int holderIdx = 0; holderIdx < holders.size(); ++holderIdx) { if (holderIdx > 0) { ipw.print(", "); } ipw.print(holders.get(holderIdx)); } ipw.println(); } ipw.decreaseIndent(); } ipw.decreaseIndent(); } }
services/usage/java/com/android/server/usage/UsageStatsService.java +1 −0 Original line number Diff line number Diff line Loading @@ -357,6 +357,7 @@ public class UsageStatsService extends SystemService implements getDpmInternal(); // initialize mShortcutServiceInternal getShortcutServiceInternal(); mResponseStatsTracker.onSystemServicesReady(getContext()); if (ENABLE_KERNEL_UPDATES && KERNEL_COUNTER_FILE.exists()) { try { Loading