Loading services/usage/java/com/android/server/usage/UsageStatsHandlerThread.javadeleted 100644 → 0 +0 −80 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 +138 −158 Original line number Diff line number Diff line Loading @@ -106,7 +106,6 @@ 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 @@ -202,8 +201,7 @@ public class UsageStatsService extends SystemService implements static final int MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED = 9; private final Object mLock = new Object(); private Handler mHandler; private Handler mIoHandler; Handler mHandler; AppOpsManager mAppOps; UserManager mUserManager; PackageManager mPackageManager; Loading Loading @@ -235,7 +233,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("mLaunchTimeAlarmQueues") // Don't hold the main lock @GuardedBy("mLock") 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 @@ -281,38 +279,6 @@ 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 @@ -332,9 +298,7 @@ public class UsageStatsService extends SystemService implements mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); mPackageManager = getContext().getPackageManager(); mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); mHandler = new H(UsageStatsHandlerThread.get().getLooper()); mIoHandler = new Handler(IoThread.get().getLooper(), mIoHandlerCallback); mHandler = new H(BackgroundThread.get().getLooper()); mAppStandby = mInjector.getAppStandbyController(getContext()); mResponseStatsTracker = new BroadcastResponseStatsTracker(mAppStandby, getContext()); Loading Loading @@ -460,9 +424,6 @@ 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 @@ -518,12 +479,10 @@ public class UsageStatsService extends SystemService implements } reportEvent(unlockEvent, userId); mIoHandler.obtainMessage(MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK, userId, 0).sendToTarget(); mHandler.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 @@ -642,7 +601,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) { mIoHandler.obtainMessage(MSG_UID_STATE_CHANGED, uid, procState).sendToTarget(); mHandler.obtainMessage(MSG_UID_STATE_CHANGED, uid, procState).sendToTarget(); } @Override Loading Loading @@ -714,18 +673,16 @@ public class UsageStatsService extends SystemService implements callingPid, callingUid) == PackageManager.PERMISSION_GRANTED); } private static void deleteRecursively(final File path) { if (path.isDirectory()) { final File[] files = path.listFiles(); private static void deleteRecursively(File f) { File[] files = f.listFiles(); if (files != null) { for (File subFile : files) { deleteRecursively(subFile); } } } if (path.exists() && !path.delete()) { Slog.e(TAG, "Failed to delete " + path); if (f.exists() && !f.delete()) { Slog.e(TAG, "Failed to delete " + f); } } Loading Loading @@ -1287,9 +1244,6 @@ 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 @@ -1320,13 +1274,6 @@ 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 @@ -1335,7 +1282,10 @@ 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 @@ -1545,27 +1495,23 @@ public class UsageStatsService extends SystemService implements estimatedLaunchTime = calculateEstimatedPackageLaunchTime(userId, packageName); mAppStandby.setEstimatedLaunchTime(packageName, userId, estimatedLaunchTime); getOrCreateLaunchTimeAlarmQueue(userId).addAlarm(packageName, SystemClock.elapsedRealtime() + (estimatedLaunchTime - now)); } return estimatedLaunchTime; } private LaunchTimeAlarmQueue getOrCreateLaunchTimeAlarmQueue(int userId) { synchronized (mLaunchTimeAlarmQueues) { synchronized (mLock) { LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); if (alarmQueue == null) { alarmQueue = new LaunchTimeAlarmQueue( userId, getContext(), BackgroundThread.get().getLooper()); mLaunchTimeAlarmQueues.put(userId, alarmQueue); } return alarmQueue; alarmQueue.addAlarm(packageName, SystemClock.elapsedRealtime() + (estimatedLaunchTime - now)); } } 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 @@ -1603,6 +1549,7 @@ public class UsageStatsService extends SystemService implements } while (events.getNextEvent(event)); return unknownTime; } } @CurrentTimeMillisLong private static long calculateNextLaunchTime( Loading @@ -1622,6 +1569,7 @@ 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 @@ -1632,8 +1580,13 @@ 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 @@ -1672,6 +1625,7 @@ 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 @@ -2041,11 +1995,37 @@ 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.javadeleted 100644 → 0 +0 −80 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 +138 −158 Original line number Diff line number Diff line Loading @@ -106,7 +106,6 @@ 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 @@ -202,8 +201,7 @@ public class UsageStatsService extends SystemService implements static final int MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED = 9; private final Object mLock = new Object(); private Handler mHandler; private Handler mIoHandler; Handler mHandler; AppOpsManager mAppOps; UserManager mUserManager; PackageManager mPackageManager; Loading Loading @@ -235,7 +233,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("mLaunchTimeAlarmQueues") // Don't hold the main lock @GuardedBy("mLock") 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 @@ -281,38 +279,6 @@ 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 @@ -332,9 +298,7 @@ public class UsageStatsService extends SystemService implements mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE); mPackageManager = getContext().getPackageManager(); mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); mHandler = new H(UsageStatsHandlerThread.get().getLooper()); mIoHandler = new Handler(IoThread.get().getLooper(), mIoHandlerCallback); mHandler = new H(BackgroundThread.get().getLooper()); mAppStandby = mInjector.getAppStandbyController(getContext()); mResponseStatsTracker = new BroadcastResponseStatsTracker(mAppStandby, getContext()); Loading Loading @@ -460,9 +424,6 @@ 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 @@ -518,12 +479,10 @@ public class UsageStatsService extends SystemService implements } reportEvent(unlockEvent, userId); mIoHandler.obtainMessage(MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK, userId, 0).sendToTarget(); mHandler.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 @@ -642,7 +601,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) { mIoHandler.obtainMessage(MSG_UID_STATE_CHANGED, uid, procState).sendToTarget(); mHandler.obtainMessage(MSG_UID_STATE_CHANGED, uid, procState).sendToTarget(); } @Override Loading Loading @@ -714,18 +673,16 @@ public class UsageStatsService extends SystemService implements callingPid, callingUid) == PackageManager.PERMISSION_GRANTED); } private static void deleteRecursively(final File path) { if (path.isDirectory()) { final File[] files = path.listFiles(); private static void deleteRecursively(File f) { File[] files = f.listFiles(); if (files != null) { for (File subFile : files) { deleteRecursively(subFile); } } } if (path.exists() && !path.delete()) { Slog.e(TAG, "Failed to delete " + path); if (f.exists() && !f.delete()) { Slog.e(TAG, "Failed to delete " + f); } } Loading Loading @@ -1287,9 +1244,6 @@ 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 @@ -1320,13 +1274,6 @@ 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 @@ -1335,7 +1282,10 @@ 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 @@ -1545,27 +1495,23 @@ public class UsageStatsService extends SystemService implements estimatedLaunchTime = calculateEstimatedPackageLaunchTime(userId, packageName); mAppStandby.setEstimatedLaunchTime(packageName, userId, estimatedLaunchTime); getOrCreateLaunchTimeAlarmQueue(userId).addAlarm(packageName, SystemClock.elapsedRealtime() + (estimatedLaunchTime - now)); } return estimatedLaunchTime; } private LaunchTimeAlarmQueue getOrCreateLaunchTimeAlarmQueue(int userId) { synchronized (mLaunchTimeAlarmQueues) { synchronized (mLock) { LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); if (alarmQueue == null) { alarmQueue = new LaunchTimeAlarmQueue( userId, getContext(), BackgroundThread.get().getLooper()); mLaunchTimeAlarmQueues.put(userId, alarmQueue); } return alarmQueue; alarmQueue.addAlarm(packageName, SystemClock.elapsedRealtime() + (estimatedLaunchTime - now)); } } 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 @@ -1603,6 +1549,7 @@ public class UsageStatsService extends SystemService implements } while (events.getNextEvent(event)); return unknownTime; } } @CurrentTimeMillisLong private static long calculateNextLaunchTime( Loading @@ -1622,6 +1569,7 @@ 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 @@ -1632,8 +1580,13 @@ 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 @@ -1672,6 +1625,7 @@ 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 @@ -2041,11 +1995,37 @@ 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