From 8f35d505babb6b60ec07aa84b1caa01524f808b2 Mon Sep 17 00:00:00 2001 From: Jeongsik Mun Date: Tue, 5 Jan 2021 16:51:28 +0900 Subject: [PATCH] Avoid running RegisteredServicesCache tasks on main thread Since RegisteredServicesCache tasks from SyncManager and AccountManager run on the main thread of SystemServer, It could cause draining the main thread and end up with ANR when receiving a lot of broadcasts or notifying changes through a listener. This CL changes a few things to avoid running it on main thread. 1. RegisteredServicesCache uses BackgroundThread by default for receiving broadcasts and a listener, instead of main thread. 2. AccountManager uses its own handler for a listener. Bug: 171907687 Test: atest SyncManagerTest CtsSyncManagerTest AccountManagerServiceTest Change-Id: I838c15b797b46fd58bb3c6ce9ee444a4737775d8 --- .../android/content/pm/RegisteredServicesCache.java | 11 +++++++---- .../server/accounts/AccountManagerService.java | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java index 7ecb11248d235..7696cbe0b6316 100644 --- a/core/java/android/content/pm/RegisteredServicesCache.java +++ b/core/java/android/content/pm/RegisteredServicesCache.java @@ -42,6 +42,7 @@ import android.util.Xml; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.os.BackgroundThread; import com.android.internal.util.ArrayUtils; import libcore.io.IoUtils; @@ -161,18 +162,20 @@ public abstract class RegisteredServicesCache { intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED); intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); intentFilter.addDataScheme("package"); - mContext.registerReceiverAsUser(mPackageReceiver, UserHandle.ALL, intentFilter, null, null); + Handler handler = BackgroundThread.getHandler(); + mContext.registerReceiverAsUser( + mPackageReceiver, UserHandle.ALL, intentFilter, null, handler); // Register for events related to sdcard installation. IntentFilter sdFilter = new IntentFilter(); sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE); sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); - mContext.registerReceiver(mExternalReceiver, sdFilter); + mContext.registerReceiver(mExternalReceiver, sdFilter, null, handler); // Register for user-related events IntentFilter userFilter = new IntentFilter(); sdFilter.addAction(Intent.ACTION_USER_REMOVED); - mContext.registerReceiver(mUserRemovedReceiver, userFilter); + mContext.registerReceiver(mUserRemovedReceiver, userFilter, null, handler); } private void handlePackageEvent(Intent intent, int userId) { @@ -265,7 +268,7 @@ public abstract class RegisteredServicesCache { public void setListener(RegisteredServicesCacheListener listener, Handler handler) { if (handler == null) { - handler = new Handler(mContext.getMainLooper()); + handler = BackgroundThread.getHandler(); } synchronized (this) { mHandler = handler; diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index 9930eac5cbd52..73755231c3bef 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -279,7 +279,7 @@ public class AccountManagerService mAppOpsManager = mContext.getSystemService(AppOpsManager.class); mHandler = new MessageHandler(injector.getMessageHandlerLooper()); mAuthenticatorCache = mInjector.getAccountAuthenticatorCache(); - mAuthenticatorCache.setListener(this, null /* Handler */); + mAuthenticatorCache.setListener(this, mHandler); sThis.set(this);