summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jigar Thakkar <jigarthakkar@google.com> 2024-01-14 01:19:35 +0000
committer Jigar Thakkar <jigarthakkar@google.com> 2024-01-16 19:20:47 +0000
commit62fbc41bced11d4a4e00a554ff4a4c27cb1c70f2 (patch)
tree48d3c5a2ed2f56fc38c04272714a95dde92aea09
parent33921055106c4769bfe4e62b4ff372fe53dcb74a (diff)
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
-rw-r--r--core/java/android/content/pm/multiuser.aconfig7
-rw-r--r--services/core/java/com/android/server/pm/UserManagerService.java25
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();