Merge "Statsd logging: notification controls." into rvc-dev

This commit is contained in:
TreeHugger Robot
2020-06-23 05:26:55 +00:00
committed by Android (Google) Code Review
9 changed files with 234 additions and 19 deletions

View File

@@ -24,6 +24,7 @@ import android.os.Handler;
import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityManager;
import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.bubbles.BubbleController; import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Background;
@@ -116,7 +117,8 @@ public interface NotificationsModule {
ChannelEditorDialogController channelEditorDialogController, ChannelEditorDialogController channelEditorDialogController,
CurrentUserContextTracker contextTracker, CurrentUserContextTracker contextTracker,
Provider<PriorityOnboardingDialogController.Builder> builderProvider, Provider<PriorityOnboardingDialogController.Builder> builderProvider,
BubbleController bubbleController) { BubbleController bubbleController,
UiEventLogger uiEventLogger) {
return new NotificationGutsManager( return new NotificationGutsManager(
context, context,
visualStabilityManager, visualStabilityManager,
@@ -131,7 +133,8 @@ public interface NotificationsModule {
channelEditorDialogController, channelEditorDialogController,
contextTracker, contextTracker,
builderProvider, builderProvider,
bubbleController); bubbleController,
uiEventLogger);
} }
/** Provides an instance of {@link VisualStabilityManager} */ /** Provides an instance of {@link VisualStabilityManager} */

View File

