Loading packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java +79 −4 Original line number Diff line number Diff line Loading @@ -52,6 +52,9 @@ import android.widget.ImageView; import com.android.internal.annotations.VisibleForTesting; 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.MetricsEvent; import com.android.systemui.Dependency; import com.android.systemui.R; Loading @@ -64,6 +67,7 @@ public class KeyButtonView extends ImageView implements ButtonInterface { private static final String TAG = KeyButtonView.class.getSimpleName(); private final boolean mPlaySounds; private final UiEventLogger mUiEventLogger; private int mContentDescriptionRes; private long mDownTime; private int mCode; Loading @@ -72,7 +76,7 @@ public class KeyButtonView extends ImageView implements ButtonInterface { private boolean mIsVertical; private AudioManager mAudioManager; private boolean mGestureAborted; private boolean mLongClicked; @VisibleForTesting boolean mLongClicked; private OnClickListener mOnClickListener; private final KeyButtonRipple mRipple; private final OverviewProxyService mOverviewProxyService; Loading @@ -82,6 +86,40 @@ public class KeyButtonView extends ImageView implements ButtonInterface { private float mDarkIntensity; private boolean mHasOvalBg = false; @VisibleForTesting public enum NavBarActionsEvent implements UiEventLogger.UiEventEnum { @UiEvent(doc = "The home button was pressed in the navigation bar.") NAVBAR_HOME_BUTTON_TAP(533), @UiEvent(doc = "The back button was pressed in the navigation bar.") NAVBAR_BACK_BUTTON_TAP(534), @UiEvent(doc = "The overview button was pressed in the navigation bar.") NAVBAR_OVERVIEW_BUTTON_TAP(535), @UiEvent(doc = "The home button was long-pressed in the navigation bar.") NAVBAR_HOME_BUTTON_LONGPRESS(536), @UiEvent(doc = "The back button was long-pressed in the navigation bar.") NAVBAR_BACK_BUTTON_LONGPRESS(537), @UiEvent(doc = "The overview button was long-pressed in the navigation bar.") NAVBAR_OVERVIEW_BUTTON_LONGPRESS(538), NONE(0); // an event we should not log private final int mId; NavBarActionsEvent(int id) { mId = id; } @Override public int getId() { return mId; } } private final Runnable mCheckLongPress = new Runnable() { public void run() { if (isPressed()) { Loading @@ -104,12 +142,14 @@ public class KeyButtonView extends ImageView implements ButtonInterface { } public KeyButtonView(Context context, AttributeSet attrs, int defStyle) { this(context, attrs, defStyle, InputManager.getInstance()); this(context, attrs, defStyle, InputManager.getInstance(), new UiEventLoggerImpl()); } @VisibleForTesting public KeyButtonView(Context context, AttributeSet attrs, int defStyle, InputManager manager) { public KeyButtonView(Context context, AttributeSet attrs, int defStyle, InputManager manager, UiEventLogger uiEventLogger) { super(context, attrs); mUiEventLogger = uiEventLogger; TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.KeyButtonView, defStyle, 0); Loading Loading @@ -326,13 +366,48 @@ public class KeyButtonView extends ImageView implements ButtonInterface { sendEvent(action, flags, SystemClock.uptimeMillis()); } private void logSomePresses(int action, int flags) { boolean longPressSet = (flags & KeyEvent.FLAG_LONG_PRESS) != 0; NavBarActionsEvent uiEvent = NavBarActionsEvent.NONE; if (action == MotionEvent.ACTION_UP && mLongClicked) { return; // don't log the up after a long press } if (action == MotionEvent.ACTION_DOWN && !longPressSet) { return; // don't log a down unless it is also the long press marker } if ((flags & KeyEvent.FLAG_CANCELED) != 0 || (flags & KeyEvent.FLAG_CANCELED_LONG_PRESS) != 0) { return; // don't log various cancels } switch(mCode) { case KeyEvent.KEYCODE_BACK: uiEvent = longPressSet ? NavBarActionsEvent.NAVBAR_BACK_BUTTON_LONGPRESS : NavBarActionsEvent.NAVBAR_BACK_BUTTON_TAP; break; case KeyEvent.KEYCODE_HOME: uiEvent = longPressSet ? NavBarActionsEvent.NAVBAR_HOME_BUTTON_LONGPRESS : NavBarActionsEvent.NAVBAR_HOME_BUTTON_TAP; break; case KeyEvent.KEYCODE_APP_SWITCH: uiEvent = longPressSet ? NavBarActionsEvent.NAVBAR_OVERVIEW_BUTTON_LONGPRESS : NavBarActionsEvent.NAVBAR_OVERVIEW_BUTTON_TAP; break; } if (uiEvent != NavBarActionsEvent.NONE) { mUiEventLogger.log(uiEvent); } } private void sendEvent(int action, int flags, long when) { mMetricsLogger.write(new LogMaker(MetricsEvent.ACTION_NAV_BUTTON_EVENT) .setType(MetricsEvent.TYPE_ACTION) .setSubtype(mCode) .addTaggedData(MetricsEvent.FIELD_NAV_ACTION, action) .addTaggedData(MetricsEvent.FIELD_FLAGS, flags)); // TODO(b/122195391): Added logs to make sure sysui is sending back button events logSomePresses(action, flags); if (mCode == KeyEvent.KEYCODE_BACK && flags != KeyEvent.FLAG_LONG_PRESS) { Log.i(TAG, "Back button event: " + KeyEvent.actionToString(action)); if (action == MotionEvent.ACTION_UP) { Loading packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyButtonViewTest.java +81 −42 Original line number Diff line number Diff line Loading @@ -14,21 +14,33 @@ package com.android.systemui.statusbar.policy; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_NAV_BUTTON_EVENT; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_FLAGS; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_NAV_ACTION; import static android.view.KeyEvent.ACTION_DOWN; import static android.view.KeyEvent.ACTION_UP; import static android.view.KeyEvent.FLAG_CANCELED; import static android.view.KeyEvent.FLAG_LONG_PRESS; import static android.view.KeyEvent.KEYCODE_0; import static android.view.KeyEvent.KEYCODE_APP_SWITCH; import static android.view.KeyEvent.KEYCODE_BACK; import static android.view.KeyEvent.KEYCODE_HOME; import static com.android.systemui.statusbar.policy.KeyButtonView.NavBarActionsEvent.NAVBAR_BACK_BUTTON_LONGPRESS; import static com.android.systemui.statusbar.policy.KeyButtonView.NavBarActionsEvent.NAVBAR_BACK_BUTTON_TAP; import static com.android.systemui.statusbar.policy.KeyButtonView.NavBarActionsEvent.NAVBAR_HOME_BUTTON_LONGPRESS; import static com.android.systemui.statusbar.policy.KeyButtonView.NavBarActionsEvent.NAVBAR_HOME_BUTTON_TAP; import static com.android.systemui.statusbar.policy.KeyButtonView.NavBarActionsEvent.NAVBAR_OVERVIEW_BUTTON_LONGPRESS; import static com.android.systemui.statusbar.policy.KeyButtonView.NavBarActionsEvent.NAVBAR_OVERVIEW_BUTTON_TAP; import static junit.framework.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.hardware.input.InputManager; import android.metrics.LogMaker; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; Loading @@ -37,7 +49,7 @@ import android.view.KeyEvent; import androidx.test.filters.SmallTest; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.UiEventLogger; import com.android.systemui.SysuiTestCase; import com.android.systemui.bubbles.BubbleController; import com.android.systemui.recents.OverviewProxyService; Loading @@ -46,12 +58,9 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; import org.mockito.Captor; import org.mockito.MockitoAnnotations; import java.util.Objects; @RunWith(AndroidTestingRunner.class) @RunWithLooper @SmallTest Loading @@ -60,6 +69,7 @@ public class KeyButtonViewTest extends SysuiTestCase { private KeyButtonView mKeyButtonView; private MetricsLogger mMetricsLogger; private BubbleController mBubbleController; private UiEventLogger mUiEventLogger; private InputManager mInputManager = mock(InputManager.class); @Captor private ArgumentCaptor<KeyEvent> mInputEventCaptor; Loading @@ -70,45 +80,74 @@ public class KeyButtonViewTest extends SysuiTestCase { mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class); mBubbleController = mDependency.injectMockDependency(BubbleController.class); mDependency.injectMockDependency(OverviewProxyService.class); mUiEventLogger = mDependency.injectMockDependency(UiEventLogger.class); TestableLooper.get(this).runWithLooper(() -> { mKeyButtonView = new KeyButtonView(mContext, null, 0, mInputManager); mKeyButtonView = new KeyButtonView(mContext, null, 0, mInputManager, mUiEventLogger); }); } @Test public void testMetrics() { int action = 42; int flags = 0x141; int code = KeyEvent.KEYCODE_ENTER; mKeyButtonView.setCode(code); mKeyButtonView.sendEvent(action, flags); public void testLogBackPress() { checkmetrics(KEYCODE_BACK, ACTION_UP, 0, NAVBAR_BACK_BUTTON_TAP); } @Test public void testLogOverviewPress() { checkmetrics(KEYCODE_APP_SWITCH, ACTION_UP, 0, NAVBAR_OVERVIEW_BUTTON_TAP); } @Test public void testLogHomePress() { checkmetrics(KEYCODE_HOME, ACTION_UP, 0, NAVBAR_HOME_BUTTON_TAP); } @Test public void testLogBackLongPressLog() { checkmetrics(KEYCODE_BACK, ACTION_DOWN, FLAG_LONG_PRESS, NAVBAR_BACK_BUTTON_LONGPRESS); } verify(mMetricsLogger).write(argThat(new ArgumentMatcher<LogMaker>() { public String mReason; @Override public boolean matches(LogMaker argument) { return checkField("category", argument.getCategory(), ACTION_NAV_BUTTON_EVENT) && checkField("type", argument.getType(), MetricsEvent.TYPE_ACTION) && checkField("subtype", argument.getSubtype(), code) && checkField("FIELD_FLAGS", argument.getTaggedData(FIELD_FLAGS), flags) && checkField("FIELD_NAV_ACTION", argument.getTaggedData(FIELD_NAV_ACTION), action); @Test public void testLogOverviewLongPress() { checkmetrics(KEYCODE_APP_SWITCH, ACTION_DOWN, FLAG_LONG_PRESS, NAVBAR_OVERVIEW_BUTTON_LONGPRESS); } @Test public void testLogHomeLongPress() { checkmetrics(KEYCODE_HOME, ACTION_DOWN, FLAG_LONG_PRESS, NAVBAR_HOME_BUTTON_LONGPRESS); } @Test public void testNoLogKeyDown() { checkmetrics(KEYCODE_BACK, ACTION_DOWN, 0, null); } private boolean checkField(String field, Object val, Object val2) { if (!Objects.equals(val, val2)) { mReason = "Expected " + field + " " + val2 + " but was " + val; return false; @Test public void testNoLogTapAfterLong() { mKeyButtonView.mLongClicked = true; checkmetrics(KEYCODE_BACK, ACTION_UP, 0, null); } return true; @Test public void testNoLogCanceled() { checkmetrics(KEYCODE_HOME, ACTION_UP, FLAG_CANCELED, null); } @Override public String toString() { return mReason; @Test public void testNoLogArbitraryKeys() { checkmetrics(KEYCODE_0, ACTION_UP, 0, null); } private void checkmetrics(int code, int action, int flag, KeyButtonView.NavBarActionsEvent expected) { mKeyButtonView.setCode(code); mKeyButtonView.sendEvent(action, flag); if (expected == null) { verify(mUiEventLogger, never()).log(any(KeyButtonView.NavBarActionsEvent.class)); } else { verify(mUiEventLogger, times(1)).log(expected); } })); } @Test Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java +79 −4 Original line number Diff line number Diff line Loading @@ -52,6 +52,9 @@ import android.widget.ImageView; import com.android.internal.annotations.VisibleForTesting; 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.MetricsEvent; import com.android.systemui.Dependency; import com.android.systemui.R; Loading @@ -64,6 +67,7 @@ public class KeyButtonView extends ImageView implements ButtonInterface { private static final String TAG = KeyButtonView.class.getSimpleName(); private final boolean mPlaySounds; private final UiEventLogger mUiEventLogger; private int mContentDescriptionRes; private long mDownTime; private int mCode; Loading @@ -72,7 +76,7 @@ public class KeyButtonView extends ImageView implements ButtonInterface { private boolean mIsVertical; private AudioManager mAudioManager; private boolean mGestureAborted; private boolean mLongClicked; @VisibleForTesting boolean mLongClicked; private OnClickListener mOnClickListener; private final KeyButtonRipple mRipple; private final OverviewProxyService mOverviewProxyService; Loading @@ -82,6 +86,40 @@ public class KeyButtonView extends ImageView implements ButtonInterface { private float mDarkIntensity; private boolean mHasOvalBg = false; @VisibleForTesting public enum NavBarActionsEvent implements UiEventLogger.UiEventEnum { @UiEvent(doc = "The home button was pressed in the navigation bar.") NAVBAR_HOME_BUTTON_TAP(533), @UiEvent(doc = "The back button was pressed in the navigation bar.") NAVBAR_BACK_BUTTON_TAP(534), @UiEvent(doc = "The overview button was pressed in the navigation bar.") NAVBAR_OVERVIEW_BUTTON_TAP(535), @UiEvent(doc = "The home button was long-pressed in the navigation bar.") NAVBAR_HOME_BUTTON_LONGPRESS(536), @UiEvent(doc = "The back button was long-pressed in the navigation bar.") NAVBAR_BACK_BUTTON_LONGPRESS(537), @UiEvent(doc = "The overview button was long-pressed in the navigation bar.") NAVBAR_OVERVIEW_BUTTON_LONGPRESS(538), NONE(0); // an event we should not log private final int mId; NavBarActionsEvent(int id) { mId = id; } @Override public int getId() { return mId; } } private final Runnable mCheckLongPress = new Runnable() { public void run() { if (isPressed()) { Loading @@ -104,12 +142,14 @@ public class KeyButtonView extends ImageView implements ButtonInterface { } public KeyButtonView(Context context, AttributeSet attrs, int defStyle) { this(context, attrs, defStyle, InputManager.getInstance()); this(context, attrs, defStyle, InputManager.getInstance(), new UiEventLoggerImpl()); } @VisibleForTesting public KeyButtonView(Context context, AttributeSet attrs, int defStyle, InputManager manager) { public KeyButtonView(Context context, AttributeSet attrs, int defStyle, InputManager manager, UiEventLogger uiEventLogger) { super(context, attrs); mUiEventLogger = uiEventLogger; TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.KeyButtonView, defStyle, 0); Loading Loading @@ -326,13 +366,48 @@ public class KeyButtonView extends ImageView implements ButtonInterface { sendEvent(action, flags, SystemClock.uptimeMillis()); } private void logSomePresses(int action, int flags) { boolean longPressSet = (flags & KeyEvent.FLAG_LONG_PRESS) != 0; NavBarActionsEvent uiEvent = NavBarActionsEvent.NONE; if (action == MotionEvent.ACTION_UP && mLongClicked) { return; // don't log the up after a long press } if (action == MotionEvent.ACTION_DOWN && !longPressSet) { return; // don't log a down unless it is also the long press marker } if ((flags & KeyEvent.FLAG_CANCELED) != 0 || (flags & KeyEvent.FLAG_CANCELED_LONG_PRESS) != 0) { return; // don't log various cancels } switch(mCode) { case KeyEvent.KEYCODE_BACK: uiEvent = longPressSet ? NavBarActionsEvent.NAVBAR_BACK_BUTTON_LONGPRESS : NavBarActionsEvent.NAVBAR_BACK_BUTTON_TAP; break; case KeyEvent.KEYCODE_HOME: uiEvent = longPressSet ? NavBarActionsEvent.NAVBAR_HOME_BUTTON_LONGPRESS : NavBarActionsEvent.NAVBAR_HOME_BUTTON_TAP; break; case KeyEvent.KEYCODE_APP_SWITCH: uiEvent = longPressSet ? NavBarActionsEvent.NAVBAR_OVERVIEW_BUTTON_LONGPRESS : NavBarActionsEvent.NAVBAR_OVERVIEW_BUTTON_TAP; break; } if (uiEvent != NavBarActionsEvent.NONE) { mUiEventLogger.log(uiEvent); } } private void sendEvent(int action, int flags, long when) { mMetricsLogger.write(new LogMaker(MetricsEvent.ACTION_NAV_BUTTON_EVENT) .setType(MetricsEvent.TYPE_ACTION) .setSubtype(mCode) .addTaggedData(MetricsEvent.FIELD_NAV_ACTION, action) .addTaggedData(MetricsEvent.FIELD_FLAGS, flags)); // TODO(b/122195391): Added logs to make sure sysui is sending back button events logSomePresses(action, flags); if (mCode == KeyEvent.KEYCODE_BACK && flags != KeyEvent.FLAG_LONG_PRESS) { Log.i(TAG, "Back button event: " + KeyEvent.actionToString(action)); if (action == MotionEvent.ACTION_UP) { Loading
packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyButtonViewTest.java +81 −42 Original line number Diff line number Diff line Loading @@ -14,21 +14,33 @@ package com.android.systemui.statusbar.policy; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_NAV_BUTTON_EVENT; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_FLAGS; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_NAV_ACTION; import static android.view.KeyEvent.ACTION_DOWN; import static android.view.KeyEvent.ACTION_UP; import static android.view.KeyEvent.FLAG_CANCELED; import static android.view.KeyEvent.FLAG_LONG_PRESS; import static android.view.KeyEvent.KEYCODE_0; import static android.view.KeyEvent.KEYCODE_APP_SWITCH; import static android.view.KeyEvent.KEYCODE_BACK; import static android.view.KeyEvent.KEYCODE_HOME; import static com.android.systemui.statusbar.policy.KeyButtonView.NavBarActionsEvent.NAVBAR_BACK_BUTTON_LONGPRESS; import static com.android.systemui.statusbar.policy.KeyButtonView.NavBarActionsEvent.NAVBAR_BACK_BUTTON_TAP; import static com.android.systemui.statusbar.policy.KeyButtonView.NavBarActionsEvent.NAVBAR_HOME_BUTTON_LONGPRESS; import static com.android.systemui.statusbar.policy.KeyButtonView.NavBarActionsEvent.NAVBAR_HOME_BUTTON_TAP; import static com.android.systemui.statusbar.policy.KeyButtonView.NavBarActionsEvent.NAVBAR_OVERVIEW_BUTTON_LONGPRESS; import static com.android.systemui.statusbar.policy.KeyButtonView.NavBarActionsEvent.NAVBAR_OVERVIEW_BUTTON_TAP; import static junit.framework.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.hardware.input.InputManager; import android.metrics.LogMaker; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; Loading @@ -37,7 +49,7 @@ import android.view.KeyEvent; import androidx.test.filters.SmallTest; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.logging.UiEventLogger; import com.android.systemui.SysuiTestCase; import com.android.systemui.bubbles.BubbleController; import com.android.systemui.recents.OverviewProxyService; Loading @@ -46,12 +58,9 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.ArgumentMatcher; import org.mockito.Captor; import org.mockito.MockitoAnnotations; import java.util.Objects; @RunWith(AndroidTestingRunner.class) @RunWithLooper @SmallTest Loading @@ -60,6 +69,7 @@ public class KeyButtonViewTest extends SysuiTestCase { private KeyButtonView mKeyButtonView; private MetricsLogger mMetricsLogger; private BubbleController mBubbleController; private UiEventLogger mUiEventLogger; private InputManager mInputManager = mock(InputManager.class); @Captor private ArgumentCaptor<KeyEvent> mInputEventCaptor; Loading @@ -70,45 +80,74 @@ public class KeyButtonViewTest extends SysuiTestCase { mMetricsLogger = mDependency.injectMockDependency(MetricsLogger.class); mBubbleController = mDependency.injectMockDependency(BubbleController.class); mDependency.injectMockDependency(OverviewProxyService.class); mUiEventLogger = mDependency.injectMockDependency(UiEventLogger.class); TestableLooper.get(this).runWithLooper(() -> { mKeyButtonView = new KeyButtonView(mContext, null, 0, mInputManager); mKeyButtonView = new KeyButtonView(mContext, null, 0, mInputManager, mUiEventLogger); }); } @Test public void testMetrics() { int action = 42; int flags = 0x141; int code = KeyEvent.KEYCODE_ENTER; mKeyButtonView.setCode(code); mKeyButtonView.sendEvent(action, flags); public void testLogBackPress() { checkmetrics(KEYCODE_BACK, ACTION_UP, 0, NAVBAR_BACK_BUTTON_TAP); } @Test public void testLogOverviewPress() { checkmetrics(KEYCODE_APP_SWITCH, ACTION_UP, 0, NAVBAR_OVERVIEW_BUTTON_TAP); } @Test public void testLogHomePress() { checkmetrics(KEYCODE_HOME, ACTION_UP, 0, NAVBAR_HOME_BUTTON_TAP); } @Test public void testLogBackLongPressLog() { checkmetrics(KEYCODE_BACK, ACTION_DOWN, FLAG_LONG_PRESS, NAVBAR_BACK_BUTTON_LONGPRESS); } verify(mMetricsLogger).write(argThat(new ArgumentMatcher<LogMaker>() { public String mReason; @Override public boolean matches(LogMaker argument) { return checkField("category", argument.getCategory(), ACTION_NAV_BUTTON_EVENT) && checkField("type", argument.getType(), MetricsEvent.TYPE_ACTION) && checkField("subtype", argument.getSubtype(), code) && checkField("FIELD_FLAGS", argument.getTaggedData(FIELD_FLAGS), flags) && checkField("FIELD_NAV_ACTION", argument.getTaggedData(FIELD_NAV_ACTION), action); @Test public void testLogOverviewLongPress() { checkmetrics(KEYCODE_APP_SWITCH, ACTION_DOWN, FLAG_LONG_PRESS, NAVBAR_OVERVIEW_BUTTON_LONGPRESS); } @Test public void testLogHomeLongPress() { checkmetrics(KEYCODE_HOME, ACTION_DOWN, FLAG_LONG_PRESS, NAVBAR_HOME_BUTTON_LONGPRESS); } @Test public void testNoLogKeyDown() { checkmetrics(KEYCODE_BACK, ACTION_DOWN, 0, null); } private boolean checkField(String field, Object val, Object val2) { if (!Objects.equals(val, val2)) { mReason = "Expected " + field + " " + val2 + " but was " + val; return false; @Test public void testNoLogTapAfterLong() { mKeyButtonView.mLongClicked = true; checkmetrics(KEYCODE_BACK, ACTION_UP, 0, null); } return true; @Test public void testNoLogCanceled() { checkmetrics(KEYCODE_HOME, ACTION_UP, FLAG_CANCELED, null); } @Override public String toString() { return mReason; @Test public void testNoLogArbitraryKeys() { checkmetrics(KEYCODE_0, ACTION_UP, 0, null); } private void checkmetrics(int code, int action, int flag, KeyButtonView.NavBarActionsEvent expected) { mKeyButtonView.setCode(code); mKeyButtonView.sendEvent(action, flag); if (expected == null) { verify(mUiEventLogger, never()).log(any(KeyButtonView.NavBarActionsEvent.class)); } else { verify(mUiEventLogger, times(1)).log(expected); } })); } @Test Loading