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

Commit 8196e171 authored by Julia Reynolds's avatar Julia Reynolds Committed by Android (Google) Code Review
Browse files

Merge "Log when notifying from a cached state" into main

parents d38ce1fd aa72d0fe
Loading
Loading
Loading
Loading
+43 −2
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.notification;
import static android.Manifest.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS;
import static android.Manifest.permission.RECEIVE_SENSITIVE_NOTIFICATIONS;
import static android.Manifest.permission.STATUS_BAR_SERVICE;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static android.app.ActivityManagerInternal.ServiceNotificationPolicy.NOT_FOREGROUND_SERVICE;
import static android.app.AppOpsManager.MODE_ALLOWED;
@@ -175,6 +176,7 @@ import static com.android.server.am.PendingIntentRecord.FLAG_BROADCAST_SENDER;
import static com.android.server.am.PendingIntentRecord.FLAG_SERVICE_SENDER;
import static com.android.server.notification.Flags.expireBitmaps;
import static com.android.server.notification.Flags.managedServicesConcurrentMultiuser;
import static com.android.server.notification.NotificationManagerService.NotificationPostEvent.NOTIFICATION_POSTED_CACHED;
import static com.android.server.policy.PhoneWindowManager.TOAST_WINDOW_ANIM_BUFFER;
import static com.android.server.policy.PhoneWindowManager.TOAST_WINDOW_TIMEOUT;
import static com.android.server.utils.PriorityDump.PRIORITY_ARG;
@@ -346,6 +348,9 @@ import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.Notificat
import com.android.internal.logging.InstanceId;
import com.android.internal.logging.InstanceIdSequence;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLoggerImpl;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.messages.nano.SystemMessageProto;
@@ -726,6 +731,7 @@ public class NotificationManagerService extends SystemService {
    private DevicePolicyManagerInternal mDpm;
    private StatsManager mStatsManager;
    private StatsPullAtomCallbackImpl mPullAtomCallback;
    private UiEventLogger mUiEventLogger;
    private Archive mArchive;
@@ -2667,6 +2673,22 @@ public class NotificationManagerService extends SystemService {
        mTelecomManager = tm;
    }
    enum NotificationPostEvent implements UiEventLogger.UiEventEnum {
        @UiEvent(doc = "An app posted a notification while cached")
        NOTIFICATION_POSTED_CACHED(2237);
        private final int mId;
        NotificationPostEvent(int id) {
            mId = id;
        }
        @Override
        public int getId() {
            return mId;
        }
    }
    // TODO: All tests should use this init instead of the one-off setters above.
    @VisibleForTesting
    void init(WorkerHandler handler, RankingHandler rankingHandler, Handler broadcastsHandler,
@@ -2686,7 +2708,8 @@ public class NotificationManagerService extends SystemService {
            TelecomManager telecomManager, NotificationChannelLogger channelLogger,
            SystemUiSystemPropertiesFlags.FlagResolver flagResolver,
            PermissionManager permissionManager, PowerManager powerManager,
            PostNotificationTrackerFactory postNotificationTrackerFactory) {
            PostNotificationTrackerFactory postNotificationTrackerFactory,
            UiEventLogger uiEventLogger) {
        mHandler = handler;
        if (Flags.nmBinderPerfThrottleEffectsSuppressorBroadcast()) {
            mBroadcastsHandler = broadcastsHandler;
@@ -2724,6 +2747,7 @@ public class NotificationManagerService extends SystemService {
        mPostNotificationTrackerFactory = postNotificationTrackerFactory;
        mPlatformCompat = IPlatformCompat.Stub.asInterface(
                ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
        mUiEventLogger = uiEventLogger;
        mStrongAuthTracker = new StrongAuthTracker(getContext());
        String[] extractorNames;
@@ -3054,7 +3078,7 @@ public class NotificationManagerService extends SystemService {
                new NotificationChannelLoggerImpl(), SystemUiSystemPropertiesFlags.getResolver(),
                getContext().getSystemService(PermissionManager.class),
                getContext().getSystemService(PowerManager.class),
                new PostNotificationTrackerFactory() {});
                new PostNotificationTrackerFactory() {}, new UiEventLoggerImpl());
        publishBinderService(Context.NOTIFICATION_SERVICE, mService, /* allowIsolated= */ false,
                DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL);
@@ -8375,6 +8399,12 @@ public class NotificationManagerService extends SystemService {
            final int callingPid, final String tag, final int id, final Notification notification,
            int incomingUserId, boolean postSilently, boolean byForegroundService,
            boolean isAppProvided) {
        if (Flags.logCachedPosts()) {
            final int packageImportance = getPackageImportanceWithIdentity(callingUid);
            if (packageImportance == IMPORTANCE_CACHED) {
                mUiEventLogger.log(NOTIFICATION_POSTED_CACHED, callingUid, opPkg);
            }
        }
        PostNotificationTracker tracker = acquireWakeLockForPost(pkg, callingUid);
        boolean enqueued = false;
        try {
@@ -13039,6 +13069,17 @@ public class NotificationManagerService extends SystemService {
        return packageImportance;
    }
    private int getPackageImportanceWithIdentity(int uid) {
        final int packageImportance;
        final long token = Binder.clearCallingIdentity();
        try {
            packageImportance = mActivityManager.getUidImportance(uid);
        } finally {
            Binder.restoreCallingIdentity(token);
        }
        return packageImportance;
    }
    public class NotificationListeners extends ManagedServices {
        static final String TAG_ENABLED_NOTIFICATION_LISTENERS = "enabled_listeners";
        static final String TAG_REQUESTED_LISTENERS = "request_listeners";
+10 −0
Original line number Diff line number Diff line
@@ -207,3 +207,13 @@ flag {
  description: "Enables ManagedServices to support Concurrent multi user environment"
  bug: "380297485"
}

flag {
  name: "log_cached_posts"
  namespace: "systemui"
  description: "Logs an event if notify was called from a cached process state"
  bug: "392740866"
  metadata {
    purpose: PURPOSE_BUGFIX
  }
}
+34 −9
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.notification;
import static android.Manifest.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS;
import static android.Manifest.permission.STATUS_BAR_SERVICE;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
import static android.app.ActivityManagerInternal.ServiceNotificationPolicy.NOT_FOREGROUND_SERVICE;
@@ -142,12 +143,14 @@ import static com.android.server.am.PendingIntentRecord.FLAG_ACTIVITY_SENDER;
import static com.android.server.am.PendingIntentRecord.FLAG_BROADCAST_SENDER;
import static com.android.server.am.PendingIntentRecord.FLAG_SERVICE_SENDER;
import static com.android.server.notification.Flags.FLAG_ALL_NOTIFS_NEED_TTL;
import static com.android.server.notification.Flags.FLAG_LOG_CACHED_POSTS;
import static com.android.server.notification.Flags.FLAG_MANAGED_SERVICES_CONCURRENT_MULTIUSER;
import static com.android.server.notification.Flags.FLAG_REJECT_OLD_NOTIFICATIONS;
import static com.android.server.notification.GroupHelper.AUTOGROUP_KEY;
import static com.android.server.notification.NotificationManagerService.BITMAP_DURATION;
import static com.android.server.notification.NotificationManagerService.DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE;
import static com.android.server.notification.NotificationManagerService.NOTIFICATION_TTL;
import static com.android.server.notification.NotificationManagerService.NotificationPostEvent.NOTIFICATION_POSTED_CACHED;
import static com.android.server.notification.NotificationManagerService.TAG;
import static com.android.server.notification.NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_ADJUSTED;
import static com.android.server.notification.NotificationRecordLogger.NotificationReportedEvent.NOTIFICATION_POSTED;
@@ -168,12 +171,12 @@ import static junit.framework.Assert.fail;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.atLeastOnce;
@@ -322,6 +325,7 @@ import com.android.internal.config.sysui.TestableFlagResolver;
import com.android.internal.logging.InstanceId;
import com.android.internal.logging.InstanceIdSequence;
import com.android.internal.logging.InstanceIdSequenceFake;
import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.internal.messages.nano.SystemMessageProto;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.widget.LockPatternUtils;
@@ -349,13 +353,13 @@ import com.android.server.utils.quota.MultiRateLimiter;
import com.android.server.wm.ActivityTaskManagerInternal;
import com.android.server.wm.WindowManagerInternal;
import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
import com.google.android.collect.Lists;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@@ -373,9 +377,6 @@ import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
import platform.test.runner.parameterized.Parameters;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
@@ -391,6 +392,9 @@ import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.function.Consumer;
import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
import platform.test.runner.parameterized.Parameters;
@SmallTest
@RunWith(ParameterizedAndroidJunit4.class)
@RunWithLooper
@@ -487,6 +491,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
    private final ArrayList<WakeLock> mAcquiredWakeLocks = new ArrayList<>();
    private final TestPostNotificationTrackerFactory mPostNotificationTrackerFactory =
            new TestPostNotificationTrackerFactory();
    private UiEventLoggerFake mUiEventLogger;
    private PendingIntent mActivityIntent;
    private PendingIntent mActivityIntentImmutable;
@@ -619,6 +624,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        MockitoAnnotations.initMocks(this);
        mUiEventLogger = new UiEventLoggerFake();
        when(mActivityManager.getUidImportance(anyInt())).thenReturn(IMPORTANCE_VISIBLE);
        DeviceIdleInternal deviceIdleInternal = mock(DeviceIdleInternal.class);
        when(deviceIdleInternal.getNotificationAllowlistDuration()).thenReturn(3000L);
@@ -811,7 +819,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                mAppOpsManager, mUm, mHistoryManager, mStatsManager, mAmi, mToastRateLimiter,
                mPermissionHelper, mock(UsageStatsManagerInternal.class), mTelecomManager, mLogger,
                mTestFlagResolver, mPermissionManager, mPowerManager,
                mPostNotificationTrackerFactory);
                mPostNotificationTrackerFactory, mUiEventLogger);
        mService.setAttentionHelper(mAttentionHelper);
        mService.setLockPatternUtils(mock(LockPatternUtils.class));
@@ -1418,6 +1426,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, sbn.getTag(),
                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
        waitForIdle();
        assertThat(mUiEventLogger.numLogs()).isEqualTo(0);
        return mService.findNotificationLocked(
                mPkg, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getUserId());
@@ -18959,4 +18968,20 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                any(IBinder.class), anyInt(), any(), eq(DEFAULT_DISPLAY));
        verify(mStatusBar, never()).hideToast(eq(testPackage), eq(firstBuiltin));
    }
    @Test
    @EnableFlags(FLAG_LOG_CACHED_POSTS)
    public void notifyAsCached_Logs() throws Exception {
        when(mActivityManager.getUidImportance(anyInt())).thenReturn(IMPORTANCE_CACHED);
        NotificationRecord n = generateNotificationRecord(
                mTestNotificationChannel, 1, "group", true);
        mBinderService.enqueueNotificationWithTag(mPkg, mPkg, "tag",
                n.getSbn().getId(), n.getSbn().getNotification(), n.getSbn().getUserId());
        waitForIdle();
        assertThat(mUiEventLogger.numLogs()).isEqualTo(1);
        assertThat(mUiEventLogger.get(0).eventId).isEqualTo(NOTIFICATION_POSTED_CACHED.getId());
        assertThat(mUiEventLogger.get(0).uid).isEqualTo(mUid);
    }
}
+3 −1
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.config.sysui.TestableFlagResolver;
import com.android.internal.logging.InstanceIdSequence;
import com.android.internal.logging.InstanceIdSequenceFake;
import com.android.internal.logging.UiEventLogger;
import com.android.server.LocalServices;
import com.android.server.UiServiceTestCase;
import com.android.server.lights.LightsManager;
@@ -171,7 +172,8 @@ public class RoleObserverTest extends UiServiceTestCase {
                    mock(NotificationChannelLogger.class), new TestableFlagResolver(),
                    mock(PermissionManager.class),
                    mock(PowerManager.class),
                    new NotificationManagerService.PostNotificationTrackerFactory() {});
                    new NotificationManagerService.PostNotificationTrackerFactory() {},
                    mock(UiEventLogger.class));
        } catch (SecurityException e) {
            if (!e.getMessage().contains("Permission Denial: not allowed to send broadcast")) {
                throw e;