@@ -31,6 +31,7 @@ import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.R; import com.android.systemui.R;
@@ -50,6 +51,7 @@ public class AppOpsInfo extends LinearLayout implements NotificationGuts.GutsCon
private MetricsLogger mMetricsLogger; private MetricsLogger mMetricsLogger;
private OnSettingsClickListener mOnSettingsClickListener; private OnSettingsClickListener mOnSettingsClickListener;
private NotificationGuts mGutsContainer; private NotificationGuts mGutsContainer;
private UiEventLogger mUiEventLogger;
private OnClickListener mOnOk = v -> { private OnClickListener mOnOk = v -> {
mGutsContainer.closeControls(v, false); mGutsContainer.closeControls(v, false);
@@ -66,6 +68,7 @@ public class AppOpsInfo extends LinearLayout implements NotificationGuts.GutsCon
public void bindGuts(final PackageManager pm, public void bindGuts(final PackageManager pm,
final OnSettingsClickListener onSettingsClick, final OnSettingsClickListener onSettingsClick,
final StatusBarNotification sbn, final StatusBarNotification sbn,
final UiEventLogger uiEventLogger,
ArraySet<Integer> activeOps) { ArraySet<Integer> activeOps) {
mPkg = sbn.getPackageName(); mPkg = sbn.getPackageName();
mSbn = sbn; mSbn = sbn;
@@ -73,11 +76,13 @@ public class AppOpsInfo extends LinearLayout implements NotificationGuts.GutsCon
mAppName = mPkg; mAppName = mPkg;
mOnSettingsClickListener = onSettingsClick; mOnSettingsClickListener = onSettingsClick;
mAppOps = activeOps; mAppOps = activeOps;
mUiEventLogger = uiEventLogger;
bindHeader(); bindHeader();
bindPrompt(); bindPrompt();
bindButtons(); bindButtons();
logUiEvent(NotificationAppOpsEvent.NOTIFICATION_APP_OPS_OPEN);
mMetricsLogger = new MetricsLogger(); mMetricsLogger = new MetricsLogger();
mMetricsLogger.visibility(MetricsEvent.APP_OPS_GUTS, true); mMetricsLogger.visibility(MetricsEvent.APP_OPS_GUTS, true);
} }
@@ -188,6 +193,7 @@ public class AppOpsInfo extends LinearLayout implements NotificationGuts.GutsCon
@Override @Override
public boolean handleCloseControls(boolean save, boolean force) { public boolean handleCloseControls(boolean save, boolean force) {
logUiEvent(NotificationAppOpsEvent.NOTIFICATION_APP_OPS_CLOSE);
if (mMetricsLogger != null) { if (mMetricsLogger != null) {
mMetricsLogger.visibility(MetricsEvent.APP_OPS_GUTS, false); mMetricsLogger.visibility(MetricsEvent.APP_OPS_GUTS, false);
} }
@@ -198,4 +204,11 @@ public class AppOpsInfo extends LinearLayout implements NotificationGuts.GutsCon
public int getActualHeight() { public int getActualHeight() {
return getHeight(); return getHeight();
} }
private void logUiEvent(NotificationAppOpsEvent event) {
if (mSbn != null) {
mUiEventLogger.logWithInstanceId(event,
mSbn.getUid(), mSbn.getPackageName(), mSbn.getInstanceId());
}
}
} }

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2020 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.systemui.statusbar.notification.row;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
enum NotificationAppOpsEvent implements UiEventLogger.UiEventEnum {
@UiEvent(doc = "User opened app ops controls on a notification (for active "
+ "privacy-sensitive permissions usage)")
NOTIFICATION_APP_OPS_OPEN(597),
@UiEvent(doc = "User closed app ops controls")
NOTIFICATION_APP_OPS_CLOSE(598),
@UiEvent(doc = "User clicked through to settings in app ops controls")
NOTIFICATION_APP_OPS_SETTINGS_CLICK(599);
private final int mId;
NotificationAppOpsEvent(int id) {
mId = id;
}
@Override public int getId() {
return mId;
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (C) 2020 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.systemui.statusbar.notification.row;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
enum NotificationControlsEvent implements UiEventLogger.UiEventEnum {
@UiEvent(doc = "The user opened the notification inline controls.")
NOTIFICATION_CONTROLS_OPEN(594),
@UiEvent(doc = "In notification inline controls, the user saved a notification channel "
+ "importance change.")
NOTIFICATION_CONTROLS_SAVE_IMPORTANCE(595),
@UiEvent(doc = "The user closed the notification inline controls.")
NOTIFICATION_CONTROLS_CLOSE(596);
private final int mId;
NotificationControlsEvent(int id) {
mId = id;
}
@Override public int getId() {
return mId;
}
}

View File

@@ -41,6 +41,7 @@ import android.view.accessibility.AccessibilityManager;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto; import com.android.internal.logging.nano.MetricsProto;
import com.android.settingslib.notification.ConversationIconFactory; import com.android.settingslib.notification.ConversationIconFactory;
import com.android.systemui.Dependency; import com.android.systemui.Dependency;
@@ -121,6 +122,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
private final ShortcutManager mShortcutManager; private final ShortcutManager mShortcutManager;
private final CurrentUserContextTracker mContextTracker; private final CurrentUserContextTracker mContextTracker;
private final Provider<PriorityOnboardingDialogController.Builder> mBuilderProvider; private final Provider<PriorityOnboardingDialogController.Builder> mBuilderProvider;
private final UiEventLogger mUiEventLogger;
/** /**
* Injected constructor. See {@link NotificationsModule}. * Injected constructor. See {@link NotificationsModule}.
@@ -135,7 +137,8 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
ChannelEditorDialogController channelEditorDialogController, ChannelEditorDialogController channelEditorDialogController,
CurrentUserContextTracker contextTracker, CurrentUserContextTracker contextTracker,
Provider<PriorityOnboardingDialogController.Builder> builderProvider, Provider<PriorityOnboardingDialogController.Builder> builderProvider,
BubbleController bubbleController) { BubbleController bubbleController,
UiEventLogger uiEventLogger) {
mContext = context; mContext = context;
mVisualStabilityManager = visualStabilityManager; mVisualStabilityManager = visualStabilityManager;
mStatusBarLazy = statusBarLazy; mStatusBarLazy = statusBarLazy;
@@ -150,6 +153,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
mBuilderProvider = builderProvider; mBuilderProvider = builderProvider;
mChannelEditorDialogController = channelEditorDialogController; mChannelEditorDialogController = channelEditorDialogController;
mBubbleController = bubbleController; mBubbleController = bubbleController;
mUiEventLogger = uiEventLogger;
} }
public void setUpWithPresenter(NotificationPresenter presenter, public void setUpWithPresenter(NotificationPresenter presenter,
@@ -315,12 +319,16 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
AppOpsInfo.OnSettingsClickListener onSettingsClick = AppOpsInfo.OnSettingsClickListener onSettingsClick =
(View v, String pkg, int uid, ArraySet<Integer> ops) -> { (View v, String pkg, int uid, ArraySet<Integer> ops) -> {
mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_OPS_GUTS_SETTINGS); mUiEventLogger.logWithInstanceId(
guts.resetFalsingCheck(); NotificationAppOpsEvent.NOTIFICATION_APP_OPS_SETTINGS_CLICK,
startAppOpsSettingsActivity(pkg, uid, ops, row); sbn.getUid(), sbn.getPackageName(), sbn.getInstanceId());
mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_OPS_GUTS_SETTINGS);
guts.resetFalsingCheck();
startAppOpsSettingsActivity(pkg, uid, ops, row);
}; };
if (!row.getEntry().mActiveAppOps.isEmpty()) { if (!row.getEntry().mActiveAppOps.isEmpty()) {
appOpsInfoView.bindGuts(pmUser, onSettingsClick, sbn, row.getEntry().mActiveAppOps); appOpsInfoView.bindGuts(pmUser, onSettingsClick, sbn, mUiEventLogger,
row.getEntry().mActiveAppOps);
} }
} }
@@ -370,6 +378,7 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
row.getEntry(), row.getEntry(),
onSettingsClick, onSettingsClick,
onAppSettingsClick, onAppSettingsClick,
mUiEventLogger,
mDeviceProvisionedController.isDeviceProvisioned(), mDeviceProvisionedController.isDeviceProvisioned(),
row.getIsNonblockable(), row.getIsNonblockable(),
mHighPriorityProvider.isHighPriority(row.getEntry())); mHighPriorityProvider.isHighPriority(row.getEntry()));

View File

@@ -56,6 +56,7 @@ import android.widget.TextView;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.Dependency; import com.android.systemui.Dependency;
import com.android.systemui.R; import com.android.systemui.R;
@@ -122,6 +123,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
private OnAppSettingsClickListener mAppSettingsClickListener; private OnAppSettingsClickListener mAppSettingsClickListener;
private NotificationGuts mGutsContainer; private NotificationGuts mGutsContainer;
private Drawable mPkgIcon; private Drawable mPkgIcon;
private UiEventLogger mUiEventLogger;
@VisibleForTesting @VisibleForTesting
boolean mSkipPost = false; boolean mSkipPost = false;
@@ -182,6 +184,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
NotificationEntry entry, NotificationEntry entry,
OnSettingsClickListener onSettingsClick, OnSettingsClickListener onSettingsClick,
OnAppSettingsClickListener onAppSettingsClick, OnAppSettingsClickListener onAppSettingsClick,
UiEventLogger uiEventLogger,
boolean isDeviceProvisioned, boolean isDeviceProvisioned,
boolean isNonblockable, boolean isNonblockable,
boolean wasShownHighPriority) boolean wasShownHighPriority)
@@ -205,6 +208,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
mAppUid = mSbn.getUid(); mAppUid = mSbn.getUid();
mDelegatePkg = mSbn.getOpPkg(); mDelegatePkg = mSbn.getOpPkg();
mIsDeviceProvisioned = isDeviceProvisioned; mIsDeviceProvisioned = isDeviceProvisioned;
mUiEventLogger = uiEventLogger;
int numTotalChannels = mINotificationManager.getNumNotificationChannelsForPackage( int numTotalChannels = mINotificationManager.getNumNotificationChannelsForPackage(
pkg, mAppUid, false /* includeDeleted */); pkg, mAppUid, false /* includeDeleted */);
@@ -223,6 +227,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
bindInlineControls(); bindInlineControls();
logUiEvent(NotificationControlsEvent.NOTIFICATION_CONTROLS_OPEN);
mMetricsLogger.write(notificationControlsLogMaker()); mMetricsLogger.write(notificationControlsLogMaker());
} }
@@ -397,6 +402,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
*/ */
private void updateImportance() { private void updateImportance() {
if (mChosenImportance != null) { if (mChosenImportance != null) {
logUiEvent(NotificationControlsEvent.NOTIFICATION_CONTROLS_SAVE_IMPORTANCE);
mMetricsLogger.write(importanceChangeLogMaker()); mMetricsLogger.write(importanceChangeLogMaker());
int newImportance = mChosenImportance; int newImportance = mChosenImportance;
@@ -483,6 +489,7 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
bindInlineControls(); bindInlineControls();
logUiEvent(NotificationControlsEvent.NOTIFICATION_CONTROLS_CLOSE);
mMetricsLogger.write(notificationControlsLogMaker().setType(MetricsEvent.TYPE_CLOSE)); mMetricsLogger.write(notificationControlsLogMaker().setType(MetricsEvent.TYPE_CLOSE));
} }
@@ -627,6 +634,13 @@ public class NotificationInfo extends LinearLayout implements NotificationGuts.G
} }
} }
private void logUiEvent(NotificationControlsEvent event) {
if (mSbn != null) {
mUiEventLogger.logWithInstanceId(event,
mSbn.getUid(), mSbn.getPackageName(), mSbn.getInstanceId());
}
}
/** /**
* Returns a LogMaker with all available notification information. * Returns a LogMaker with all available notification information.
* Caller should set category, type, and maybe subtype, before passing it to mMetricsLogger. * Caller should set category, type, and maybe subtype, before passing it to mMetricsLogger.

View File

@@ -49,6 +49,7 @@ import android.view.View;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.SysuiTestCase; import com.android.systemui.SysuiTestCase;
@@ -69,6 +70,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
private final PackageManager mMockPackageManager = mock(PackageManager.class); private final PackageManager mMockPackageManager = mock(PackageManager.class);
private final NotificationGuts mGutsParent = mock(NotificationGuts.class); private final NotificationGuts mGutsParent = mock(NotificationGuts.class);
private StatusBarNotification mSbn; private StatusBarNotification mSbn;
private UiEventLoggerFake mUiEventLogger = new UiEventLoggerFake();
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
@@ -94,7 +96,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
@Test @Test
public void testBindNotification_SetsTextApplicationName() { public void testBindNotification_SetsTextApplicationName() {
when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name"); when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, new ArraySet<>()); mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, new ArraySet<>());
final TextView textView = mAppOpsInfo.findViewById(R.id.pkgname); final TextView textView = mAppOpsInfo.findViewById(R.id.pkgname);
assertTrue(textView.getText().toString().contains("App Name")); assertTrue(textView.getText().toString().contains("App Name"));
} }
@@ -104,7 +106,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
final Drawable iconDrawable = mock(Drawable.class); final Drawable iconDrawable = mock(Drawable.class);
when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class))) when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class)))
.thenReturn(iconDrawable); .thenReturn(iconDrawable);
mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, new ArraySet<>()); mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, new ArraySet<>());
final ImageView iconView = mAppOpsInfo.findViewById(R.id.pkgicon); final ImageView iconView = mAppOpsInfo.findViewById(R.id.pkgicon);
assertEquals(iconDrawable, iconView.getDrawable()); assertEquals(iconDrawable, iconView.getDrawable());
} }
@@ -120,7 +122,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
assertEquals(expectedOps, ops); assertEquals(expectedOps, ops);
assertEquals(TEST_UID, uid); assertEquals(TEST_UID, uid);
latch.countDown(); latch.countDown();
}, mSbn, expectedOps); }, mSbn, mUiEventLogger, expectedOps);
final View settingsButton = mAppOpsInfo.findViewById(R.id.settings); final View settingsButton = mAppOpsInfo.findViewById(R.id.settings);
settingsButton.performClick(); settingsButton.performClick();
@@ -128,6 +130,14 @@ public class AppOpsInfoTest extends SysuiTestCase {
assertEquals(0, latch.getCount()); assertEquals(0, latch.getCount());
} }
@Test
public void testBindNotification_LogsOpen() throws Exception {
mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, new ArraySet<>());
assertEquals(1, mUiEventLogger.numLogs());
assertEquals(NotificationAppOpsEvent.NOTIFICATION_APP_OPS_OPEN.getId(),
mUiEventLogger.eventId(0));
}
@Test @Test
public void testOk() { public void testOk() {
ArraySet<Integer> expectedOps = new ArraySet<>(); ArraySet<Integer> expectedOps = new ArraySet<>();
@@ -139,7 +149,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
assertEquals(expectedOps, ops); assertEquals(expectedOps, ops);
assertEquals(TEST_UID, uid); assertEquals(TEST_UID, uid);
latch.countDown(); latch.countDown();
}, mSbn, expectedOps); }, mSbn, mUiEventLogger, expectedOps);
final View okButton = mAppOpsInfo.findViewById(R.id.ok); final View okButton = mAppOpsInfo.findViewById(R.id.ok);
okButton.performClick(); okButton.performClick();
@@ -151,7 +161,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
public void testPrompt_camera() { public void testPrompt_camera() {
ArraySet<Integer> expectedOps = new ArraySet<>(); ArraySet<Integer> expectedOps = new ArraySet<>();
expectedOps.add(OP_CAMERA); expectedOps.add(OP_CAMERA);
mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, expectedOps); mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
TextView prompt = mAppOpsInfo.findViewById(R.id.prompt); TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
assertEquals("This app is using the camera.", prompt.getText()); assertEquals("This app is using the camera.", prompt.getText());
} }
@@ -160,7 +170,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
public void testPrompt_mic() { public void testPrompt_mic() {
ArraySet<Integer> expectedOps = new ArraySet<>(); ArraySet<Integer> expectedOps = new ArraySet<>();
expectedOps.add(OP_RECORD_AUDIO); expectedOps.add(OP_RECORD_AUDIO);
mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, expectedOps); mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
TextView prompt = mAppOpsInfo.findViewById(R.id.prompt); TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
assertEquals("This app is using the microphone.", prompt.getText()); assertEquals("This app is using the microphone.", prompt.getText());
} }
@@ -169,7 +179,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
public void testPrompt_overlay() { public void testPrompt_overlay() {
ArraySet<Integer> expectedOps = new ArraySet<>(); ArraySet<Integer> expectedOps = new ArraySet<>();
expectedOps.add(OP_SYSTEM_ALERT_WINDOW); expectedOps.add(OP_SYSTEM_ALERT_WINDOW);
mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, expectedOps); mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
TextView prompt = mAppOpsInfo.findViewById(R.id.prompt); TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
assertEquals("This app is displaying over other apps on your screen.", prompt.getText()); assertEquals("This app is displaying over other apps on your screen.", prompt.getText());
} }
@@ -179,7 +189,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
ArraySet<Integer> expectedOps = new ArraySet<>(); ArraySet<Integer> expectedOps = new ArraySet<>();
expectedOps.add(OP_CAMERA); expectedOps.add(OP_CAMERA);
expectedOps.add(OP_RECORD_AUDIO); expectedOps.add(OP_RECORD_AUDIO);
mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, expectedOps); mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
TextView prompt = mAppOpsInfo.findViewById(R.id.prompt); TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
assertEquals("This app is using the microphone and camera.", prompt.getText()); assertEquals("This app is using the microphone and camera.", prompt.getText());
} }
@@ -190,7 +200,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
expectedOps.add(OP_CAMERA); expectedOps.add(OP_CAMERA);
expectedOps.add(OP_RECORD_AUDIO); expectedOps.add(OP_RECORD_AUDIO);
expectedOps.add(OP_SYSTEM_ALERT_WINDOW); expectedOps.add(OP_SYSTEM_ALERT_WINDOW);
mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, expectedOps); mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
TextView prompt = mAppOpsInfo.findViewById(R.id.prompt); TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
assertEquals("This app is displaying over other apps on your screen and using" assertEquals("This app is displaying over other apps on your screen and using"
+ " the microphone and camera.", prompt.getText()); + " the microphone and camera.", prompt.getText());
@@ -201,7 +211,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
ArraySet<Integer> expectedOps = new ArraySet<>(); ArraySet<Integer> expectedOps = new ArraySet<>();
expectedOps.add(OP_CAMERA); expectedOps.add(OP_CAMERA);
expectedOps.add(OP_SYSTEM_ALERT_WINDOW); expectedOps.add(OP_SYSTEM_ALERT_WINDOW);
mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, expectedOps); mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
TextView prompt = mAppOpsInfo.findViewById(R.id.prompt); TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
assertEquals("This app is displaying over other apps on your screen and using" assertEquals("This app is displaying over other apps on your screen and using"
+ " the camera.", prompt.getText()); + " the camera.", prompt.getText());
@@ -212,7 +222,7 @@ public class AppOpsInfoTest extends SysuiTestCase {
ArraySet<Integer> expectedOps = new ArraySet<>(); ArraySet<Integer> expectedOps = new ArraySet<>();
expectedOps.add(OP_RECORD_AUDIO); expectedOps.add(OP_RECORD_AUDIO);
expectedOps.add(OP_SYSTEM_ALERT_WINDOW); expectedOps.add(OP_SYSTEM_ALERT_WINDOW);
mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, expectedOps); mAppOpsInfo.bindGuts(mMockPackageManager, null, mSbn, mUiEventLogger, expectedOps);
TextView prompt = mAppOpsInfo.findViewById(R.id.prompt); TextView prompt = mAppOpsInfo.findViewById(R.id.prompt);
assertEquals("This app is displaying over other apps on your screen and using" assertEquals("This app is displaying over other apps on your screen and using"
+ " the microphone.", prompt.getText()); + " the microphone.", prompt.getText());

View File

@@ -64,6 +64,8 @@ import android.view.accessibility.AccessibilityManager;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.systemui.SysuiTestCase; import com.android.systemui.SysuiTestCase;
import com.android.systemui.bubbles.BubbleController; import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin; import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
@@ -149,7 +151,8 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
mGutsManager = new NotificationGutsManager(mContext, mVisualStabilityManager, mGutsManager = new NotificationGutsManager(mContext, mVisualStabilityManager,
() -> mStatusBar, mHandler, mHandler, mAccessibilityManager, mHighPriorityProvider, () -> mStatusBar, mHandler, mHandler, mAccessibilityManager, mHighPriorityProvider,
mINotificationManager, mLauncherApps, mShortcutManager, mINotificationManager, mLauncherApps, mShortcutManager,
mChannelEditorDialogController, mContextTracker, mProvider, mBubbleController); mChannelEditorDialogController, mContextTracker, mProvider, mBubbleController,
new UiEventLoggerFake());
mGutsManager.setUpWithPresenter(mPresenter, mStackScroller, mGutsManager.setUpWithPresenter(mPresenter, mStackScroller,
mCheckSaveListener, mOnSettingsClickListener); mCheckSaveListener, mOnSettingsClickListener);
mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter); mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
@@ -362,6 +365,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
eq(entry), eq(entry),
any(NotificationInfo.OnSettingsClickListener.class), any(NotificationInfo.OnSettingsClickListener.class),
any(NotificationInfo.OnAppSettingsClickListener.class), any(NotificationInfo.OnAppSettingsClickListener.class),
any(UiEventLogger.class),
eq(false), eq(false),
eq(false), eq(false),
eq(true) /* wasShownHighPriority */); eq(true) /* wasShownHighPriority */);
@@ -394,6 +398,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
eq(entry), eq(entry),
any(NotificationInfo.OnSettingsClickListener.class), any(NotificationInfo.OnSettingsClickListener.class),
any(NotificationInfo.OnAppSettingsClickListener.class), any(NotificationInfo.OnAppSettingsClickListener.class),
any(UiEventLogger.class),
eq(true), eq(true),
eq(false), eq(false),
eq(false) /* wasShownHighPriority */); eq(false) /* wasShownHighPriority */);
@@ -424,6 +429,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
eq(entry), eq(entry),
any(NotificationInfo.OnSettingsClickListener.class), any(NotificationInfo.OnSettingsClickListener.class),
any(NotificationInfo.OnAppSettingsClickListener.class), any(NotificationInfo.OnAppSettingsClickListener.class),
any(UiEventLogger.class),
eq(false), eq(false),
eq(false), eq(false),
eq(false) /* wasShownHighPriority */); eq(false) /* wasShownHighPriority */);

