Loading services/usage/java/com/android/server/usage/UsageStatsService.java +156 −137 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ import com.android.internal.util.CollectionUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.IndentingPrintWriter; import com.android.server.IoThread; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener; Loading Loading @@ -201,7 +202,8 @@ public class UsageStatsService extends SystemService implements static final int MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED = 9; private final Object mLock = new Object(); Handler mHandler; private Handler mHandler; private Handler mIoHandler; AppOpsManager mAppOps; UserManager mUserManager; PackageManager mPackageManager; Loading Loading @@ -233,7 +235,7 @@ public class UsageStatsService extends SystemService implements private final SparseArray<LinkedList<Event>> mReportedEvents = new SparseArray<>(); final SparseArray<ArraySet<String>> mUsageReporters = new SparseArray(); final SparseArray<ActivityData> mVisibleActivities = new SparseArray(); @GuardedBy("mLock") @GuardedBy("mLaunchTimeAlarmQueues") // Don't hold the main lock private final SparseArray<LaunchTimeAlarmQueue> mLaunchTimeAlarmQueues = new SparseArray<>(); @GuardedBy("mUsageEventListeners") // Don't hold the main lock when calling out private final ArraySet<UsageStatsManagerInternal.UsageEventListener> mUsageEventListeners = Loading Loading @@ -279,6 +281,38 @@ public class UsageStatsService extends SystemService implements } } private final Handler.Callback mIoHandlerCallback = (msg) -> { switch (msg.what) { case MSG_UID_STATE_CHANGED: { final int uid = msg.arg1; final int procState = msg.arg2; final int newCounter = (procState <= ActivityManager.PROCESS_STATE_TOP) ? 0 : 1; synchronized (mUidToKernelCounter) { final int oldCounter = mUidToKernelCounter.get(uid, 0); if (newCounter != oldCounter) { mUidToKernelCounter.put(uid, newCounter); try { FileUtils.stringToFile(KERNEL_COUNTER_FILE, uid + " " + newCounter); } catch (IOException e) { Slog.w(TAG, "Failed to update counter set: " + e); } } } return true; } case MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK: { final int userId = msg.arg1; Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "usageStatsHandleEstimatedLaunchTimesOnUser(" + userId + ")"); handleEstimatedLaunchTimesOnUserUnlock(userId); Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); return true; } } return false; }; private final Injector mInjector; public UsageStatsService(Context context) { Loading @@ -299,6 +333,7 @@ public class UsageStatsService extends SystemService implements mPackageManager = getContext().getPackageManager(); mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); mHandler = new H(BackgroundThread.get().getLooper()); mIoHandler = new Handler(IoThread.get().getLooper(), mIoHandlerCallback); mAppStandby = mInjector.getAppStandbyController(getContext()); mResponseStatsTracker = new BroadcastResponseStatsTracker(mAppStandby, getContext()); Loading Loading @@ -424,6 +459,9 @@ public class UsageStatsService extends SystemService implements } mUserUnlockedStates.remove(userId); mUserState.put(userId, null); // release the service (mainly for GC) } synchronized (mLaunchTimeAlarmQueues) { LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); if (alarmQueue != null) { alarmQueue.removeAllAlarms(); Loading Loading @@ -479,10 +517,12 @@ public class UsageStatsService extends SystemService implements } reportEvent(unlockEvent, userId); mHandler.obtainMessage(MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK, userId, 0).sendToTarget(); mIoHandler.obtainMessage(MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK, userId, 0).sendToTarget(); // Remove all the stats stored in system DE. deleteRecursively(new File(Environment.getDataSystemDeDirectory(userId), "usagestats")); // Force a flush to disk for the current user to ensure important events are persisted. // Note: there is a very very small chance that the system crashes between deleting // the stats above from DE and persisting them to CE here in which case we will lose Loading Loading @@ -601,7 +641,7 @@ public class UsageStatsService extends SystemService implements private final IUidObserver mUidObserver = new UidObserver() { @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) { mHandler.obtainMessage(MSG_UID_STATE_CHANGED, uid, procState).sendToTarget(); mIoHandler.obtainMessage(MSG_UID_STATE_CHANGED, uid, procState).sendToTarget(); } @Override Loading Loading @@ -673,16 +713,18 @@ public class UsageStatsService extends SystemService implements callingPid, callingUid) == PackageManager.PERMISSION_GRANTED); } private static void deleteRecursively(File f) { File[] files = f.listFiles(); private static void deleteRecursively(final File path) { if (path.isDirectory()) { final File[] files = path.listFiles(); if (files != null) { for (File subFile : files) { deleteRecursively(subFile); } } } if (f.exists() && !f.delete()) { Slog.e(TAG, "Failed to delete " + f); if (path.exists() && !path.delete()) { Slog.e(TAG, "Failed to delete " + path); } } Loading Loading @@ -1244,6 +1286,9 @@ public class UsageStatsService extends SystemService implements Slog.i(TAG, "Removing user " + userId + " and all data."); mUserState.remove(userId); mAppTimeLimit.onUserRemoved(userId); } synchronized (mLaunchTimeAlarmQueues) { final LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); if (alarmQueue != null) { alarmQueue.removeAllAlarms(); Loading Loading @@ -1274,6 +1319,13 @@ public class UsageStatsService extends SystemService implements } } synchronized (mLaunchTimeAlarmQueues) { final LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); if (alarmQueue != null) { alarmQueue.removeAlarmForKey(packageName); } } final int tokenRemoved; synchronized (mLock) { final long timeRemoved = System.currentTimeMillis(); Loading @@ -1282,10 +1334,7 @@ public class UsageStatsService extends SystemService implements // when the user service is initialized and package manager is queried. return; } final LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); if (alarmQueue != null) { alarmQueue.removeAlarmForKey(packageName); } final UserUsageStatsService userService = mUserState.get(userId); if (userService == null) { return; Loading Loading @@ -1495,23 +1544,27 @@ public class UsageStatsService extends SystemService implements estimatedLaunchTime = calculateEstimatedPackageLaunchTime(userId, packageName); mAppStandby.setEstimatedLaunchTime(packageName, userId, estimatedLaunchTime); synchronized (mLock) { getOrCreateLaunchTimeAlarmQueue(userId).addAlarm(packageName, SystemClock.elapsedRealtime() + (estimatedLaunchTime - now)); } return estimatedLaunchTime; } private LaunchTimeAlarmQueue getOrCreateLaunchTimeAlarmQueue(int userId) { synchronized (mLaunchTimeAlarmQueues) { LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); if (alarmQueue == null) { alarmQueue = new LaunchTimeAlarmQueue( userId, getContext(), BackgroundThread.get().getLooper()); mLaunchTimeAlarmQueues.put(userId, alarmQueue); } alarmQueue.addAlarm(packageName, SystemClock.elapsedRealtime() + (estimatedLaunchTime - now)); } return alarmQueue; } return estimatedLaunchTime; } @CurrentTimeMillisLong private long calculateEstimatedPackageLaunchTime(int userId, String packageName) { synchronized (mLock) { final long endTime = System.currentTimeMillis(); final long beginTime = endTime - ONE_WEEK; final long unknownTime = endTime + UNKNOWN_LAUNCH_TIME_DELAY_MS; Loading Loading @@ -1549,7 +1602,6 @@ public class UsageStatsService extends SystemService implements } while (events.getNextEvent(event)); return unknownTime; } } @CurrentTimeMillisLong private static long calculateNextLaunchTime( Loading @@ -1569,7 +1621,6 @@ public class UsageStatsService extends SystemService implements } private void handleEstimatedLaunchTimesOnUserUnlock(int userId) { synchronized (mLock) { final long nowElapsed = SystemClock.elapsedRealtime(); final long now = System.currentTimeMillis(); final long beginTime = now - ONE_WEEK; Loading @@ -1580,13 +1631,8 @@ public class UsageStatsService extends SystemService implements } final ArrayMap<String, Boolean> hasMoreThan24HoursOfHistory = new ArrayMap<>(); final UsageEvents.Event event = new UsageEvents.Event(); LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); if (alarmQueue == null) { alarmQueue = new LaunchTimeAlarmQueue( userId, getContext(), BackgroundThread.get().getLooper()); mLaunchTimeAlarmQueues.put(userId, alarmQueue); } boolean changedTimes = false; final LaunchTimeAlarmQueue alarmQueue = getOrCreateLaunchTimeAlarmQueue(userId); for (boolean unprocessedEvent = events.getNextEvent(event); unprocessedEvent; unprocessedEvent = events.getNextEvent(event)) { final String packageName = event.getPackageName(); Loading Loading @@ -1625,7 +1671,6 @@ public class UsageStatsService extends SystemService implements mHandler.sendEmptyMessage(MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED); } } } private void setEstimatedLaunchTime(int userId, String packageName, @CurrentTimeMillisLong long estimatedLaunchTime) { Loading Loading @@ -1995,37 +2040,11 @@ public class UsageStatsService extends SystemService implements case MSG_PACKAGE_REMOVED: onPackageRemoved(msg.arg1, (String) msg.obj); break; case MSG_UID_STATE_CHANGED: { final int uid = msg.arg1; final int procState = msg.arg2; final int newCounter = (procState <= ActivityManager.PROCESS_STATE_TOP) ? 0 : 1; synchronized (mUidToKernelCounter) { final int oldCounter = mUidToKernelCounter.get(uid, 0); if (newCounter != oldCounter) { mUidToKernelCounter.put(uid, newCounter); try { FileUtils.stringToFile(KERNEL_COUNTER_FILE, uid + " " + newCounter); } catch (IOException e) { Slog.w(TAG, "Failed to update counter set: " + e); } } } break; } case MSG_ON_START: synchronized (mLock) { loadGlobalComponentUsageLocked(); } break; case MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK: { final int userId = msg.arg1; Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "usageStatsHandleEstimatedLaunchTimesOnUser(" + userId + ")"); handleEstimatedLaunchTimesOnUserUnlock(userId); Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } break; case MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED: { removeMessages(MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED); Loading Loading
services/usage/java/com/android/server/usage/UsageStatsService.java +156 −137 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ import com.android.internal.util.CollectionUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.FrameworkStatsLog; import com.android.internal.util.IndentingPrintWriter; import com.android.server.IoThread; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener; Loading Loading @@ -201,7 +202,8 @@ public class UsageStatsService extends SystemService implements static final int MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED = 9; private final Object mLock = new Object(); Handler mHandler; private Handler mHandler; private Handler mIoHandler; AppOpsManager mAppOps; UserManager mUserManager; PackageManager mPackageManager; Loading Loading @@ -233,7 +235,7 @@ public class UsageStatsService extends SystemService implements private final SparseArray<LinkedList<Event>> mReportedEvents = new SparseArray<>(); final SparseArray<ArraySet<String>> mUsageReporters = new SparseArray(); final SparseArray<ActivityData> mVisibleActivities = new SparseArray(); @GuardedBy("mLock") @GuardedBy("mLaunchTimeAlarmQueues") // Don't hold the main lock private final SparseArray<LaunchTimeAlarmQueue> mLaunchTimeAlarmQueues = new SparseArray<>(); @GuardedBy("mUsageEventListeners") // Don't hold the main lock when calling out private final ArraySet<UsageStatsManagerInternal.UsageEventListener> mUsageEventListeners = Loading Loading @@ -279,6 +281,38 @@ public class UsageStatsService extends SystemService implements } } private final Handler.Callback mIoHandlerCallback = (msg) -> { switch (msg.what) { case MSG_UID_STATE_CHANGED: { final int uid = msg.arg1; final int procState = msg.arg2; final int newCounter = (procState <= ActivityManager.PROCESS_STATE_TOP) ? 0 : 1; synchronized (mUidToKernelCounter) { final int oldCounter = mUidToKernelCounter.get(uid, 0); if (newCounter != oldCounter) { mUidToKernelCounter.put(uid, newCounter); try { FileUtils.stringToFile(KERNEL_COUNTER_FILE, uid + " " + newCounter); } catch (IOException e) { Slog.w(TAG, "Failed to update counter set: " + e); } } } return true; } case MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK: { final int userId = msg.arg1; Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "usageStatsHandleEstimatedLaunchTimesOnUser(" + userId + ")"); handleEstimatedLaunchTimesOnUserUnlock(userId); Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); return true; } } return false; }; private final Injector mInjector; public UsageStatsService(Context context) { Loading @@ -299,6 +333,7 @@ public class UsageStatsService extends SystemService implements mPackageManager = getContext().getPackageManager(); mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); mHandler = new H(BackgroundThread.get().getLooper()); mIoHandler = new Handler(IoThread.get().getLooper(), mIoHandlerCallback); mAppStandby = mInjector.getAppStandbyController(getContext()); mResponseStatsTracker = new BroadcastResponseStatsTracker(mAppStandby, getContext()); Loading Loading @@ -424,6 +459,9 @@ public class UsageStatsService extends SystemService implements } mUserUnlockedStates.remove(userId); mUserState.put(userId, null); // release the service (mainly for GC) } synchronized (mLaunchTimeAlarmQueues) { LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); if (alarmQueue != null) { alarmQueue.removeAllAlarms(); Loading Loading @@ -479,10 +517,12 @@ public class UsageStatsService extends SystemService implements } reportEvent(unlockEvent, userId); mHandler.obtainMessage(MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK, userId, 0).sendToTarget(); mIoHandler.obtainMessage(MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK, userId, 0).sendToTarget(); // Remove all the stats stored in system DE. deleteRecursively(new File(Environment.getDataSystemDeDirectory(userId), "usagestats")); // Force a flush to disk for the current user to ensure important events are persisted. // Note: there is a very very small chance that the system crashes between deleting // the stats above from DE and persisting them to CE here in which case we will lose Loading Loading @@ -601,7 +641,7 @@ public class UsageStatsService extends SystemService implements private final IUidObserver mUidObserver = new UidObserver() { @Override public void onUidStateChanged(int uid, int procState, long procStateSeq, int capability) { mHandler.obtainMessage(MSG_UID_STATE_CHANGED, uid, procState).sendToTarget(); mIoHandler.obtainMessage(MSG_UID_STATE_CHANGED, uid, procState).sendToTarget(); } @Override Loading Loading @@ -673,16 +713,18 @@ public class UsageStatsService extends SystemService implements callingPid, callingUid) == PackageManager.PERMISSION_GRANTED); } private static void deleteRecursively(File f) { File[] files = f.listFiles(); private static void deleteRecursively(final File path) { if (path.isDirectory()) { final File[] files = path.listFiles(); if (files != null) { for (File subFile : files) { deleteRecursively(subFile); } } } if (f.exists() && !f.delete()) { Slog.e(TAG, "Failed to delete " + f); if (path.exists() && !path.delete()) { Slog.e(TAG, "Failed to delete " + path); } } Loading Loading @@ -1244,6 +1286,9 @@ public class UsageStatsService extends SystemService implements Slog.i(TAG, "Removing user " + userId + " and all data."); mUserState.remove(userId); mAppTimeLimit.onUserRemoved(userId); } synchronized (mLaunchTimeAlarmQueues) { final LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); if (alarmQueue != null) { alarmQueue.removeAllAlarms(); Loading Loading @@ -1274,6 +1319,13 @@ public class UsageStatsService extends SystemService implements } } synchronized (mLaunchTimeAlarmQueues) { final LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); if (alarmQueue != null) { alarmQueue.removeAlarmForKey(packageName); } } final int tokenRemoved; synchronized (mLock) { final long timeRemoved = System.currentTimeMillis(); Loading @@ -1282,10 +1334,7 @@ public class UsageStatsService extends SystemService implements // when the user service is initialized and package manager is queried. return; } final LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); if (alarmQueue != null) { alarmQueue.removeAlarmForKey(packageName); } final UserUsageStatsService userService = mUserState.get(userId); if (userService == null) { return; Loading Loading @@ -1495,23 +1544,27 @@ public class UsageStatsService extends SystemService implements estimatedLaunchTime = calculateEstimatedPackageLaunchTime(userId, packageName); mAppStandby.setEstimatedLaunchTime(packageName, userId, estimatedLaunchTime); synchronized (mLock) { getOrCreateLaunchTimeAlarmQueue(userId).addAlarm(packageName, SystemClock.elapsedRealtime() + (estimatedLaunchTime - now)); } return estimatedLaunchTime; } private LaunchTimeAlarmQueue getOrCreateLaunchTimeAlarmQueue(int userId) { synchronized (mLaunchTimeAlarmQueues) { LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); if (alarmQueue == null) { alarmQueue = new LaunchTimeAlarmQueue( userId, getContext(), BackgroundThread.get().getLooper()); mLaunchTimeAlarmQueues.put(userId, alarmQueue); } alarmQueue.addAlarm(packageName, SystemClock.elapsedRealtime() + (estimatedLaunchTime - now)); } return alarmQueue; } return estimatedLaunchTime; } @CurrentTimeMillisLong private long calculateEstimatedPackageLaunchTime(int userId, String packageName) { synchronized (mLock) { final long endTime = System.currentTimeMillis(); final long beginTime = endTime - ONE_WEEK; final long unknownTime = endTime + UNKNOWN_LAUNCH_TIME_DELAY_MS; Loading Loading @@ -1549,7 +1602,6 @@ public class UsageStatsService extends SystemService implements } while (events.getNextEvent(event)); return unknownTime; } } @CurrentTimeMillisLong private static long calculateNextLaunchTime( Loading @@ -1569,7 +1621,6 @@ public class UsageStatsService extends SystemService implements } private void handleEstimatedLaunchTimesOnUserUnlock(int userId) { synchronized (mLock) { final long nowElapsed = SystemClock.elapsedRealtime(); final long now = System.currentTimeMillis(); final long beginTime = now - ONE_WEEK; Loading @@ -1580,13 +1631,8 @@ public class UsageStatsService extends SystemService implements } final ArrayMap<String, Boolean> hasMoreThan24HoursOfHistory = new ArrayMap<>(); final UsageEvents.Event event = new UsageEvents.Event(); LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); if (alarmQueue == null) { alarmQueue = new LaunchTimeAlarmQueue( userId, getContext(), BackgroundThread.get().getLooper()); mLaunchTimeAlarmQueues.put(userId, alarmQueue); } boolean changedTimes = false; final LaunchTimeAlarmQueue alarmQueue = getOrCreateLaunchTimeAlarmQueue(userId); for (boolean unprocessedEvent = events.getNextEvent(event); unprocessedEvent; unprocessedEvent = events.getNextEvent(event)) { final String packageName = event.getPackageName(); Loading Loading @@ -1625,7 +1671,6 @@ public class UsageStatsService extends SystemService implements mHandler.sendEmptyMessage(MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED); } } } private void setEstimatedLaunchTime(int userId, String packageName, @CurrentTimeMillisLong long estimatedLaunchTime) { Loading Loading @@ -1995,37 +2040,11 @@ public class UsageStatsService extends SystemService implements case MSG_PACKAGE_REMOVED: onPackageRemoved(msg.arg1, (String) msg.obj); break; case MSG_UID_STATE_CHANGED: { final int uid = msg.arg1; final int procState = msg.arg2; final int newCounter = (procState <= ActivityManager.PROCESS_STATE_TOP) ? 0 : 1; synchronized (mUidToKernelCounter) { final int oldCounter = mUidToKernelCounter.get(uid, 0); if (newCounter != oldCounter) { mUidToKernelCounter.put(uid, newCounter); try { FileUtils.stringToFile(KERNEL_COUNTER_FILE, uid + " " + newCounter); } catch (IOException e) { Slog.w(TAG, "Failed to update counter set: " + e); } } } break; } case MSG_ON_START: synchronized (mLock) { loadGlobalComponentUsageLocked(); } break; case MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK: { final int userId = msg.arg1; Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "usageStatsHandleEstimatedLaunchTimesOnUser(" + userId + ")"); handleEstimatedLaunchTimesOnUserUnlock(userId); Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } break; case MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED: { removeMessages(MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED); Loading