Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7b61a82 authored by Matías Hernández's avatar Matías Hernández
Browse files

Use a separate thread and Handler for delayed Zen broadcasts

So we don't clog the one used for processing notifications.

Bug: 371776935
Test: atest NotificationManagerServiceTest
Flag: com.android.server.notification.nm_binder_perf_throttle_effects_suppressor_broadcast
Change-Id: Ifcb03c5fd2916451339813000b428dbf6940087a
parent 7e6a7855
Loading
Loading
Loading
Loading
+19 −4
Original line number Diff line number Diff line
@@ -679,6 +679,8 @@ public class NotificationManagerService extends SystemService {
    WorkerHandler mHandler;
    private final HandlerThread mRankingThread = new HandlerThread("ranker",
            Process.THREAD_PRIORITY_BACKGROUND);
    @FlaggedApi(Flags.FLAG_NM_BINDER_PERF_THROTTLE_EFFECTS_SUPPRESSOR_BROADCAST)
    private Handler mBroadcastsHandler;
    private final SparseArray<ArraySet<ComponentName>> mListenersDisablingEffects =
            new SparseArray<>();
@@ -2682,7 +2684,7 @@ public class NotificationManagerService extends SystemService {
    // TODO: All tests should use this init instead of the one-off setters above.
    @VisibleForTesting
    void init(WorkerHandler handler, RankingHandler rankingHandler,
    void init(WorkerHandler handler, RankingHandler rankingHandler, Handler broadcastsHandler,
            IPackageManager packageManager, PackageManager packageManagerClient,
            LightsManager lightsManager, NotificationListeners notificationListeners,
            NotificationAssistants notificationAssistants, ConditionProviders conditionProviders,
@@ -2702,6 +2704,9 @@ public class NotificationManagerService extends SystemService {
            ConnectivityManager connectivityManager,
            PostNotificationTrackerFactory postNotificationTrackerFactory) {
        mHandler = handler;
        if (Flags.nmBinderPerfThrottleEffectsSuppressorBroadcast()) {
            mBroadcastsHandler = broadcastsHandler;
        }
        Resources resources = getContext().getResources();
        mMaxPackageEnqueueRate = Settings.Global.getFloat(getContext().getContentResolver(),
                Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE,
@@ -3045,13 +3050,22 @@ public class NotificationManagerService extends SystemService {
        WorkerHandler handler = new WorkerHandler(Looper.myLooper());
        Handler broadcastsHandler;
        if (Flags.nmBinderPerfThrottleEffectsSuppressorBroadcast()) {
            HandlerThread broadcastsThread = new HandlerThread("NMS Broadcasts");
            broadcastsThread.start();
            broadcastsHandler = new Handler(broadcastsThread.getLooper());
        } else {
            broadcastsHandler = null;
        }
        mShowReviewPermissionsNotification = getContext().getResources().getBoolean(
                R.bool.config_notificationReviewPermissions);
        mDefaultUnsupportedAdjustments = getContext().getResources().getStringArray(
                R.array.config_notificationDefaultUnsupportedAdjustments);
        init(handler, new RankingHandlerWorker(mRankingThread.getLooper()),
        init(handler, new RankingHandlerWorker(mRankingThread.getLooper()), broadcastsHandler,
                AppGlobals.getPackageManager(), getContext().getPackageManager(),
                getLocalService(LightsManager.class),
                new NotificationListeners(getContext(), mNotificationLock, mUserProfiles,
@@ -3297,10 +3311,11 @@ public class NotificationManagerService extends SystemService {
     * so that e.g. rapidly changing some value A -> B -> C will only produce a broadcast for C
     * (instead of every time because the extras are different).
     */
    @FlaggedApi(Flags.FLAG_NM_BINDER_PERF_THROTTLE_EFFECTS_SUPPRESSOR_BROADCAST)
    private void sendZenBroadcastWithDelay(Intent intent) {
        String token = "zen_broadcast:" + intent.getAction();
        mHandler.removeCallbacksAndEqualMessages(token);
        mHandler.postDelayed(() -> sendRegisteredOnlyBroadcast(intent), token,
        mBroadcastsHandler.removeCallbacksAndEqualMessages(token);
        mBroadcastsHandler.postDelayed(() -> sendRegisteredOnlyBroadcast(intent), token,
                ZEN_BROADCAST_DELAY.toMillis());
    }
+15 −8
Original line number Diff line number Diff line
@@ -262,6 +262,7 @@ import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Parcel;
@@ -577,6 +578,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
    NetworkCapabilities mWifiNetworkCapabilities;
    private NotificationManagerService.WorkerHandler mWorkerHandler;
    private Handler mBroadcastsHandler;
    private class TestableToastCallback extends ITransientNotification.Stub {
        @Override
@@ -814,14 +816,16 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        when(mUmInternal.isUserInitialized(anyInt())).thenReturn(true);
        mWorkerHandler = spy(mService.new WorkerHandler(mTestableLooper.getLooper()));
        mService.init(mWorkerHandler, mRankingHandler, mPackageManager, mPackageManagerClient,
                mLightsManager, mListeners, mAssistants, mConditionProviders, mCompanionMgr,
                mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager, mGroupHelper, mAm, mAtm,
                mAppUsageStats, mDevicePolicyManager, mUgm, mUgmInternal,
                mAppOpsManager, mUm, mHistoryManager, mStatsManager,
                mAmi, mToastRateLimiter, mPermissionHelper, mock(UsageStatsManagerInternal.class),
                mTelecomManager, mLogger, mTestFlagResolver, mPermissionManager,
                mPowerManager, mConnectivityManager, mPostNotificationTrackerFactory);
        mBroadcastsHandler = new Handler(mTestableLooper.getLooper());
        mService.init(mWorkerHandler, mRankingHandler, mBroadcastsHandler, mPackageManager,
                mPackageManagerClient, mLightsManager, mListeners, mAssistants, mConditionProviders,
                mCompanionMgr, mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager,
                mGroupHelper, mAm, mAtm, mAppUsageStats, mDevicePolicyManager, mUgm, mUgmInternal,
                mAppOpsManager, mUm, mHistoryManager, mStatsManager, mAmi, mToastRateLimiter,
                mPermissionHelper, mock(UsageStatsManagerInternal.class), mTelecomManager, mLogger,
                mTestFlagResolver, mPermissionManager, mPowerManager, mConnectivityManager,
                mPostNotificationTrackerFactory);
        mService.setAttentionHelper(mAttentionHelper);
        mService.setLockPatternUtils(mock(LockPatternUtils.class));
@@ -998,6 +1002,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
            // problematic interactions with mocks when they're no longer working as expected).
            mWorkerHandler.removeCallbacksAndMessages(null);
        }
        if (mBroadcastsHandler != null) {
            mBroadcastsHandler.removeCallbacksAndMessages(null);
        }
        if (mTestableLooper != null) {
            // Must remove static reference to this test object to prevent leak (b/261039202)
+2 −2
Original line number Diff line number Diff line
@@ -48,13 +48,13 @@ import android.content.Context;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.permission.PermissionManager;
import android.telecom.TelecomManager;
import android.telephony.TelephonyManager;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
@@ -152,7 +152,7 @@ public class RoleObserverTest extends UiServiceTestCase {

        try {
            mService.init(mService.new WorkerHandler(mTestableLooper.getLooper()),
                    mock(RankingHandler.class),
                    mock(RankingHandler.class), new Handler(mTestableLooper.getLooper()),
                    mock(IPackageManager.class), mock(PackageManager.class),
                    mock(LightsManager.class),
                    mock(NotificationListeners.class), mock(NotificationAssistants.class),