diff options
3 files changed, 85 insertions, 5 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java index 351ae8298ff4..67cf4812ba6b 100644 --- a/packages/SystemUI/src/com/android/systemui/Dependency.java +++ b/packages/SystemUI/src/com/android/systemui/Dependency.java @@ -28,6 +28,7 @@ import android.view.IWindowManager; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.UiEventLogger; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.util.Preconditions; import com.android.keyguard.KeyguardSecurityModel; @@ -358,6 +359,7 @@ public class Dependency { @Inject Lazy<SystemStatusAnimationScheduler> mSystemStatusAnimationSchedulerLazy; @Inject Lazy<PrivacyDotViewController> mPrivacyDotViewControllerLazy; @Inject Lazy<EdgeBackGestureHandler> mEdgeBackGestureHandler; + @Inject Lazy<UiEventLogger> mUiEventLogger; @Inject public Dependency() { @@ -571,6 +573,7 @@ public class Dependency { mSystemStatusAnimationSchedulerLazy::get); mProviders.put(PrivacyDotViewController.class, mPrivacyDotViewControllerLazy::get); mProviders.put(EdgeBackGestureHandler.class, mEdgeBackGestureHandler::get); + mProviders.put(UiEventLogger.class, mUiEventLogger::get); Dependency.setInstance(this); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java index d86ef3208f7e..c3b9c7bf89f2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java @@ -76,6 +76,8 @@ import androidx.annotation.NonNull; import com.android.internal.graphics.ColorUtils; import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.UiEvent; +import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.nano.MetricsProto; import com.android.internal.statusbar.IStatusBarService; import com.android.internal.util.ContrastColorUtil; @@ -111,6 +113,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene private final SendButtonTextWatcher mTextWatcher; private final TextView.OnEditorActionListener mEditorActionHandler; private final NotificationRemoteInputManager mRemoteInputManager; + private final UiEventLogger mUiEventLogger; private final List<OnFocusChangeListener> mEditTextFocusChangeListeners = new ArrayList<>(); private final List<OnSendRemoteInputListener> mOnSendListeners = new ArrayList<>(); private RemoteEditText mEditText; @@ -145,12 +148,35 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene private ImageView mDelete; private ImageView mDeleteBg; + /** + * Enum for logged notification remote input UiEvents. + */ + enum NotificationRemoteInputEvent implements UiEventLogger.UiEventEnum { + @UiEvent(doc = "Notification remote input view was displayed") + NOTIFICATION_REMOTE_INPUT_OPEN(795), + @UiEvent(doc = "Notification remote input view was closed") + NOTIFICATION_REMOTE_INPUT_CLOSE(796), + @UiEvent(doc = "User sent data through the notification remote input view") + NOTIFICATION_REMOTE_INPUT_SEND(797), + @UiEvent(doc = "Failed attempt to send data through the notification remote input view") + NOTIFICATION_REMOTE_INPUT_FAILURE(798); + + private final int mId; + NotificationRemoteInputEvent(int id) { + mId = id; + } + @Override public int getId() { + return mId; + } + } + public RemoteInputView(Context context, AttributeSet attrs) { super(context, attrs); mTextWatcher = new SendButtonTextWatcher(); mEditorActionHandler = new EditorActionHandler(); mRemoteInputQuickSettingsDisabler = Dependency.get(RemoteInputQuickSettingsDisabler.class); mRemoteInputManager = Dependency.get(NotificationRemoteInputManager.class); + mUiEventLogger = Dependency.get(UiEventLogger.class); mStatusBarManagerService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); TypedArray ta = getContext().getTheme().obtainStyledAttributes(new int[]{ @@ -389,12 +415,20 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_REMOTE_INPUT_SEND, mEntry.getSbn().getPackageName()); + mUiEventLogger.logWithInstanceId( + NotificationRemoteInputEvent.NOTIFICATION_REMOTE_INPUT_SEND, + mEntry.getSbn().getUid(), mEntry.getSbn().getPackageName(), + mEntry.getSbn().getInstanceId()); try { mPendingIntent.send(mContext, 0, intent); } catch (PendingIntent.CanceledException e) { Log.i(TAG, "Unable to send remote input result", e); MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_REMOTE_INPUT_FAIL, mEntry.getSbn().getPackageName()); + mUiEventLogger.logWithInstanceId( + NotificationRemoteInputEvent.NOTIFICATION_REMOTE_INPUT_FAILURE, + mEntry.getSbn().getUid(), mEntry.getSbn().getPackageName(), + mEntry.getSbn().getInstanceId()); } setAttachment(null); } @@ -433,7 +467,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene return true; } - private void onDefocus(boolean animate) { + private void onDefocus(boolean animate, boolean logClose) { mController.removeRemoteInput(mEntry, mToken); mEntry.remoteInputText = mEditText.getText(); @@ -465,8 +499,14 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mRemoteInputQuickSettingsDisabler.setRemoteInputActive(false); - MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_REMOTE_INPUT_CLOSE, - mEntry.getSbn().getPackageName()); + if (logClose) { + MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_REMOTE_INPUT_CLOSE, + mEntry.getSbn().getPackageName()); + mUiEventLogger.logWithInstanceId( + NotificationRemoteInputEvent.NOTIFICATION_REMOTE_INPUT_CLOSE, + mEntry.getSbn().getUid(), mEntry.getSbn().getPackageName(), + mEntry.getSbn().getInstanceId()); + } } @Override @@ -544,6 +584,10 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene public void focus() { MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_REMOTE_INPUT_OPEN, mEntry.getSbn().getPackageName()); + mUiEventLogger.logWithInstanceId( + NotificationRemoteInputEvent.NOTIFICATION_REMOTE_INPUT_OPEN, + mEntry.getSbn().getUid(), mEntry.getSbn().getPackageName(), + mEntry.getSbn().getInstanceId()); setVisibility(VISIBLE); if (mWrapper != null) { @@ -584,7 +628,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mProgressBar.setVisibility(INVISIBLE); mController.removeSpinning(mEntry.getKey(), mToken); updateSendButton(); - onDefocus(false /* animate */); + onDefocus(false /* animate */, false /* logClose */); mResetting = false; } @@ -878,7 +922,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene if (isFocusable() && isEnabled()) { setInnerFocusable(false); if (mRemoteInputView != null) { - mRemoteInputView.onDefocus(animate); + mRemoteInputView.onDefocus(animate, true /* logClose */); } mShowImeOnInputConnection = false; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java index a60baa54541e..dd8354dedafd 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java @@ -42,6 +42,8 @@ import android.widget.ImageButton; import androidx.test.filters.SmallTest; +import com.android.internal.logging.UiEventLogger; +import com.android.internal.logging.testing.UiEventLoggerFake; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; @@ -76,6 +78,7 @@ public class RemoteInputViewTest extends SysuiTestCase { @Mock private RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler; @Mock private LightBarController mLightBarController; private BlockingQueueIntentReceiver mReceiver; + private final UiEventLoggerFake mUiEventLoggerFake = new UiEventLoggerFake(); private RemoteInputView mView; @Before @@ -87,6 +90,7 @@ public class RemoteInputViewTest extends SysuiTestCase { mRemoteInputQuickSettingsDisabler); mDependency.injectTestDependency(LightBarController.class, mLightBarController); + mDependency.injectTestDependency(UiEventLogger.class, mUiEventLoggerFake); mDependency.injectMockDependency(NotificationRemoteInputManager.class); mReceiver = new BlockingQueueIntentReceiver(); @@ -205,4 +209,33 @@ public class RemoteInputViewTest extends SysuiTestCase { view.setVisibility(View.INVISIBLE); view.setVisibility(View.VISIBLE); } + + @Test + public void testUiEventLogging_openAndSend() throws Exception { + NotificationTestHelper helper = new NotificationTestHelper( + mContext, + mDependency, + TestableLooper.get(this)); + ExpandableNotificationRow row = helper.createRow(); + RemoteInputView view = RemoteInputView.inflate(mContext, null, row.getEntry(), mController); + + setTestPendingIntent(view); + + // Open view, send a reply + view.focus(); + EditText editText = view.findViewById(R.id.remote_input_text); + editText.setText(TEST_REPLY); + ImageButton sendButton = view.findViewById(R.id.remote_input_send); + sendButton.performClick(); + + mReceiver.waitForIntent(); + + assertEquals(2, mUiEventLoggerFake.numLogs()); + assertEquals( + RemoteInputView.NotificationRemoteInputEvent.NOTIFICATION_REMOTE_INPUT_OPEN.getId(), + mUiEventLoggerFake.eventId(0)); + assertEquals( + RemoteInputView.NotificationRemoteInputEvent.NOTIFICATION_REMOTE_INPUT_SEND.getId(), + mUiEventLoggerFake.eventId(1)); + } } |