diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java index de96aaa1d9402..9d71489c8abe4 100644 --- a/services/core/java/com/android/server/GestureLauncherService.java +++ b/services/core/java/com/android/server/GestureLauncherService.java @@ -44,6 +44,9 @@ import android.view.KeyEvent; 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.server.LocalServices; import com.android.server.statusbar.StatusBarManagerInternal; @@ -129,16 +132,41 @@ public class GestureLauncherService extends SystemService { private boolean mCameraDoubleTapPowerEnabled; private long mLastPowerDown; private int mPowerButtonConsecutiveTaps; + private final UiEventLogger mUiEventLogger; + @VisibleForTesting + public enum GestureLauncherEvent implements UiEventLogger.UiEventEnum { + @UiEvent(doc = "The user lifted the device just the right way to launch the camera.") + GESTURE_CAMERA_LIFT(658), + + @UiEvent(doc = "The user wiggled the device just the right way to launch the camera.") + GESTURE_CAMERA_WIGGLE(659), + + @UiEvent(doc = "The user double-tapped power quickly enough to launch the camera.") + GESTURE_CAMERA_DOUBLE_TAP_POWER(660); + + private final int mId; + + GestureLauncherEvent(int id) { + mId = id; + } + + @Override + public int getId() { + return mId; + } + } public GestureLauncherService(Context context) { - this(context, new MetricsLogger()); + this(context, new MetricsLogger(), new UiEventLoggerImpl()); } @VisibleForTesting - GestureLauncherService(Context context, MetricsLogger metricsLogger) { + GestureLauncherService(Context context, MetricsLogger metricsLogger, + UiEventLogger uiEventLogger) { super(context); mContext = context; mMetricsLogger = metricsLogger; + mUiEventLogger = uiEventLogger; } public void onStart() { @@ -392,6 +420,7 @@ public class GestureLauncherService extends SystemService { if (launched) { mMetricsLogger.action(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE, (int) powerTapInterval); + mUiEventLogger.log(GestureLauncherEvent.GESTURE_CAMERA_DOUBLE_TAP_POWER); } } mMetricsLogger.histogram("power_consecutive_short_tap_count", mPowerButtonConsecutiveTaps); @@ -474,6 +503,7 @@ public class GestureLauncherService extends SystemService { if (handleCameraGesture(true /* useWakelock */, StatusBarManager.CAMERA_LAUNCH_SOURCE_WIGGLE)) { mMetricsLogger.action(MetricsEvent.ACTION_WIGGLE_CAMERA_GESTURE); + mUiEventLogger.log(GestureLauncherEvent.GESTURE_CAMERA_WIGGLE); trackCameraLaunchEvent(event); } return; @@ -558,6 +588,7 @@ public class GestureLauncherService extends SystemService { if (handleCameraGesture(true /* useWakelock */, StatusBarManager.CAMERA_LAUNCH_SOURCE_LIFT_TRIGGER)) { MetricsLogger.action(mContext, MetricsEvent.ACTION_CAMERA_LIFT_TRIGGER); + mUiEventLogger.log(GestureLauncherEvent.GESTURE_CAMERA_LIFT); } } else { if (DBG_CAMERA_LIFT) Slog.d(TAG, "Ignoring lift event"); diff --git a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java index 4fbc587c8a87a..0cdc2c9256567 100644 --- a/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java @@ -19,6 +19,7 @@ package com.android.server; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.never; @@ -34,6 +35,7 @@ import android.os.UserHandle; import android.platform.test.annotations.Presubmit; import android.provider.Settings; import android.test.mock.MockContentResolver; +import android.testing.TestableLooper; import android.util.MutableBoolean; import android.view.KeyEvent; @@ -42,6 +44,7 @@ import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.test.FakeSettingsProvider; import com.android.server.LocalServices; @@ -64,6 +67,7 @@ import java.util.List; @Presubmit @SmallTest @RunWith(AndroidJUnit4.class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) public class GestureLauncherServiceTest { private static final int FAKE_USER_ID = 1337; @@ -81,6 +85,7 @@ public class GestureLauncherServiceTest { private @Mock Resources mResources; private @Mock StatusBarManagerInternal mStatusBarManagerInternal; private @Mock MetricsLogger mMetricsLogger; + @Mock private UiEventLogger mUiEventLogger; private MockContentResolver mContentResolver; private GestureLauncherService mGestureLauncherService; @@ -105,7 +110,8 @@ public class GestureLauncherServiceTest { mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); when(mContext.getContentResolver()).thenReturn(mContentResolver); - mGestureLauncherService = new GestureLauncherService(mContext, mMetricsLogger); + mGestureLauncherService = new GestureLauncherService(mContext, mMetricsLogger, + mUiEventLogger); } @Test @@ -217,6 +223,7 @@ public class GestureLauncherServiceTest { verify(mMetricsLogger, never()) .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); + verify(mUiEventLogger, never()).log(any()); final ArgumentCaptor intervalCaptor = ArgumentCaptor.forClass(Integer.class); verify(mMetricsLogger, times(2)).histogram( @@ -261,6 +268,7 @@ public class GestureLauncherServiceTest { verify(mMetricsLogger, never()) .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); + verify(mUiEventLogger, never()).log(any()); final ArgumentCaptor intervalCaptor = ArgumentCaptor.forClass(Integer.class); verify(mMetricsLogger, times(2)).histogram( @@ -307,6 +315,7 @@ public class GestureLauncherServiceTest { verify(mMetricsLogger, never()) .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); + verify(mUiEventLogger, never()).log(any()); final ArgumentCaptor intervalCaptor = ArgumentCaptor.forClass(Integer.class); verify(mMetricsLogger, times(2)).histogram( @@ -355,6 +364,8 @@ public class GestureLauncherServiceTest { StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP); verify(mMetricsLogger) .action(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE, (int) interval); + verify(mUiEventLogger, times(1)) + .log(GestureLauncherService.GestureLauncherEvent.GESTURE_CAMERA_DOUBLE_TAP_POWER); final ArgumentCaptor intervalCaptor = ArgumentCaptor.forClass(Integer.class); verify(mMetricsLogger, times(2)).histogram( @@ -401,6 +412,7 @@ public class GestureLauncherServiceTest { verify(mMetricsLogger, never()) .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); + verify(mUiEventLogger, never()).log(any()); final ArgumentCaptor intervalCaptor = ArgumentCaptor.forClass(Integer.class); verify(mMetricsLogger, times(1)).histogram( @@ -445,6 +457,7 @@ public class GestureLauncherServiceTest { verify(mMetricsLogger, never()) .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); + verify(mUiEventLogger, never()).log(any()); final ArgumentCaptor intervalCaptor = ArgumentCaptor.forClass(Integer.class); verify(mMetricsLogger, times(2)).histogram( @@ -491,6 +504,7 @@ public class GestureLauncherServiceTest { verify(mMetricsLogger, never()) .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); + verify(mUiEventLogger, never()).log(any()); final ArgumentCaptor intervalCaptor = ArgumentCaptor.forClass(Integer.class); verify(mMetricsLogger, times(2)).histogram( @@ -537,6 +551,7 @@ public class GestureLauncherServiceTest { verify(mMetricsLogger, never()) .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); + verify(mUiEventLogger, never()).log(any()); final ArgumentCaptor intervalCaptor = ArgumentCaptor.forClass(Integer.class); verify(mMetricsLogger, times(2)).histogram( @@ -581,6 +596,7 @@ public class GestureLauncherServiceTest { verify(mMetricsLogger, never()) .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); + verify(mUiEventLogger, never()).log(any()); final ArgumentCaptor intervalCaptor = ArgumentCaptor.forClass(Integer.class); verify(mMetricsLogger, times(2)).histogram( @@ -624,6 +640,7 @@ public class GestureLauncherServiceTest { assertFalse(outLaunched.value); verify(mMetricsLogger, never()) .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); + verify(mUiEventLogger, never()).log(any()); final ArgumentCaptor intervalCaptor = ArgumentCaptor.forClass(Integer.class); verify(mMetricsLogger, times(2)).histogram( @@ -669,6 +686,7 @@ public class GestureLauncherServiceTest { assertFalse(outLaunched.value); verify(mMetricsLogger, never()) .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); + verify(mUiEventLogger, never()).log(any()); final ArgumentCaptor intervalCaptor = ArgumentCaptor.forClass(Integer.class); verify(mMetricsLogger, times(2)).histogram( @@ -716,6 +734,8 @@ public class GestureLauncherServiceTest { StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP); verify(mMetricsLogger) .action(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE, (int) interval); + verify(mUiEventLogger, times(1)) + .log(GestureLauncherService.GestureLauncherEvent.GESTURE_CAMERA_DOUBLE_TAP_POWER); final ArgumentCaptor intervalCaptor = ArgumentCaptor.forClass(Integer.class); verify(mMetricsLogger, times(2)).histogram( @@ -762,6 +782,7 @@ public class GestureLauncherServiceTest { verify(mMetricsLogger, never()) .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); + verify(mUiEventLogger, never()).log(any()); final ArgumentCaptor intervalCaptor = ArgumentCaptor.forClass(Integer.class); verify(mMetricsLogger, times(2)).histogram( @@ -806,6 +827,7 @@ public class GestureLauncherServiceTest { verify(mMetricsLogger, never()) .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); + verify(mUiEventLogger, never()).log(any()); final ArgumentCaptor intervalCaptor = ArgumentCaptor.forClass(Integer.class); verify(mMetricsLogger, times(2)).histogram( @@ -852,6 +874,7 @@ public class GestureLauncherServiceTest { verify(mMetricsLogger, never()) .action(eq(MetricsEvent.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE), anyInt()); + verify(mUiEventLogger, never()).log(any()); final ArgumentCaptor intervalCaptor = ArgumentCaptor.forClass(Integer.class); verify(mMetricsLogger, times(2)).histogram(