View File

@@ -62,6 +62,7 @@ import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.systemui.Dependency; import com.android.systemui.Dependency;
import com.android.systemui.R; import com.android.systemui.R;
import com.android.systemui.SysuiTestCase; import com.android.systemui.SysuiTestCase;
@@ -102,6 +103,7 @@ public class NotificationInfoTest extends SysuiTestCase {
private Set<NotificationChannel> mDefaultNotificationChannelSet = new HashSet<>(); private Set<NotificationChannel> mDefaultNotificationChannelSet = new HashSet<>();
private StatusBarNotification mSbn; private StatusBarNotification mSbn;
private NotificationEntry mEntry; private NotificationEntry mEntry;
private UiEventLoggerFake mUiEventLogger = new UiEventLoggerFake();
@Rule @Rule
public MockitoRule mockito = MockitoJUnit.rule(); public MockitoRule mockito = MockitoJUnit.rule();
@@ -187,6 +189,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -211,6 +214,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -231,6 +235,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -260,6 +265,7 @@ public class NotificationInfoTest extends SysuiTestCase {
entry, entry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -281,6 +287,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -307,6 +314,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -328,6 +336,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -348,6 +357,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -372,6 +382,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -392,6 +403,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
true, true,
true); true);
@@ -416,6 +428,7 @@ public class NotificationInfoTest extends SysuiTestCase {
latch.countDown(); latch.countDown();
}, },
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -439,6 +452,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -462,6 +476,7 @@ public class NotificationInfoTest extends SysuiTestCase {
assertEquals(mNotificationChannel, c); assertEquals(mNotificationChannel, c);
}, },
null, null,
mUiEventLogger,
false, false,
false, false,
true); true);
@@ -482,6 +497,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -496,6 +512,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
(View v, NotificationChannel c, int appUid) -> { }, (View v, NotificationChannel c, int appUid) -> { },
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -519,6 +536,7 @@ public class NotificationInfoTest extends SysuiTestCase {
latch.countDown(); latch.countDown();
}, },
null, null,
mUiEventLogger,
true, true,
true, true,
true); true);
@@ -543,6 +561,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -565,6 +584,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -587,6 +607,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
true, true,
true); true);
@@ -611,6 +632,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -630,6 +652,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
false); false);
@@ -649,6 +672,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -657,6 +681,28 @@ public class NotificationInfoTest extends SysuiTestCase {
anyString(), eq(TEST_UID), any()); anyString(), eq(TEST_UID), any());
} }
@Test
public void testBindNotification_LogsOpen() throws Exception {
mNotificationInfo.bindNotification(
mMockPackageManager,
mMockINotificationManager,
mVisualStabilityManager,
mChannelEditorDialogController,
TEST_PACKAGE_NAME,
mNotificationChannel,
mNotificationChannelSet,
mEntry,
null,
null,
mUiEventLogger,
true,
false,
true);
assertEquals(1, mUiEventLogger.numLogs());
assertEquals(NotificationControlsEvent.NOTIFICATION_CONTROLS_OPEN.getId(),
mUiEventLogger.eventId(0));
}
@Test @Test
public void testDoesNotUpdateNotificationChannelAfterImportanceChanged() throws Exception { public void testDoesNotUpdateNotificationChannelAfterImportanceChanged() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW); mNotificationChannel.setImportance(IMPORTANCE_LOW);
@@ -671,6 +717,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
false); false);
@@ -696,6 +743,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -721,6 +769,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -730,6 +779,13 @@ public class NotificationInfoTest extends SysuiTestCase {
verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage( verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
anyString(), eq(TEST_UID), any()); anyString(), eq(TEST_UID), any());
assertEquals(originalImportance, mNotificationChannel.getImportance()); assertEquals(originalImportance, mNotificationChannel.getImportance());
assertEquals(2, mUiEventLogger.numLogs());
assertEquals(NotificationControlsEvent.NOTIFICATION_CONTROLS_OPEN.getId(),
mUiEventLogger.eventId(0));
// The SAVE_IMPORTANCE event is logged whenever importance is saved, even if unchanged.
assertEquals(NotificationControlsEvent.NOTIFICATION_CONTROLS_SAVE_IMPORTANCE.getId(),
mUiEventLogger.eventId(1));
} }
@Test @Test
@@ -747,6 +803,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -773,6 +830,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -789,6 +847,12 @@ public class NotificationInfoTest extends SysuiTestCase {
assertTrue((updated.getValue().getUserLockedFields() assertTrue((updated.getValue().getUserLockedFields()
& USER_LOCKED_IMPORTANCE) != 0); & USER_LOCKED_IMPORTANCE) != 0);
assertEquals(IMPORTANCE_LOW, updated.getValue().getImportance()); assertEquals(IMPORTANCE_LOW, updated.getValue().getImportance());
assertEquals(2, mUiEventLogger.numLogs());
assertEquals(NotificationControlsEvent.NOTIFICATION_CONTROLS_OPEN.getId(),
mUiEventLogger.eventId(0));
assertEquals(NotificationControlsEvent.NOTIFICATION_CONTROLS_SAVE_IMPORTANCE.getId(),
mUiEventLogger.eventId(1));
} }
@Test @Test
@@ -805,6 +869,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
false); false);
@@ -838,6 +903,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -871,6 +937,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
false); false);
@@ -907,6 +974,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
false); false);
@@ -942,6 +1010,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
true); true);
@@ -968,6 +1037,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
false); false);
@@ -997,6 +1067,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
false); false);
@@ -1029,6 +1100,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
false); false);
@@ -1040,6 +1112,10 @@ public class NotificationInfoTest extends SysuiTestCase {
mTestableLooper.processAllMessages(); mTestableLooper.processAllMessages();
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage( verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(mNotificationChannel)); eq(TEST_PACKAGE_NAME), eq(TEST_UID), eq(mNotificationChannel));
assertEquals(1, mUiEventLogger.numLogs());
assertEquals(NotificationControlsEvent.NOTIFICATION_CONTROLS_OPEN.getId(),
mUiEventLogger.eventId(0));
} }
@Test @Test
@@ -1056,6 +1132,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
false false
@@ -1088,6 +1165,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
false false
@@ -1113,6 +1191,7 @@ public class NotificationInfoTest extends SysuiTestCase {
mEntry, mEntry,
null, null,
null, null,
mUiEventLogger,
true, true,
false, false,
false false