Loading core/java/android/app/usage/flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -13,3 +13,11 @@ flag { description: "Feature flag for the new REPORT_USAGE_STATS permission." bug: "296056771" } flag { name: "use_dedicated_handler_thread" namespace: "backstage_power" description: "Flag to use a dedicated thread for usage event process" is_fixed_read_only: true bug: "299336442" } services/usage/java/com/android/server/usage/UsageStatsHandlerThread.java 0 → 100644 +64 −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.Looper; import android.os.Trace; import com.android.internal.annotations.GuardedBy; import com.android.server.ServiceThread; /** * Shared singleton default priority thread for usage stats message handling. */ public class UsageStatsHandlerThread extends ServiceThread { private static final long SLOW_DISPATCH_THRESHOLD_MS = 10_000; private static final long SLOW_DELIVERY_THRESHOLD_MS = 30_000; private static final Object sLock = new Object(); @GuardedBy("sLock") private static UsageStatsHandlerThread sInstance; private UsageStatsHandlerThread() { super("android.usagestats", android.os.Process.THREAD_PRIORITY_DEFAULT, /* allowIo= */ true); } @GuardedBy("sLock") private static void ensureThreadLocked() { if (sInstance != null) { return; } 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); } /** * Obtain a singleton instance of the UsageStatsHandlerThread. */ public static UsageStatsHandlerThread get() { synchronized (sLock) { ensureThreadLocked(); return sInstance; } } } services/usage/java/com/android/server/usage/UsageStatsService.java +20 −7 Original line number Diff line number Diff line Loading @@ -202,6 +202,7 @@ public class UsageStatsService extends SystemService implements static final int MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK = 8; static final int MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED = 9; static final int MSG_UID_REMOVED = 10; static final int MSG_USER_STARTED = 11; private final Object mLock = new Object(); private Handler mHandler; Loading Loading @@ -334,7 +335,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(BackgroundThread.get().getLooper()); mHandler = getUsageEventProcessingHandler(); mIoHandler = new Handler(IoThread.get().getLooper(), mIoHandlerCallback); mAppStandby = mInjector.getAppStandbyController(getContext()); Loading Loading @@ -380,10 +381,12 @@ public class UsageStatsService extends SystemService implements IntentFilter filter = new IntentFilter(Intent.ACTION_USER_REMOVED); filter.addAction(Intent.ACTION_USER_STARTED); getContext().registerReceiverAsUser(new UserActionsReceiver(), UserHandle.ALL, filter, null, /* Handler scheduler */ null); getContext().registerReceiverAsUser(new UserActionsReceiver(), UserHandle.ALL, filter, null, /* scheduler= */ Flags.useDedicatedHandlerThread() ? mHandler : null); getContext().registerReceiverAsUser(new UidRemovedReceiver(), UserHandle.ALL, new IntentFilter(ACTION_UID_REMOVED), null, /* Handler scheduler */ null); new IntentFilter(ACTION_UID_REMOVED), null, /* scheduler= */ Flags.useDedicatedHandlerThread() ? mHandler : null); mRealTimeSnapshot = SystemClock.elapsedRealtime(); mSystemTimeSnapshot = System.currentTimeMillis(); Loading Loading @@ -471,6 +474,14 @@ public class UsageStatsService extends SystemService implements } } private Handler getUsageEventProcessingHandler() { if (Flags.useDedicatedHandlerThread()) { return new H(UsageStatsHandlerThread.get().getLooper()); } else { return new H(BackgroundThread.get().getLooper()); } } private void onUserUnlocked(int userId) { // fetch the installed packages outside the lock so it doesn't block package manager. final HashMap<String, Long> installedPackages = getInstalledPackages(userId); Loading Loading @@ -618,7 +629,7 @@ public class UsageStatsService extends SystemService implements } } else if (Intent.ACTION_USER_STARTED.equals(action)) { if (userId >= 0) { mAppStandby.postCheckIdleStates(userId); mHandler.obtainMessage(MSG_USER_STARTED, userId, 0).sendToTarget(); } } } Loading Loading @@ -1554,8 +1565,7 @@ public class UsageStatsService extends SystemService implements synchronized (mLaunchTimeAlarmQueues) { LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); if (alarmQueue == null) { alarmQueue = new LaunchTimeAlarmQueue( userId, getContext(), BackgroundThread.get().getLooper()); alarmQueue = new LaunchTimeAlarmQueue(userId, getContext(), mHandler.getLooper()); mLaunchTimeAlarmQueues.put(userId, alarmQueue); } Loading Loading @@ -2040,6 +2050,9 @@ public class UsageStatsService extends SystemService implements case MSG_UID_REMOVED: mResponseStatsTracker.onUidRemoved(msg.arg1); break; case MSG_USER_STARTED: mAppStandby.postCheckIdleStates(msg.arg1); break; case MSG_PACKAGE_REMOVED: onPackageRemoved(msg.arg1, (String) msg.obj); break; Loading Loading
core/java/android/app/usage/flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -13,3 +13,11 @@ flag { description: "Feature flag for the new REPORT_USAGE_STATS permission." bug: "296056771" } flag { name: "use_dedicated_handler_thread" namespace: "backstage_power" description: "Flag to use a dedicated thread for usage event process" is_fixed_read_only: true bug: "299336442" }
services/usage/java/com/android/server/usage/UsageStatsHandlerThread.java 0 → 100644 +64 −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.Looper; import android.os.Trace; import com.android.internal.annotations.GuardedBy; import com.android.server.ServiceThread; /** * Shared singleton default priority thread for usage stats message handling. */ public class UsageStatsHandlerThread extends ServiceThread { private static final long SLOW_DISPATCH_THRESHOLD_MS = 10_000; private static final long SLOW_DELIVERY_THRESHOLD_MS = 30_000; private static final Object sLock = new Object(); @GuardedBy("sLock") private static UsageStatsHandlerThread sInstance; private UsageStatsHandlerThread() { super("android.usagestats", android.os.Process.THREAD_PRIORITY_DEFAULT, /* allowIo= */ true); } @GuardedBy("sLock") private static void ensureThreadLocked() { if (sInstance != null) { return; } 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); } /** * Obtain a singleton instance of the UsageStatsHandlerThread. */ public static UsageStatsHandlerThread get() { synchronized (sLock) { ensureThreadLocked(); return sInstance; } } }
services/usage/java/com/android/server/usage/UsageStatsService.java +20 −7 Original line number Diff line number Diff line Loading @@ -202,6 +202,7 @@ public class UsageStatsService extends SystemService implements static final int MSG_HANDLE_LAUNCH_TIME_ON_USER_UNLOCK = 8; static final int MSG_NOTIFY_ESTIMATED_LAUNCH_TIMES_CHANGED = 9; static final int MSG_UID_REMOVED = 10; static final int MSG_USER_STARTED = 11; private final Object mLock = new Object(); private Handler mHandler; Loading Loading @@ -334,7 +335,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(BackgroundThread.get().getLooper()); mHandler = getUsageEventProcessingHandler(); mIoHandler = new Handler(IoThread.get().getLooper(), mIoHandlerCallback); mAppStandby = mInjector.getAppStandbyController(getContext()); Loading Loading @@ -380,10 +381,12 @@ public class UsageStatsService extends SystemService implements IntentFilter filter = new IntentFilter(Intent.ACTION_USER_REMOVED); filter.addAction(Intent.ACTION_USER_STARTED); getContext().registerReceiverAsUser(new UserActionsReceiver(), UserHandle.ALL, filter, null, /* Handler scheduler */ null); getContext().registerReceiverAsUser(new UserActionsReceiver(), UserHandle.ALL, filter, null, /* scheduler= */ Flags.useDedicatedHandlerThread() ? mHandler : null); getContext().registerReceiverAsUser(new UidRemovedReceiver(), UserHandle.ALL, new IntentFilter(ACTION_UID_REMOVED), null, /* Handler scheduler */ null); new IntentFilter(ACTION_UID_REMOVED), null, /* scheduler= */ Flags.useDedicatedHandlerThread() ? mHandler : null); mRealTimeSnapshot = SystemClock.elapsedRealtime(); mSystemTimeSnapshot = System.currentTimeMillis(); Loading Loading @@ -471,6 +474,14 @@ public class UsageStatsService extends SystemService implements } } private Handler getUsageEventProcessingHandler() { if (Flags.useDedicatedHandlerThread()) { return new H(UsageStatsHandlerThread.get().getLooper()); } else { return new H(BackgroundThread.get().getLooper()); } } private void onUserUnlocked(int userId) { // fetch the installed packages outside the lock so it doesn't block package manager. final HashMap<String, Long> installedPackages = getInstalledPackages(userId); Loading Loading @@ -618,7 +629,7 @@ public class UsageStatsService extends SystemService implements } } else if (Intent.ACTION_USER_STARTED.equals(action)) { if (userId >= 0) { mAppStandby.postCheckIdleStates(userId); mHandler.obtainMessage(MSG_USER_STARTED, userId, 0).sendToTarget(); } } } Loading Loading @@ -1554,8 +1565,7 @@ public class UsageStatsService extends SystemService implements synchronized (mLaunchTimeAlarmQueues) { LaunchTimeAlarmQueue alarmQueue = mLaunchTimeAlarmQueues.get(userId); if (alarmQueue == null) { alarmQueue = new LaunchTimeAlarmQueue( userId, getContext(), BackgroundThread.get().getLooper()); alarmQueue = new LaunchTimeAlarmQueue(userId, getContext(), mHandler.getLooper()); mLaunchTimeAlarmQueues.put(userId, alarmQueue); } Loading Loading @@ -2040,6 +2050,9 @@ public class UsageStatsService extends SystemService implements case MSG_UID_REMOVED: mResponseStatsTracker.onUidRemoved(msg.arg1); break; case MSG_USER_STARTED: mAppStandby.postCheckIdleStates(msg.arg1); break; case MSG_PACKAGE_REMOVED: onPackageRemoved(msg.arg1, (String) msg.obj); break; Loading