Merge "Add UiEvent logging for NOTIFICATION_REMOTE_INPUT_(OPEN|CLOSE|SEND|FAILURE)." into sc-dev
This commit is contained in:
@@ -28,6 +28,7 @@ import android.view.IWindowManager;
|
|||||||
|
|
||||||
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.statusbar.IStatusBarService;
|
import com.android.internal.statusbar.IStatusBarService;
|
||||||
import com.android.internal.util.Preconditions;
|
import com.android.internal.util.Preconditions;
|
||||||
import com.android.keyguard.KeyguardSecurityModel;
|
import com.android.keyguard.KeyguardSecurityModel;
|
||||||
@@ -358,6 +359,7 @@ public class Dependency {
|
|||||||
@Inject Lazy<SystemStatusAnimationScheduler> mSystemStatusAnimationSchedulerLazy;
|
@Inject Lazy<SystemStatusAnimationScheduler> mSystemStatusAnimationSchedulerLazy;
|
||||||
@Inject Lazy<PrivacyDotViewController> mPrivacyDotViewControllerLazy;
|
@Inject Lazy<PrivacyDotViewController> mPrivacyDotViewControllerLazy;
|
||||||
@Inject Lazy<EdgeBackGestureHandler> mEdgeBackGestureHandler;
|
@Inject Lazy<EdgeBackGestureHandler> mEdgeBackGestureHandler;
|
||||||
|
@Inject Lazy<UiEventLogger> mUiEventLogger;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public Dependency() {
|
public Dependency() {
|
||||||
@@ -571,6 +573,7 @@ public class Dependency {
|
|||||||
mSystemStatusAnimationSchedulerLazy::get);
|
mSystemStatusAnimationSchedulerLazy::get);
|
||||||
mProviders.put(PrivacyDotViewController.class, mPrivacyDotViewControllerLazy::get);
|
mProviders.put(PrivacyDotViewController.class, mPrivacyDotViewControllerLazy::get);
|
||||||
mProviders.put(EdgeBackGestureHandler.class, mEdgeBackGestureHandler::get);
|
mProviders.put(EdgeBackGestureHandler.class, mEdgeBackGestureHandler::get);
|
||||||
|
mProviders.put(UiEventLogger.class, mUiEventLogger::get);
|
||||||
|
|
||||||
Dependency.setInstance(this);
|
Dependency.setInstance(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ import androidx.annotation.NonNull;
|
|||||||
|
|
||||||
import com.android.internal.graphics.ColorUtils;
|
import com.android.internal.graphics.ColorUtils;
|
||||||
import com.android.internal.logging.MetricsLogger;
|
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.logging.nano.MetricsProto;
|
||||||
import com.android.internal.statusbar.IStatusBarService;
|
import com.android.internal.statusbar.IStatusBarService;
|
||||||
import com.android.internal.util.ContrastColorUtil;
|
import com.android.internal.util.ContrastColorUtil;
|
||||||
@@ -111,6 +113,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
|||||||
private final SendButtonTextWatcher mTextWatcher;
|
private final SendButtonTextWatcher mTextWatcher;
|
||||||
private final TextView.OnEditorActionListener mEditorActionHandler;
|
private final TextView.OnEditorActionListener mEditorActionHandler;
|
||||||
private final NotificationRemoteInputManager mRemoteInputManager;
|
private final NotificationRemoteInputManager mRemoteInputManager;
|
||||||
|
private final UiEventLogger mUiEventLogger;
|
||||||
private final List<OnFocusChangeListener> mEditTextFocusChangeListeners = new ArrayList<>();
|
private final List<OnFocusChangeListener> mEditTextFocusChangeListeners = new ArrayList<>();
|
||||||
private final List<OnSendRemoteInputListener> mOnSendListeners = new ArrayList<>();
|
private final List<OnSendRemoteInputListener> mOnSendListeners = new ArrayList<>();
|
||||||
private RemoteEditText mEditText;
|
private RemoteEditText mEditText;
|
||||||
@@ -145,12 +148,35 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
|||||||
private ImageView mDelete;
|
private ImageView mDelete;
|
||||||
private ImageView mDeleteBg;
|
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) {
|
public RemoteInputView(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
mTextWatcher = new SendButtonTextWatcher();
|
mTextWatcher = new SendButtonTextWatcher();
|
||||||
mEditorActionHandler = new EditorActionHandler();
|
mEditorActionHandler = new EditorActionHandler();
|
||||||
mRemoteInputQuickSettingsDisabler = Dependency.get(RemoteInputQuickSettingsDisabler.class);
|
mRemoteInputQuickSettingsDisabler = Dependency.get(RemoteInputQuickSettingsDisabler.class);
|
||||||
mRemoteInputManager = Dependency.get(NotificationRemoteInputManager.class);
|
mRemoteInputManager = Dependency.get(NotificationRemoteInputManager.class);
|
||||||
|
mUiEventLogger = Dependency.get(UiEventLogger.class);
|
||||||
mStatusBarManagerService = IStatusBarService.Stub.asInterface(
|
mStatusBarManagerService = IStatusBarService.Stub.asInterface(
|
||||||
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
|
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
|
||||||
TypedArray ta = getContext().getTheme().obtainStyledAttributes(new int[]{
|
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,
|
MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_REMOTE_INPUT_SEND,
|
||||||
mEntry.getSbn().getPackageName());
|
mEntry.getSbn().getPackageName());
|
||||||
|
mUiEventLogger.logWithInstanceId(
|
||||||
|
NotificationRemoteInputEvent.NOTIFICATION_REMOTE_INPUT_SEND,
|
||||||
|
mEntry.getSbn().getUid(), mEntry.getSbn().getPackageName(),
|
||||||
|
mEntry.getSbn().getInstanceId());
|
||||||
try {
|
try {
|
||||||
mPendingIntent.send(mContext, 0, intent);
|
mPendingIntent.send(mContext, 0, intent);
|
||||||
} catch (PendingIntent.CanceledException e) {
|
} catch (PendingIntent.CanceledException e) {
|
||||||
Log.i(TAG, "Unable to send remote input result", e);
|
Log.i(TAG, "Unable to send remote input result", e);
|
||||||
MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_REMOTE_INPUT_FAIL,
|
MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_REMOTE_INPUT_FAIL,
|
||||||
mEntry.getSbn().getPackageName());
|
mEntry.getSbn().getPackageName());
|
||||||
|
mUiEventLogger.logWithInstanceId(
|
||||||
|
NotificationRemoteInputEvent.NOTIFICATION_REMOTE_INPUT_FAILURE,
|
||||||
|
mEntry.getSbn().getUid(), mEntry.getSbn().getPackageName(),
|
||||||
|
mEntry.getSbn().getInstanceId());
|
||||||
}
|
}
|
||||||
setAttachment(null);
|
setAttachment(null);
|
||||||
}
|
}
|
||||||
@@ -433,7 +467,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onDefocus(boolean animate) {
|
private void onDefocus(boolean animate, boolean logClose) {
|
||||||
mController.removeRemoteInput(mEntry, mToken);
|
mController.removeRemoteInput(mEntry, mToken);
|
||||||
mEntry.remoteInputText = mEditText.getText();
|
mEntry.remoteInputText = mEditText.getText();
|
||||||
|
|
||||||
@@ -465,8 +499,14 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
|||||||
|
|
||||||
mRemoteInputQuickSettingsDisabler.setRemoteInputActive(false);
|
mRemoteInputQuickSettingsDisabler.setRemoteInputActive(false);
|
||||||
|
|
||||||
|
if (logClose) {
|
||||||
MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_REMOTE_INPUT_CLOSE,
|
MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_REMOTE_INPUT_CLOSE,
|
||||||
mEntry.getSbn().getPackageName());
|
mEntry.getSbn().getPackageName());
|
||||||
|
mUiEventLogger.logWithInstanceId(
|
||||||
|
NotificationRemoteInputEvent.NOTIFICATION_REMOTE_INPUT_CLOSE,
|
||||||
|
mEntry.getSbn().getUid(), mEntry.getSbn().getPackageName(),
|
||||||
|
mEntry.getSbn().getInstanceId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -544,6 +584,10 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
|||||||
public void focus() {
|
public void focus() {
|
||||||
MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_REMOTE_INPUT_OPEN,
|
MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_REMOTE_INPUT_OPEN,
|
||||||
mEntry.getSbn().getPackageName());
|
mEntry.getSbn().getPackageName());
|
||||||
|
mUiEventLogger.logWithInstanceId(
|
||||||
|
NotificationRemoteInputEvent.NOTIFICATION_REMOTE_INPUT_OPEN,
|
||||||
|
mEntry.getSbn().getUid(), mEntry.getSbn().getPackageName(),
|
||||||
|
mEntry.getSbn().getInstanceId());
|
||||||
|
|
||||||
setVisibility(VISIBLE);
|
setVisibility(VISIBLE);
|
||||||
if (mWrapper != null) {
|
if (mWrapper != null) {
|
||||||
@@ -584,7 +628,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
|||||||
mProgressBar.setVisibility(INVISIBLE);
|
mProgressBar.setVisibility(INVISIBLE);
|
||||||
mController.removeSpinning(mEntry.getKey(), mToken);
|
mController.removeSpinning(mEntry.getKey(), mToken);
|
||||||
updateSendButton();
|
updateSendButton();
|
||||||
onDefocus(false /* animate */);
|
onDefocus(false /* animate */, false /* logClose */);
|
||||||
|
|
||||||
mResetting = false;
|
mResetting = false;
|
||||||
}
|
}
|
||||||
@@ -878,7 +922,7 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
|
|||||||
if (isFocusable() && isEnabled()) {
|
if (isFocusable() && isEnabled()) {
|
||||||
setInnerFocusable(false);
|
setInnerFocusable(false);
|
||||||
if (mRemoteInputView != null) {
|
if (mRemoteInputView != null) {
|
||||||
mRemoteInputView.onDefocus(animate);
|
mRemoteInputView.onDefocus(animate, true /* logClose */);
|
||||||
}
|
}
|
||||||
mShowImeOnInputConnection = false;
|
mShowImeOnInputConnection = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ import android.widget.ImageButton;
|
|||||||
|
|
||||||
import androidx.test.filters.SmallTest;
|
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.Dependency;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
@@ -76,6 +78,7 @@ public class RemoteInputViewTest extends SysuiTestCase {
|
|||||||
@Mock private RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler;
|
@Mock private RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler;
|
||||||
@Mock private LightBarController mLightBarController;
|
@Mock private LightBarController mLightBarController;
|
||||||
private BlockingQueueIntentReceiver mReceiver;
|
private BlockingQueueIntentReceiver mReceiver;
|
||||||
|
private final UiEventLoggerFake mUiEventLoggerFake = new UiEventLoggerFake();
|
||||||
private RemoteInputView mView;
|
private RemoteInputView mView;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -87,6 +90,7 @@ public class RemoteInputViewTest extends SysuiTestCase {
|
|||||||
mRemoteInputQuickSettingsDisabler);
|
mRemoteInputQuickSettingsDisabler);
|
||||||
mDependency.injectTestDependency(LightBarController.class,
|
mDependency.injectTestDependency(LightBarController.class,
|
||||||
mLightBarController);
|
mLightBarController);
|
||||||
|
mDependency.injectTestDependency(UiEventLogger.class, mUiEventLoggerFake);
|
||||||
mDependency.injectMockDependency(NotificationRemoteInputManager.class);
|
mDependency.injectMockDependency(NotificationRemoteInputManager.class);
|
||||||
|
|
||||||
mReceiver = new BlockingQueueIntentReceiver();
|
mReceiver = new BlockingQueueIntentReceiver();
|
||||||
@@ -205,4 +209,33 @@ public class RemoteInputViewTest extends SysuiTestCase {
|
|||||||
view.setVisibility(View.INVISIBLE);
|
view.setVisibility(View.INVISIBLE);
|
||||||
view.setVisibility(View.VISIBLE);
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user