Loading services/usage/java/com/android/server/usage/UsageStatsHandlerThread.java 0 → 100644 +80 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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 com.android.server.usage; import android.os.Handler; import android.os.HandlerExecutor; import android.os.HandlerThread; import android.os.Looper; import android.os.Process; import android.os.Trace; import java.util.concurrent.Executor; /** * Shared singleton default priority thread for usage stats message handling. * * @see com.android.internal.os.BackgroundThread */ public final class UsageStatsHandlerThread extends HandlerThread { private static final long SLOW_DISPATCH_THRESHOLD_MS = 10_000; private static final long SLOW_DELIVERY_THRESHOLD_MS = 30_000; private static UsageStatsHandlerThread sInstance; private static Handler sHandler; private static Executor sHandlerExecutor; private UsageStatsHandlerThread() { super("usagestats.default", Process.THREAD_PRIORITY_DEFAULT); } private static void ensureThreadLocked() { if (sInstance == null) { sInstance = new UsageStatsHandlerThread(); sInstance.start(); final Looper looper = sInstance.getLooper(); looper.setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER); looper.setSlowLogThresholdMs( SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS); sHandler = new Handler(sInstance.getLooper()); sHandlerExecutor = new HandlerExecutor(sHandler); } } /** Returns the UsageStatsHandlerThread singleton */ public static UsageStatsHandlerThread get() { synchronized (UsageStatsHandlerThread.class) { ensureThreadLocked(); return sInstance; } } /** Returns the singleton handler for UsageStatsHandlerThread */ public static Handler getHandler() { synchronized (UsageStatsHandlerThread.class) { ensureThreadLocked(); return sHandler; } } /** Returns the singleton handler executor for UsageStatsHandlerThread */ public static Executor getExecutor() { synchronized (UsageStatsHandlerThread.class) { ensureThreadLocked(); return sHandlerExecutor; } } } services/usage/java/com/android/server/usage/UsageStatsService.java +158 −138 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 @@ -298,7 +332,9 @@ public class UsageStatsService extends SystemService implements mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); mPackageManager = getContext().getPackageManager(); mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); mHandler = new H(BackgroundThread.get().getLooper()); mHandler = new H(UsageStatsHandlerThread.get().getLooper()); mIoHandler = new Handler(IoThread.get().getLooper(), mIoHandlerCallback); mAppStandby = mInjector.getAppStandbyController(getContext()); mResponseStatsTracker = new BroadcastResponseStatsTracker(mAppStandby, getContext()); Loading Loading @@ -424,6 +460,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 @@ -476,11 +515,13 @@ 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 memory and in system DE. mReportedEvents.remove(userId); 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 @@ -599,7 +640,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 @@ -671,16 +712,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 @@ -1241,6 +1284,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 @@ -1271,6 +1317,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 @@ -1279,10 +1332,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 @@ -1492,23 +1542,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 @@ -1546,7 +1600,6 @@ public class UsageStatsService extends SystemService implements } while (events.getNextEvent(event)); return unknownTime; } } @CurrentTimeMillisLong private static long calculateNextLaunchTime( Loading @@ -1566,7 +1619,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 @@ -1577,13 +1629,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 @@ -1622,7 +1669,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 @@ -1989,37 +2035,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/UsageStatsHandlerThread.java 0 → 100644 +80 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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 com.android.server.usage; import android.os.Handler; import android.os.HandlerExecutor; import android.os.HandlerThread; import android.os.Looper; import android.os.Process; import android.os.Trace; import java.util.concurrent.Executor; /** * Shared singleton default priority thread for usage stats message handling. * * @see com.android.internal.os.BackgroundThread */ public final class UsageStatsHandlerThread extends HandlerThread { private static final long SLOW_DISPATCH_THRESHOLD_MS = 10_000; private static final long SLOW_DELIVERY_THRESHOLD_MS = 30_000; private static UsageStatsHandlerThread sInstance; private static Handler sHandler; private static Executor sHandlerExecutor; private UsageStatsHandlerThread() { super("usagestats.default", Process.THREAD_PRIORITY_DEFAULT); } private static void ensureThreadLocked() { if (sInstance == null) { sInstance = new UsageStatsHandlerThread(); sInstance.start(); final Looper looper = sInstance.getLooper(); looper.setTraceTag(Trace.TRACE_TAG_SYSTEM_SERVER); looper.setSlowLogThresholdMs( SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS); sHandler = new Handler(sInstance.getLooper()); sHandlerExecutor = new HandlerExecutor(sHandler); } } /** Returns the UsageStatsHandlerThread singleton */ public static UsageStatsHandlerThread get() { synchronized (UsageStatsHandlerThread.class) { ensureThreadLocked(); return sInstance; } } /** Returns the singleton handler for UsageStatsHandlerThread */ public static Handler getHandler() { synchronized (UsageStatsHandlerThread.class) { ensureThreadLocked(); return sHandler; } } /** Returns the singleton handler executor for UsageStatsHandlerThread */ public static Executor getExecutor() { synchronized (UsageStatsHandlerThread.class) { ensureThreadLocked(); return sHandlerExecutor; } } }
services/usage/java/com/android/server/usage/UsageStatsService.java +158 −138 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 @@ -298,7 +332,9 @@ public class UsageStatsService extends SystemService implements mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); mPackageManager = getContext().getPackageManager(); mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); mHandler = new H(BackgroundThread.get().getLooper()); mHandler = new H(UsageStatsHandlerThread.get().getLooper()); mIoHandler = new Handler(IoThread.get().getLooper(), mIoHandlerCallback); mAppStandby = mInjector.getAppStandbyController(getContext()); mResponseStatsTracker = new BroadcastResponseStatsTracker(mAppStandby, getContext()); Loading Loading @@ -424,6 +460,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 @@ -476,11 +515,13 @@ 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 memory and in system DE. mReportedEvents.remove(userId); 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 @@ -599,7 +640,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 @@ -671,16 +712,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 @@ -1241,6 +1284,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 @@ -1271,6 +1317,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 @@ -1279,10 +1332,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 @@ -1492,23 +1542,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 @@ -1546,7 +1600,6 @@ public class UsageStatsService extends SystemService implements } while (events.getNextEvent(event)); return unknownTime; } } @CurrentTimeMillisLong private static long calculateNextLaunchTime( Loading @@ -1566,7 +1619,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 @@ -1577,13 +1629,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 @@ -1622,7 +1669,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 @@ -1989,37 +2035,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