Loading packages/SystemUI/src/com/android/systemui/Dependency.java +3 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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() { Loading Loading @@ -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); } Loading packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +49 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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[]{ Loading Loading @@ -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); } Loading Loading @@ -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(); Loading Loading @@ -465,8 +499,14 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mRemoteInputQuickSettingsDisabler.setRemoteInputActive(false); 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 Loading Loading @@ -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) { Loading Loading @@ -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; } Loading Loading @@ -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; } Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java +33 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading @@ -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(); Loading Loading @@ -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)); } } Loading
packages/SystemUI/src/com/android/systemui/Dependency.java +3 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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() { Loading Loading @@ -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); } Loading
packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +49 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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[]{ Loading Loading @@ -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); } Loading Loading @@ -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(); Loading Loading @@ -465,8 +499,14 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene mRemoteInputQuickSettingsDisabler.setRemoteInputActive(false); 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 Loading Loading @@ -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) { Loading Loading @@ -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; } Loading Loading @@ -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; } Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputViewTest.java +33 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading @@ -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(); Loading Loading @@ -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)); } }