From 62fbc41bced11d4a4e00a554ff4a4c27cb1c70f2 Mon Sep 17 00:00:00 2001 From: Jigar Thakkar Date: Sun, 14 Jan 2024 01:19:35 +0000 Subject: Move quiet mode operations to a separate thread The setQuietModeEnabled method is often called asynchronously on a background thread. This has been a reason for noticeable delays caused when the system server background thread is busy. With this change, we are moving the operation to a separte thread using a ThreadPoolExecutor of size 1. Test: Tested locally on device by adding logs and capturing pertto traces Bug: 303201022 Change-Id: I71faf0d11115e5fa4828632c28778d3add9e62f2 --- core/java/android/content/pm/multiuser.aconfig | 7 ++++++ .../com/android/server/pm/UserManagerService.java | 25 +++++++++++++++++----- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig index c7797c719e2c..7c5d3054c945 100644 --- a/core/java/android/content/pm/multiuser.aconfig +++ b/core/java/android/content/pm/multiuser.aconfig @@ -70,4 +70,11 @@ flag { namespace: "profile_experiences" description: "Add support for Private Space in resolver sheet" bug: "307515485" +} + +flag { + name: "move_quiet_mode_operations_to_separate_thread" + namespace: "profile_experiences" + description: "Move the quiet mode operations, happening on a background thread today, to a separate thread." + bug: "320483504" } \ No newline at end of file diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 315c36f32479..9859e1aaa56f 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -180,6 +180,8 @@ import java.util.List; import java.util.Objects; import java.util.Set; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; @@ -333,6 +335,8 @@ public class UserManagerService extends IUserManager.Stub { private final Handler mHandler; + private final ThreadPoolExecutor mInternalExecutor; + private final File mUsersDir; private final File mUserListFile; @@ -722,11 +726,20 @@ public class UserManagerService extends IUserManager.Stub { @VisibleForTesting void setQuietModeEnabledAsync(@UserIdInt int userId, boolean enableQuietMode, IntentSender target, @Nullable String callingPackage) { - // Call setQuietModeEnabled on bg thread to avoid ANR - BackgroundThread.getHandler().post( - () -> setQuietModeEnabled(userId, enableQuietMode, target, - callingPackage) - ); + if (android.multiuser.Flags.moveQuietModeOperationsToSeparateThread()) { + // Call setQuietModeEnabled on a separate thread. Calling this operation on the main + // thread can cause ANRs, posting on a BackgroundThread can result in delays + Slog.d(LOG_TAG, "Calling setQuietModeEnabled for user " + userId + + " on a separate thread"); + mInternalExecutor.execute(() -> setQuietModeEnabled(userId, enableQuietMode, target, + callingPackage)); + } else { + // Call setQuietModeEnabled on bg thread to avoid ANR + BackgroundThread.getHandler().post( + () -> setQuietModeEnabled(userId, enableQuietMode, target, + callingPackage) + ); + } } /** @@ -952,6 +965,8 @@ public class UserManagerService extends IUserManager.Stub { mPackagesLock = packagesLock; mUsers = users != null ? users : new SparseArray<>(); mHandler = new MainHandler(); + mInternalExecutor = new ThreadPoolExecutor(/* corePoolSize */ 0, /* maximumPoolSize */ 1, + /* keepAliveTime */ 1, TimeUnit.SECONDS, new LinkedBlockingQueue<>()); mUserVisibilityMediator = new UserVisibilityMediator(mHandler); mUserDataPreparer = userDataPreparer; mUserTypes = UserTypeFactory.getUserTypes(); -- cgit v1.2.3-59-g8ed1b