Loading services/core/java/com/android/server/GestureLauncherService.java +43 −0 Original line number Original line Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.os.SystemProperties; import android.os.Trace; import android.os.Trace; import android.os.UserHandle; import android.os.UserHandle; import android.provider.Settings; import android.provider.Settings; import android.telecom.TelecomManager; import android.util.MutableBoolean; import android.util.MutableBoolean; import android.util.Slog; import android.util.Slog; import android.view.KeyEvent; import android.view.KeyEvent; Loading Loading @@ -457,6 +458,8 @@ public class GestureLauncherService extends SystemService { } } } else if (launchPanic) { } else if (launchPanic) { Slog.i(TAG, "Panic gesture detected, launching panic."); Slog.i(TAG, "Panic gesture detected, launching panic."); launchPanic = handlePanicButtonGesture(); // TODO(b/160006048): Add logging } } mMetricsLogger.histogram("power_consecutive_short_tap_count", mMetricsLogger.histogram("power_consecutive_short_tap_count", mPowerButtonSlowConsecutiveTaps); mPowerButtonSlowConsecutiveTaps); Loading Loading @@ -501,6 +504,46 @@ public class GestureLauncherService extends SystemService { } } } } /** * @return true if panic ui was launched, false otherwise. */ @VisibleForTesting boolean handlePanicButtonGesture() { // TODO(b/160006048): This is the wrong way to launch panic ui. Rewrite this to go // through SysUI Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "GestureLauncher:handlePanicButtonGesture"); try { boolean userSetupComplete = Settings.Secure.getIntForUser(mContext.getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0; if (!userSetupComplete) { if (DBG) { Slog.d(TAG, String.format( "userSetupComplete = %s, ignoring panic gesture.", userSetupComplete)); } return false; } if (DBG) { Slog.d(TAG, String.format( "userSetupComplete = %s, performing panic gesture.", userSetupComplete)); } // TODO(b/160006048): Not all devices have telephony. Check system feature first. TelecomManager telecomManager = (TelecomManager) mContext.getSystemService( Context.TELECOM_SERVICE); mContext.startActivity(telecomManager.createLaunchEmergencyDialerIntent(null).addFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_SINGLE_TOP).putExtra( "com.android.phone.EmergencyDialer.extra.ENTRY_TYPE", 2)); // 2 maps to power button, forcing into fast emergency dialer experience. return true; } finally { Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } } private final BroadcastReceiver mUserReceiver = new BroadcastReceiver() { private final BroadcastReceiver mUserReceiver = new BroadcastReceiver() { @Override @Override public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { Loading services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java +19 −0 Original line number Original line Diff line number Diff line Loading @@ -28,11 +28,13 @@ import static org.mockito.Mockito.when; import android.app.StatusBarManager; import android.app.StatusBarManager; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.content.res.Resources; import android.os.Looper; import android.os.Looper; import android.os.UserHandle; import android.os.UserHandle; import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.Presubmit; import android.provider.Settings; import android.provider.Settings; import android.telecom.TelecomManager; import android.test.mock.MockContentResolver; import android.test.mock.MockContentResolver; import android.util.MutableBoolean; import android.util.MutableBoolean; import android.view.KeyEvent; import android.view.KeyEvent; Loading Loading @@ -80,6 +82,7 @@ public class GestureLauncherServiceTest { private @Mock Context mContext; private @Mock Context mContext; private @Mock Resources mResources; private @Mock Resources mResources; private @Mock StatusBarManagerInternal mStatusBarManagerInternal; private @Mock StatusBarManagerInternal mStatusBarManagerInternal; private @Mock TelecomManager mTelecomManager; private @Mock MetricsLogger mMetricsLogger; private @Mock MetricsLogger mMetricsLogger; private MockContentResolver mContentResolver; private MockContentResolver mContentResolver; private GestureLauncherService mGestureLauncherService; private GestureLauncherService mGestureLauncherService; Loading @@ -104,6 +107,8 @@ public class GestureLauncherServiceTest { mContentResolver = new MockContentResolver(mContext); mContentResolver = new MockContentResolver(mContext); mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); when(mContext.getContentResolver()).thenReturn(mContentResolver); when(mContext.getContentResolver()).thenReturn(mContentResolver); when(mContext.getSystemService(Context.TELECOM_SERVICE)).thenReturn(mTelecomManager); when(mTelecomManager.createLaunchEmergencyDialerIntent(null)).thenReturn(new Intent()); mGestureLauncherService = new GestureLauncherService(mContext, mMetricsLogger); mGestureLauncherService = new GestureLauncherService(mContext, mMetricsLogger); } } Loading Loading @@ -175,6 +180,13 @@ public class GestureLauncherServiceTest { verify(mStatusBarManagerInternal).onCameraLaunchGestureDetected(FAKE_SOURCE); verify(mStatusBarManagerInternal).onCameraLaunchGestureDetected(FAKE_SOURCE); } } @Test public void testHandlePanicGesture_userSetupComplete() { withUserSetupCompleteValue(true); assertTrue(mGestureLauncherService.handlePanicButtonGesture()); } @Test @Test public void testHandleCameraLaunchGesture_userSetupNotComplete() { public void testHandleCameraLaunchGesture_userSetupNotComplete() { withUserSetupCompleteValue(false); withUserSetupCompleteValue(false); Loading @@ -183,6 +195,13 @@ public class GestureLauncherServiceTest { assertFalse(mGestureLauncherService.handleCameraGesture(useWakeLock, FAKE_SOURCE)); assertFalse(mGestureLauncherService.handleCameraGesture(useWakeLock, FAKE_SOURCE)); } } @Test public void testHandlePanicGesture_userSetupNotComplete() { withUserSetupCompleteValue(false); assertFalse(mGestureLauncherService.handlePanicButtonGesture()); } @Test @Test public void testInterceptPowerKeyDown_firstPowerDownCameraPowerGestureOnInteractive() { public void testInterceptPowerKeyDown_firstPowerDownCameraPowerGestureOnInteractive() { withCameraDoubleTapPowerEnableConfigValue(true); withCameraDoubleTapPowerEnableConfigValue(true); Loading Loading
services/core/java/com/android/server/GestureLauncherService.java +43 −0 Original line number Original line Diff line number Diff line Loading @@ -38,6 +38,7 @@ import android.os.SystemProperties; import android.os.Trace; import android.os.Trace; import android.os.UserHandle; import android.os.UserHandle; import android.provider.Settings; import android.provider.Settings; import android.telecom.TelecomManager; import android.util.MutableBoolean; import android.util.MutableBoolean; import android.util.Slog; import android.util.Slog; import android.view.KeyEvent; import android.view.KeyEvent; Loading Loading @@ -457,6 +458,8 @@ public class GestureLauncherService extends SystemService { } } } else if (launchPanic) { } else if (launchPanic) { Slog.i(TAG, "Panic gesture detected, launching panic."); Slog.i(TAG, "Panic gesture detected, launching panic."); launchPanic = handlePanicButtonGesture(); // TODO(b/160006048): Add logging } } mMetricsLogger.histogram("power_consecutive_short_tap_count", mMetricsLogger.histogram("power_consecutive_short_tap_count", mPowerButtonSlowConsecutiveTaps); mPowerButtonSlowConsecutiveTaps); Loading Loading @@ -501,6 +504,46 @@ public class GestureLauncherService extends SystemService { } } } } /** * @return true if panic ui was launched, false otherwise. */ @VisibleForTesting boolean handlePanicButtonGesture() { // TODO(b/160006048): This is the wrong way to launch panic ui. Rewrite this to go // through SysUI Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "GestureLauncher:handlePanicButtonGesture"); try { boolean userSetupComplete = Settings.Secure.getIntForUser(mContext.getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0; if (!userSetupComplete) { if (DBG) { Slog.d(TAG, String.format( "userSetupComplete = %s, ignoring panic gesture.", userSetupComplete)); } return false; } if (DBG) { Slog.d(TAG, String.format( "userSetupComplete = %s, performing panic gesture.", userSetupComplete)); } // TODO(b/160006048): Not all devices have telephony. Check system feature first. TelecomManager telecomManager = (TelecomManager) mContext.getSystemService( Context.TELECOM_SERVICE); mContext.startActivity(telecomManager.createLaunchEmergencyDialerIntent(null).addFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_SINGLE_TOP).putExtra( "com.android.phone.EmergencyDialer.extra.ENTRY_TYPE", 2)); // 2 maps to power button, forcing into fast emergency dialer experience. return true; } finally { Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } } private final BroadcastReceiver mUserReceiver = new BroadcastReceiver() { private final BroadcastReceiver mUserReceiver = new BroadcastReceiver() { @Override @Override public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) { Loading
services/tests/servicestests/src/com/android/server/GestureLauncherServiceTest.java +19 −0 Original line number Original line Diff line number Diff line Loading @@ -28,11 +28,13 @@ import static org.mockito.Mockito.when; import android.app.StatusBarManager; import android.app.StatusBarManager; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.res.Resources; import android.content.res.Resources; import android.os.Looper; import android.os.Looper; import android.os.UserHandle; import android.os.UserHandle; import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.Presubmit; import android.provider.Settings; import android.provider.Settings; import android.telecom.TelecomManager; import android.test.mock.MockContentResolver; import android.test.mock.MockContentResolver; import android.util.MutableBoolean; import android.util.MutableBoolean; import android.view.KeyEvent; import android.view.KeyEvent; Loading Loading @@ -80,6 +82,7 @@ public class GestureLauncherServiceTest { private @Mock Context mContext; private @Mock Context mContext; private @Mock Resources mResources; private @Mock Resources mResources; private @Mock StatusBarManagerInternal mStatusBarManagerInternal; private @Mock StatusBarManagerInternal mStatusBarManagerInternal; private @Mock TelecomManager mTelecomManager; private @Mock MetricsLogger mMetricsLogger; private @Mock MetricsLogger mMetricsLogger; private MockContentResolver mContentResolver; private MockContentResolver mContentResolver; private GestureLauncherService mGestureLauncherService; private GestureLauncherService mGestureLauncherService; Loading @@ -104,6 +107,8 @@ public class GestureLauncherServiceTest { mContentResolver = new MockContentResolver(mContext); mContentResolver = new MockContentResolver(mContext); mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); when(mContext.getContentResolver()).thenReturn(mContentResolver); when(mContext.getContentResolver()).thenReturn(mContentResolver); when(mContext.getSystemService(Context.TELECOM_SERVICE)).thenReturn(mTelecomManager); when(mTelecomManager.createLaunchEmergencyDialerIntent(null)).thenReturn(new Intent()); mGestureLauncherService = new GestureLauncherService(mContext, mMetricsLogger); mGestureLauncherService = new GestureLauncherService(mContext, mMetricsLogger); } } Loading Loading @@ -175,6 +180,13 @@ public class GestureLauncherServiceTest { verify(mStatusBarManagerInternal).onCameraLaunchGestureDetected(FAKE_SOURCE); verify(mStatusBarManagerInternal).onCameraLaunchGestureDetected(FAKE_SOURCE); } } @Test public void testHandlePanicGesture_userSetupComplete() { withUserSetupCompleteValue(true); assertTrue(mGestureLauncherService.handlePanicButtonGesture()); } @Test @Test public void testHandleCameraLaunchGesture_userSetupNotComplete() { public void testHandleCameraLaunchGesture_userSetupNotComplete() { withUserSetupCompleteValue(false); withUserSetupCompleteValue(false); Loading @@ -183,6 +195,13 @@ public class GestureLauncherServiceTest { assertFalse(mGestureLauncherService.handleCameraGesture(useWakeLock, FAKE_SOURCE)); assertFalse(mGestureLauncherService.handleCameraGesture(useWakeLock, FAKE_SOURCE)); } } @Test public void testHandlePanicGesture_userSetupNotComplete() { withUserSetupCompleteValue(false); assertFalse(mGestureLauncherService.handlePanicButtonGesture()); } @Test @Test public void testInterceptPowerKeyDown_firstPowerDownCameraPowerGestureOnInteractive() { public void testInterceptPowerKeyDown_firstPowerDownCameraPowerGestureOnInteractive() { withCameraDoubleTapPowerEnableConfigValue(true); withCameraDoubleTapPowerEnableConfigValue(true); Loading