Merge "Modify usagestats event processing thread" into main
diff --git a/core/java/android/app/usage/flags.aconfig b/core/java/android/app/usage/flags.aconfig
index f401a76..4f1c65b 100644
--- a/core/java/android/app/usage/flags.aconfig
+++ b/core/java/android/app/usage/flags.aconfig
@@ -13,3 +13,11 @@
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"
+}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsHandlerThread.java b/services/usage/java/com/android/server/usage/UsageStatsHandlerThread.java
new file mode 100644
index 0000000..31418d6
--- /dev/null
+++ b/services/usage/java/com/android/server/usage/UsageStatsHandlerThread.java
@@ -0,0 +1,64 @@
+/*
+ * 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;
+ }
+ }
+}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 55b5d11..e413663 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -202,6 +202,7 @@
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;
@@ -334,7 +335,7 @@
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());
@@ -380,10 +381,12 @@
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();
@@ -471,6 +474,14 @@
}
}
+ 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);
@@ -618,7 +629,7 @@
}
} else if (Intent.ACTION_USER_STARTED.equals(action)) {
if (userId >= 0) {
- mAppStandby.postCheckIdleStates(userId);
+ mHandler.obtainMessage(MSG_USER_STARTED, userId, 0).sendToTarget();
}
}
}
@@ -1554,8 +1565,7 @@
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);
}
@@ -2040,6 +2050,9 @@
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;