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

Commit f079ed18 authored by Iavor-Valentin Iftime's avatar Iavor-Valentin Iftime Committed by Android (Google) Code Review
Browse files

Merge "Extract alert handling into NotificationAttentionHelper" into main

parents ac50f74f 8a1dacc0
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -81,6 +81,11 @@ public class SystemUiSystemPropertiesFlags {
        public static final Flag PROPAGATE_CHANNEL_UPDATES_TO_CONVERSATIONS = releasedFlag(
                "persist.sysui.notification.propagate_channel_updates_to_conversations");

        // TODO: b/291907312 - remove feature flags
        /** Gating the NMS->NotificationAttentionHelper buzzBeepBlink refactor */
        public static final Flag ENABLE_ATTENTION_HELPER_REFACTOR = devFlag(
                "persist.debug.sysui.notification.enable_attention_helper_refactor");

        /** b/301242692: Visit extra URIs used in notifications to prevent security issues. */
        public static final Flag VISIT_RISKY_URIS = devFlag(
                "persist.sysui.notification.visit_risky_uris");
+951 −0

File added.

Preview size limit exceeded, changes collapsed.

+28 −0
Original line number Diff line number Diff line
/*
 * 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.notification;

import android.annotation.Nullable;

/**
 * Interface that allows components (helpers) to access NotificationRecords
 * without an explicit reference to NotificationManagerService.
 */
interface NotificationManagerPrivate {
    @Nullable
    NotificationRecord getNotificationByKey(String key);
}
+126 −53
Original line number Diff line number Diff line
@@ -287,6 +287,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.compat.IPlatformCompat;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags;
import com.android.internal.logging.InstanceId;
import com.android.internal.logging.InstanceIdSequence;
import com.android.internal.logging.MetricsLogger;
@@ -315,6 +316,7 @@ import com.android.server.SystemService;
import com.android.server.job.JobSchedulerInternal;
import com.android.server.lights.LightsManager;
import com.android.server.lights.LogicalLight;
import com.android.server.notification.Flags;
import com.android.server.notification.ManagedServices.ManagedServiceInfo;
import com.android.server.notification.ManagedServices.UserProfiles;
import com.android.server.notification.toast.CustomToastRecord;
@@ -684,6 +686,7 @@ public class NotificationManagerService extends SystemService {
    private boolean mIsAutomotive;
    private boolean mNotificationEffectsEnabledForAutomotive;
    private DeviceConfig.OnPropertiesChangedListener mDeviceConfigChangedListener;
    protected NotificationAttentionHelper mAttentionHelper;
    private int mWarnRemoteViewsSizeBytes;
    private int mStripRemoteViewsSizeBytes;
@@ -1167,6 +1170,9 @@ public class NotificationManagerService extends SystemService {
        @Override
        public void onSetDisabled(int status) {
            synchronized (mNotificationLock) {
                if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
                    mAttentionHelper.updateDisableNotificationEffectsLocked(status);
                } else {
                    mDisableNotificationEffects =
                            (status & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) != 0;
                    if (disableNotificationEffects(null) != null) {
@@ -1176,6 +1182,7 @@ public class NotificationManagerService extends SystemService {
                    }
                }
            }
        }
        @Override
        public void onClearAll(int callingUid, int callingPid, int userId) {
@@ -1309,11 +1316,15 @@ public class NotificationManagerService extends SystemService {
        public void clearEffects() {
            synchronized (mNotificationLock) {
                if (DBG) Slog.d(TAG, "clearEffects");
                if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
                    mAttentionHelper.clearAttentionEffects();
                } else {
                    clearSoundLocked();
                    clearVibrateLocked();
                    clearLightsLocked();
                }
            }
        }
        @Override
        public void onNotificationError(int callingUid, int callingPid, String pkg, String tag,
@@ -1534,8 +1545,13 @@ public class NotificationManagerService extends SystemService {
                        int changedFlags = data.getFlags() ^ flags;
                        if ((changedFlags & FLAG_SUPPRESS_NOTIFICATION) != 0) {
                            // Suppress notification flag changed, clear any effects
                            if (mFlagResolver.isEnabled(
                                    NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
                                mAttentionHelper.clearEffectsLocked(key);
                            } else {
                                clearEffectsLocked(key);
                            }
                        }
                        data.setFlags(flags);
                        // Shouldn't alert again just because of a flag change.
                        r.getNotification().flags |= FLAG_ONLY_ALERT_ONCE;
@@ -1626,6 +1642,12 @@ public class NotificationManagerService extends SystemService {
    };
    NotificationManagerPrivate mNotificationManagerPrivate = key -> {
        synchronized (mNotificationLock) {
            return mNotificationsByKey.get(key);
        }
    };
    @VisibleForTesting
    void logSmartSuggestionsVisible(NotificationRecord r, int notificationLocation) {
        // If the newly visible notification has smart suggestions
@@ -1873,6 +1895,7 @@ public class NotificationManagerService extends SystemService {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (!mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
                if (action.equals(Intent.ACTION_SCREEN_ON)) {
                    // Keep track of screen on/off state, but do not turn off the notification light
                    // until user passes through the lock screen or views the notification.
@@ -1885,7 +1908,15 @@ public class NotificationManagerService extends SystemService {
                    mInCallStateOffHook = TelephonyManager.EXTRA_STATE_OFFHOOK
                        .equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE));
                    updateNotificationPulse();
            } else if (action.equals(Intent.ACTION_USER_STOPPED)) {
                } else if (action.equals(Intent.ACTION_USER_PRESENT)) {
                    // turn off LED when user passes through lock screen
                    if (mNotificationLight != null) {
                        mNotificationLight.turnOff();
                    }
                }
            }
            if (action.equals(Intent.ACTION_USER_STOPPED)) {
                int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
                if (userHandle >= 0) {
                    cancelAllNotificationsInt(MY_UID, MY_PID, null, null, 0, 0, userHandle,
@@ -1898,11 +1929,6 @@ public class NotificationManagerService extends SystemService {
                            REASON_PROFILE_TURNED_OFF);
                    mSnoozeHelper.clearData(userHandle);
                }
            } else if (action.equals(Intent.ACTION_USER_PRESENT)) {
                // turn off LED when user passes through lock screen
                if (mNotificationLight != null) {
                    mNotificationLight.turnOff();
                }
            } else if (action.equals(Intent.ACTION_USER_SWITCHED)) {
                final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, USER_NULL);
                mUserProfiles.updateCache(context);
@@ -1976,8 +2002,10 @@ public class NotificationManagerService extends SystemService {
            ContentResolver resolver = getContext().getContentResolver();
            resolver.registerContentObserver(NOTIFICATION_BADGING_URI,
                    false, this, UserHandle.USER_ALL);
            if (!mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
                resolver.registerContentObserver(NOTIFICATION_LIGHT_PULSE_URI,
                    false, this, UserHandle.USER_ALL);
            }
            resolver.registerContentObserver(NOTIFICATION_RATE_LIMIT_URI,
                    false, this, UserHandle.USER_ALL);
            resolver.registerContentObserver(NOTIFICATION_BUBBLES_URI,
@@ -2000,6 +2028,7 @@ public class NotificationManagerService extends SystemService {
        public void update(Uri uri) {
            ContentResolver resolver = getContext().getContentResolver();
            if (!mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
                if (uri == null || NOTIFICATION_LIGHT_PULSE_URI.equals(uri)) {
                    boolean pulseEnabled = Settings.System.getIntForUser(resolver,
                        Settings.System.NOTIFICATION_LIGHT_PULSE, 0, UserHandle.USER_CURRENT)
@@ -2009,6 +2038,7 @@ public class NotificationManagerService extends SystemService {
                        updateNotificationPulse();
                    }
                }
            }
            if (uri == null || NOTIFICATION_RATE_LIMIT_URI.equals(uri)) {
                mMaxPackageEnqueueRate = Settings.Global.getFloat(resolver,
                            Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE, mMaxPackageEnqueueRate);
@@ -2491,14 +2521,22 @@ public class NotificationManagerService extends SystemService {
        mToastRateLimiter = toastRateLimiter;
        if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
            mAttentionHelper = new NotificationAttentionHelper(getContext(), lightsManager,
                mAccessibilityManager, mPackageManagerClient, usageStats,
                mNotificationManagerPrivate, mZenModeHelper, flagResolver);
        }
        // register for various Intents.
        // If this is called within a test, make sure to unregister the intent receivers by
        // calling onDestroy()
        IntentFilter filter = new IntentFilter();
        if (!mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
            filter.addAction(Intent.ACTION_SCREEN_ON);
            filter.addAction(Intent.ACTION_SCREEN_OFF);
            filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
            filter.addAction(Intent.ACTION_USER_PRESENT);
        }
        filter.addAction(Intent.ACTION_USER_STOPPED);
        filter.addAction(Intent.ACTION_USER_SWITCHED);
        filter.addAction(Intent.ACTION_USER_ADDED);
@@ -2818,6 +2856,9 @@ public class NotificationManagerService extends SystemService {
            }
            registerNotificationPreferencesPullers();
            new LockPatternUtils(getContext()).registerStrongAuthTracker(mStrongAuthTracker);
            if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
                mAttentionHelper.onSystemReady();
            }
        } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
            // This observer will force an update when observe is called, causing us to
            // bind to listener services.
@@ -6375,6 +6416,9 @@ public class NotificationManagerService extends SystemService {
                    pw.println("  mMaxPackageEnqueueRate=" + mMaxPackageEnqueueRate);
                    pw.println("  hideSilentStatusBar="
                            + mPreferencesHelper.shouldHideSilentStatusIcons());
                    if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
                        mAttentionHelper.dump(pw, "    ", filter);
                    }
                }
                pw.println("  mArchive=" + mArchive.toString());
                mArchive.dumpImpl(pw, filter);
@@ -7632,7 +7676,11 @@ public class NotificationManagerService extends SystemService {
            boolean wasPosted = removeFromNotificationListsLocked(r);
            cancelNotificationLocked(r, false, REASON_SNOOZED, wasPosted, null,
                    SystemClock.elapsedRealtime());
            if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
                mAttentionHelper.updateLightsLocked();
            } else {
                updateLightsLocked();
            }
            if (isSnoozable(r)) {
                if (mSnoozeCriterionId != null) {
                    mAssistants.notifyAssistantSnoozedLocked(r, mSnoozeCriterionId);
@@ -7761,7 +7809,11 @@ public class NotificationManagerService extends SystemService {
                    cancelGroupChildrenLocked(r, mCallingUid, mCallingPid, listenerName,
                            mSendDelete, childrenFlagChecker, mReason,
                            mCancellationElapsedTimeMs);
                    if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
                        mAttentionHelper.updateLightsLocked();
                    } else {
                        updateLightsLocked();
                    }
                    if (mShortcutHelper != null) {
                        mShortcutHelper.maybeListenForShortcutChangesForBubbles(r,
                                true /* isRemoved */,
@@ -8054,8 +8106,15 @@ public class NotificationManagerService extends SystemService {
                    int buzzBeepBlinkLoggingCode = 0;
                    if (!r.isHidden()) {
                        if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
                            buzzBeepBlinkLoggingCode = mAttentionHelper.buzzBeepBlinkLocked(r,
                                new NotificationAttentionHelper.Signals(
                                    mUserProfiles.isCurrentProfile(r.getUserId()),
                                    mListenerHints));
                        } else {
                            buzzBeepBlinkLoggingCode = buzzBeepBlinkLocked(r);
                        }
                    }
                    if (notification.getSmallIcon() != null) {
                        NotificationRecordLogger.NotificationReported maybeReport =
@@ -9034,7 +9093,13 @@ public class NotificationManagerService extends SystemService {
                    || interruptiveChanged;
            if (interceptBefore && !record.isIntercepted()
                    && record.isNewEnoughForAlerting(System.currentTimeMillis())) {
                if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
                    mAttentionHelper.buzzBeepBlinkLocked(record,
                        new NotificationAttentionHelper.Signals(
                            mUserProfiles.isCurrentProfile(record.getUserId()), mListenerHints));
                } else {
                    buzzBeepBlinkLocked(record);
                }
                // Log alert after change in intercepted state to Zen Log as well
                ZenLog.traceAlertOnUpdatedIntercept(record);
@@ -9408,6 +9473,9 @@ public class NotificationManagerService extends SystemService {
                });
            }
            if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
                mAttentionHelper.clearEffectsLocked(canceledKey);
            } else {
                // sound
                if (canceledKey.equals(mSoundNotificationKey)) {
                    clearSoundLocked();
@@ -9421,6 +9489,7 @@ public class NotificationManagerService extends SystemService {
                // light
                mLights.remove(canceledKey);
            }
        }
        // Record usage stats
        // TODO: add unbundling stats?
@@ -9768,9 +9837,13 @@ public class NotificationManagerService extends SystemService {
                            cancellationElapsedTimeMs);
                }
            }
            if (mFlagResolver.isEnabled(NotificationFlags.ENABLE_ATTENTION_HELPER_REFACTOR)) {
                mAttentionHelper.updateLightsLocked();
            } else {
                updateLightsLocked();
            }
        }
    }
    void snoozeNotificationInt(String key, long duration, String snoozeCriterionId,
            ManagedServiceInfo listener) {
+1973 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading