Loading packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java +191 −0 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.ActivityOptions; import android.app.AlertDialog; import android.app.AlertDialog; import android.app.PendingIntent; import android.app.SearchManager; import android.app.SearchManager; import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManager; import android.appwidget.AppWidgetHost; import android.appwidget.AppWidgetHost; Loading @@ -40,6 +41,7 @@ import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.Rect; import android.media.RemoteControlClient; import android.media.RemoteControlClient; import android.os.Bundle; import android.os.Looper; import android.os.Looper; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import android.os.Parcelable; Loading @@ -47,6 +49,9 @@ import android.os.SystemClock; import android.os.UserHandle; import android.os.UserHandle; import android.os.UserManager; import android.os.UserManager; import android.provider.Settings; import android.provider.Settings; import android.speech.hotword.HotwordRecognitionListener; import android.speech.hotword.HotwordRecognizer; import android.telephony.TelephonyManager; import android.util.AttributeSet; import android.util.AttributeSet; import android.util.Log; import android.util.Log; import android.util.Slog; import android.util.Slog; Loading @@ -63,6 +68,11 @@ import java.util.List; public class KeyguardHostView extends KeyguardViewBase { public class KeyguardHostView extends KeyguardViewBase { private static final String TAG = "KeyguardHostView"; private static final String TAG = "KeyguardHostView"; // Don't enable hotword on limited-memory devices. private static final boolean ENABLE_HOTWORD = !ActivityManager.isLowRamDeviceStatic(); // Indicates if hotword is enabled, should it also be available on secure keyguard(s). private static final boolean ENABLE_HOTWORD_SECURE = false; // Transport control states. // Transport control states. static final int TRANSPORT_GONE = 0; static final int TRANSPORT_GONE = 0; static final int TRANSPORT_INVISIBLE = 1; static final int TRANSPORT_INVISIBLE = 1; Loading @@ -77,6 +87,13 @@ public class KeyguardHostView extends KeyguardViewBase { // Found in KeyguardAppWidgetPickActivity.java // Found in KeyguardAppWidgetPickActivity.java static final int APPWIDGET_HOST_ID = 0x4B455947; static final int APPWIDGET_HOST_ID = 0x4B455947; // TODO: Fix this to be non-static. // We need to be careful here to make stopRecognition calls on the same instance // that started it. Since KeyguardHostView is a view, it keeps getting // recreated every now and then, and unless we figure out a better way, // this needs to be a static field. private static HotwordRecognizer sHotwordClient; private final int MAX_WIDGETS = 5; private final int MAX_WIDGETS = 5; private AppWidgetHost mAppWidgetHost; private AppWidgetHost mAppWidgetHost; Loading Loading @@ -117,6 +134,8 @@ public class KeyguardHostView extends KeyguardViewBase { private KeyguardMultiUserSelectorView mKeyguardMultiUserSelectorView; private KeyguardMultiUserSelectorView mKeyguardMultiUserSelectorView; private boolean mIsScreenOn; protected int mClientGeneration; protected int mClientGeneration; protected boolean mShowSecurityWhenReturn; protected boolean mShowSecurityWhenReturn; Loading Loading @@ -198,6 +217,11 @@ public class KeyguardHostView extends KeyguardViewBase { if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0) { if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0) { Log.v(TAG, "Keyguard secure camera disabled by DPM"); Log.v(TAG, "Keyguard secure camera disabled by DPM"); } } // Create Hotword recognizer, for the first time. if (ENABLE_HOTWORD && sHotwordClient == null) { sHotwordClient = HotwordRecognizer.createHotwordRecognizer(getContext()); } } } private void getInitialTransportState() { private void getInitialTransportState() { Loading Loading @@ -295,6 +319,21 @@ public class KeyguardHostView extends KeyguardViewBase { } } } } } } @Override public void onPhoneStateChanged(int phoneState) { // We need to stop hotword detection when a call state is not idle anymore. if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection) && TelephonyManager.CALL_STATE_IDLE != phoneState) { if (DEBUG) Log.d(TAG, "Stopping due to call state not being idle"); maybeStopHotwordDetector(); } } @Override public void onUserSwitching(int userId) { if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) { maybeStopHotwordDetector(); } } }; }; private static final boolean isMusicPlaying(int playbackState) { private static final boolean isMusicPlaying(int playbackState) { Loading Loading @@ -778,6 +817,9 @@ public class KeyguardHostView extends KeyguardViewBase { // If the alternate unlock was suppressed, it can now be safely // If the alternate unlock was suppressed, it can now be safely // enabled because the user has left keyguard. // enabled because the user has left keyguard. KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true); KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true); if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)){ maybeStopHotwordDetector(); } // If there's a pending runnable because the user interacted with a widget // If there's a pending runnable because the user interacted with a widget // and we're leaving keyguard, then run it. // and we're leaving keyguard, then run it. Loading Loading @@ -942,6 +984,9 @@ public class KeyguardHostView extends KeyguardViewBase { // Emulate Activity life cycle // Emulate Activity life cycle if (oldView != null) { if (oldView != null) { if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) { maybeStopHotwordDetector(); } oldView.onPause(); oldView.onPause(); oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view } } Loading Loading @@ -982,6 +1027,7 @@ public class KeyguardHostView extends KeyguardViewBase { @Override @Override public void onScreenTurnedOn() { public void onScreenTurnedOn() { if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode())); if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode())); mIsScreenOn = true; showPrimarySecurityScreen(false); showPrimarySecurityScreen(false); getSecurityView(mCurrentSecuritySelection).onResume(KeyguardSecurityView.SCREEN_ON); getSecurityView(mCurrentSecuritySelection).onResume(KeyguardSecurityView.SCREEN_ON); Loading @@ -993,6 +1039,12 @@ public class KeyguardHostView extends KeyguardViewBase { if (mViewStateManager != null) { if (mViewStateManager != null) { mViewStateManager.showUsabilityHints(); mViewStateManager.showUsabilityHints(); } } // Start hotword detection on insecure Keyguard. if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) { maybeStartHotwordDetector(); } requestFocus(); requestFocus(); } } Loading @@ -1000,6 +1052,7 @@ public class KeyguardHostView extends KeyguardViewBase { public void onScreenTurnedOff() { public void onScreenTurnedOff() { if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s", if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s", Integer.toHexString(hashCode()), SystemClock.uptimeMillis())); Integer.toHexString(hashCode()), SystemClock.uptimeMillis())); mIsScreenOn = false; // Once the screen turns off, we no longer consider this to be first boot and we want the // Once the screen turns off, we no longer consider this to be first boot and we want the // biometric unlock to start next time keyguard is shown. // biometric unlock to start next time keyguard is shown. KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true); KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true); Loading @@ -1013,6 +1066,12 @@ public class KeyguardHostView extends KeyguardViewBase { if (cameraPage != null) { if (cameraPage != null) { cameraPage.onScreenTurnedOff(); cameraPage.onScreenTurnedOff(); } } // Stop hotword detection on insecure Keyguard. if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) { maybeStopHotwordDetector(); } clearFocus(); clearFocus(); } } Loading Loading @@ -1097,6 +1156,9 @@ public class KeyguardHostView extends KeyguardViewBase { new CameraWidgetFrame.Callbacks() { new CameraWidgetFrame.Callbacks() { @Override @Override public void onLaunchingCamera() { public void onLaunchingCamera() { if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) { maybeStopHotwordDetector(); } setSliderHandleAlpha(0); setSliderHandleAlpha(0); } } Loading Loading @@ -1626,6 +1688,9 @@ public class KeyguardHostView extends KeyguardViewBase { } } public void showAssistant() { public void showAssistant() { if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) { maybeStopHotwordDetector(); } final Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) final Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) .getAssistIntent(mContext, true, UserHandle.USER_CURRENT); .getAssistIntent(mContext, true, UserHandle.USER_CURRENT); Loading @@ -1640,4 +1705,130 @@ public class KeyguardHostView extends KeyguardViewBase { mActivityLauncher.launchActivityWithAnimation( mActivityLauncher.launchActivityWithAnimation( intent, false, opts.toBundle(), null, null); intent, false, opts.toBundle(), null, null); } } /** * Start the hotword detector if: * <li> ENABLE_HOTWORD is true and * <li> Hotword detection is not already running and * <li> TelephonyManager is in CALL_STATE_IDLE * <li> and Screen is turned on. */ private void maybeStartHotwordDetector() { if (!ENABLE_HOTWORD) return; if (sHotwordClient != null) { if (DEBUG) Log.d(TAG, "maybeStartHotwordDetector()"); // Don't start hotword detection if the screen is off. if (!mIsScreenOn) { if (DEBUG) Log.d(TAG, "screen was off, not starting"); return; } KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(getContext()); if (monitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE) { if (DEBUG) Log.d(TAG, "Call underway, not starting"); return; } try { sHotwordClient.startRecognition(mHotwordCallback); } catch(Exception ex) { // Don't allow hotword errors to make the keyguard unusable Log.e(TAG, "Failed to start hotword recognition", ex); sHotwordClient = null; } } } /** * Stop hotword detector if: * <li> ENABLE_HOTWORD is true * <li> and hotword is running. */ private void maybeStopHotwordDetector() { if (!ENABLE_HOTWORD) return; if (sHotwordClient != null) { if (DEBUG) Log.d(TAG, "maybeStopHotwordDetector()"); try { sHotwordClient.stopRecognition(); } catch(Exception ex) { // Don't allow hotword errors to make the keyguard unusable Log.e(TAG, "Failed to start hotword recognition", ex); } finally { sHotwordClient = null; } } } private final HotwordRecognitionListener mHotwordCallback = new HotwordRecognitionListener() { private static final String TAG = "HotwordRecognitionListener"; public void onHotwordRecognitionStarted() { if (DEBUG) Log.d(TAG, "onHotwordRecognitionStarted()"); } public void onHotwordRecognitionStopped() { if (DEBUG) Log.d(TAG, "onHotwordRecognitionStopped()"); } public void onHotwordEvent(int eventType, Bundle eventBundle) { if (DEBUG) Log.d(TAG, "onHotwordEvent: " + eventType); if (eventType == HotwordRecognizer.EVENT_TYPE_STATE_CHANGED) { if (eventBundle != null && eventBundle.containsKey(HotwordRecognizer.PROMPT_TEXT)) { new KeyguardMessageArea.Helper( (View) getSecurityView(mCurrentSecuritySelection)) .setMessage(eventBundle.getString(HotwordRecognizer.PROMPT_TEXT),true); } } } public void onHotwordRecognized(final PendingIntent intent) { if (DEBUG) Log.d(TAG, "onHotwordRecognized"); maybeStopHotwordDetector(); if (SecurityMode.None == mCurrentSecuritySelection) { if (intent != null) { try { intent.send(); } catch (PendingIntent.CanceledException e) { Log.w(TAG, "Failed to launch PendingIntent. Encountered CanceledException"); } } mCallback.userActivity(0); mCallback.dismiss(false); } else if (ENABLE_HOTWORD_SECURE && mLockPatternUtils.isSecure()) { setOnDismissAction(new OnDismissAction() { @Override public boolean onDismiss() { if (intent != null) { try { intent.send(); } catch (PendingIntent.CanceledException e) { Log.w(TAG, "Failed to launch PendingIntent." + "Encountered CanceledException"); } } return false; } }); getSecurityView(mCurrentSecuritySelection).showBouncer(0); } } public void onHotwordError(int errorCode) { if (DEBUG) Log.d(TAG, "onHotwordError: " + errorCode); // TODO: Inspect the error code and handle the errors appropriately // instead of blindly failing. maybeStopHotwordDetector(); } }; private boolean shouldRunHotwordInSecurityMode(SecurityMode mode) { // Enable hotoword for insecure keyguard, // and for pattern unlock if ENABLE_HOTWORD_SECURE is true. return ENABLE_HOTWORD && ((SecurityMode.None == mode) || (ENABLE_HOTWORD_SECURE && mLockPatternUtils.isSecure())); } } } packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java +0 −133 Original line number Original line Diff line number Diff line Loading @@ -28,8 +28,6 @@ import android.os.Bundle; import android.os.PowerManager; import android.os.PowerManager; import android.os.UserHandle; import android.os.UserHandle; import android.provider.Settings; import android.provider.Settings; import android.speech.hotword.HotwordRecognitionListener; import android.speech.hotword.HotwordRecognizer; import android.telephony.TelephonyManager; import android.telephony.TelephonyManager; import android.util.AttributeSet; import android.util.AttributeSet; import android.util.Log; import android.util.Log; Loading @@ -48,12 +46,6 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri private static final String ASSIST_ICON_METADATA_NAME = private static final String ASSIST_ICON_METADATA_NAME = "com.android.systemui.action_assist_icon"; "com.android.systemui.action_assist_icon"; // Don't enable hotword on limited-memory devices. private static final boolean ENABLE_HOTWORD = !ActivityManager.isLowRamDeviceStatic(); // TODO: Fix this to be non-static. private static HotwordRecognizer sHotwordClient; private KeyguardSecurityCallback mCallback; private KeyguardSecurityCallback mCallback; private GlowPadView mGlowPadView; private GlowPadView mGlowPadView; private ObjectAnimator mAnim; private ObjectAnimator mAnim; Loading @@ -69,7 +61,6 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri public void onTrigger(View v, int target) { public void onTrigger(View v, int target) { final int resId = mGlowPadView.getResourceIdForTarget(target); final int resId = mGlowPadView.getResourceIdForTarget(target); maybeStopHotwordDetector(); switch (resId) { switch (resId) { case R.drawable.ic_action_assist_generic: case R.drawable.ic_action_assist_generic: Loading Loading @@ -129,22 +120,6 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri public void onSimStateChanged(State simState) { public void onSimStateChanged(State simState) { updateTargets(); updateTargets(); } } @Override public void onPhoneStateChanged(int phoneState) { if (ENABLE_HOTWORD) { // We need to stop hotword detection when a call state is not idle anymore. if (phoneState != TelephonyManager.CALL_STATE_IDLE) { if (DEBUG) Log.d(TAG, "Stopping due to call state not being idle"); maybeStopHotwordDetector(); } } } @Override public void onUserSwitching(int userId) { maybeStopHotwordDetector(); } }; }; private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() { private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() { Loading Loading @@ -183,9 +158,6 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this); mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this); View bouncerFrameView = findViewById(R.id.keyguard_selector_view_frame); View bouncerFrameView = findViewById(R.id.keyguard_selector_view_frame); mBouncerFrame = bouncerFrameView.getBackground(); mBouncerFrame = bouncerFrameView.getBackground(); if (ENABLE_HOTWORD && sHotwordClient == null) { sHotwordClient = HotwordRecognizer.createHotwordRecognizer(getContext()); } } } public void setCarrierArea(View carrierArea) { public void setCarrierArea(View carrierArea) { Loading Loading @@ -289,20 +261,11 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri @Override @Override public void onPause() { public void onPause() { KeyguardUpdateMonitor.getInstance(getContext()).removeCallback(mUpdateCallback); KeyguardUpdateMonitor.getInstance(getContext()).removeCallback(mUpdateCallback); maybeStopHotwordDetector(); } } @Override @Override public void onResume(int reason) { public void onResume(int reason) { KeyguardUpdateMonitor.getInstance(getContext()).registerCallback(mUpdateCallback); KeyguardUpdateMonitor.getInstance(getContext()).registerCallback(mUpdateCallback); // TODO: Figure out if there's a better way to do it. // onResume gets called multiple times, however we are interested in // the reason to figure out when to start/stop hotword detection. if (reason == SCREEN_ON) { if (!KeyguardUpdateMonitor.getInstance(getContext()).isSwitchingUser()) { maybeStartHotwordDetector(); } } } } @Override @Override Loading @@ -323,100 +286,4 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri KeyguardSecurityViewHelper. KeyguardSecurityViewHelper. hideBouncer(mSecurityMessageDisplay, mFadeView, mBouncerFrame, duration); hideBouncer(mSecurityMessageDisplay, mFadeView, mBouncerFrame, duration); } } /** * Start the hotword detector if: * <li> FLAG_HOTWORD is true and * <li> Hotword detection is not already running and * <li> TelephonyManager is in CALL_STATE_IDLE * * If this method is called when the screen is off, * it attempts to stop hotword detection if it's running. */ private void maybeStartHotwordDetector() { if (ENABLE_HOTWORD && sHotwordClient != null) { if (DEBUG) Log.d(TAG, "maybeStartHotwordDetector()"); // Don't start it if the screen is off or not showing PowerManager powerManager = (PowerManager) getContext().getSystemService( Context.POWER_SERVICE); if (!powerManager.isScreenOn()) { if (DEBUG) Log.d(TAG, "screen was off, not starting"); return; } KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(getContext()); if (monitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE) { if (DEBUG) Log.d(TAG, "Call underway, not starting"); return; } try { sHotwordClient.startRecognition(mHotwordCallback); } catch(Exception ex) { // Don't allow hotword errors to make the keyguard unusable Log.e(TAG, "Failed to start hotword recognition", ex); sHotwordClient = null; } } } /** * Stop hotword detector if HOTWORDING_ENABLED is true. */ private void maybeStopHotwordDetector() { if (ENABLE_HOTWORD && sHotwordClient != null) { if (DEBUG) Log.d(TAG, "maybeStopHotwordDetector()"); try { sHotwordClient.stopRecognition(); } catch(Exception ex) { // Don't allow hotword errors to make the keyguard unusable Log.e(TAG, "Failed to start hotword recognition", ex); } finally { sHotwordClient = null; } } } private final HotwordRecognitionListener mHotwordCallback = new HotwordRecognitionListener() { private static final String TAG = "HotwordRecognitionListener"; public void onHotwordRecognitionStarted() { if (DEBUG) Log.d(TAG, "onHotwordRecognitionStarted()"); } public void onHotwordRecognitionStopped() { if (DEBUG) Log.d(TAG, "onHotwordRecognitionStopped()"); } public void onHotwordEvent(int eventType, Bundle eventBundle) { if (DEBUG) Log.d(TAG, "onHotwordEvent: " + eventType); if (eventType == HotwordRecognizer.EVENT_TYPE_STATE_CHANGED) { if (eventBundle != null && eventBundle.containsKey(HotwordRecognizer.PROMPT_TEXT)) { mSecurityMessageDisplay.setMessage( eventBundle.getString(HotwordRecognizer.PROMPT_TEXT), true); } } } public void onHotwordRecognized(PendingIntent intent) { if (DEBUG) Log.d(TAG, "onHotwordRecognized"); maybeStopHotwordDetector(); if (intent != null) { try { intent.send(); } catch (PendingIntent.CanceledException e) { Log.w(TAG, "Failed to launch PendingIntent. Encountered CanceledException"); } } mCallback.userActivity(0); mCallback.dismiss(false); } public void onHotwordError(int errorCode) { if (DEBUG) Log.d(TAG, "onHotwordError: " + errorCode); // TODO: Inspect the error code and handle the errors appropriately // instead of blindly failing. maybeStopHotwordDetector(); } }; } } Loading
packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java +191 −0 Original line number Original line Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityManager; import android.app.ActivityOptions; import android.app.ActivityOptions; import android.app.AlertDialog; import android.app.AlertDialog; import android.app.PendingIntent; import android.app.SearchManager; import android.app.SearchManager; import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManager; import android.appwidget.AppWidgetHost; import android.appwidget.AppWidgetHost; Loading @@ -40,6 +41,7 @@ import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.Rect; import android.media.RemoteControlClient; import android.media.RemoteControlClient; import android.os.Bundle; import android.os.Looper; import android.os.Looper; import android.os.Parcel; import android.os.Parcel; import android.os.Parcelable; import android.os.Parcelable; Loading @@ -47,6 +49,9 @@ import android.os.SystemClock; import android.os.UserHandle; import android.os.UserHandle; import android.os.UserManager; import android.os.UserManager; import android.provider.Settings; import android.provider.Settings; import android.speech.hotword.HotwordRecognitionListener; import android.speech.hotword.HotwordRecognizer; import android.telephony.TelephonyManager; import android.util.AttributeSet; import android.util.AttributeSet; import android.util.Log; import android.util.Log; import android.util.Slog; import android.util.Slog; Loading @@ -63,6 +68,11 @@ import java.util.List; public class KeyguardHostView extends KeyguardViewBase { public class KeyguardHostView extends KeyguardViewBase { private static final String TAG = "KeyguardHostView"; private static final String TAG = "KeyguardHostView"; // Don't enable hotword on limited-memory devices. private static final boolean ENABLE_HOTWORD = !ActivityManager.isLowRamDeviceStatic(); // Indicates if hotword is enabled, should it also be available on secure keyguard(s). private static final boolean ENABLE_HOTWORD_SECURE = false; // Transport control states. // Transport control states. static final int TRANSPORT_GONE = 0; static final int TRANSPORT_GONE = 0; static final int TRANSPORT_INVISIBLE = 1; static final int TRANSPORT_INVISIBLE = 1; Loading @@ -77,6 +87,13 @@ public class KeyguardHostView extends KeyguardViewBase { // Found in KeyguardAppWidgetPickActivity.java // Found in KeyguardAppWidgetPickActivity.java static final int APPWIDGET_HOST_ID = 0x4B455947; static final int APPWIDGET_HOST_ID = 0x4B455947; // TODO: Fix this to be non-static. // We need to be careful here to make stopRecognition calls on the same instance // that started it. Since KeyguardHostView is a view, it keeps getting // recreated every now and then, and unless we figure out a better way, // this needs to be a static field. private static HotwordRecognizer sHotwordClient; private final int MAX_WIDGETS = 5; private final int MAX_WIDGETS = 5; private AppWidgetHost mAppWidgetHost; private AppWidgetHost mAppWidgetHost; Loading Loading @@ -117,6 +134,8 @@ public class KeyguardHostView extends KeyguardViewBase { private KeyguardMultiUserSelectorView mKeyguardMultiUserSelectorView; private KeyguardMultiUserSelectorView mKeyguardMultiUserSelectorView; private boolean mIsScreenOn; protected int mClientGeneration; protected int mClientGeneration; protected boolean mShowSecurityWhenReturn; protected boolean mShowSecurityWhenReturn; Loading Loading @@ -198,6 +217,11 @@ public class KeyguardHostView extends KeyguardViewBase { if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0) { if ((mDisabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) != 0) { Log.v(TAG, "Keyguard secure camera disabled by DPM"); Log.v(TAG, "Keyguard secure camera disabled by DPM"); } } // Create Hotword recognizer, for the first time. if (ENABLE_HOTWORD && sHotwordClient == null) { sHotwordClient = HotwordRecognizer.createHotwordRecognizer(getContext()); } } } private void getInitialTransportState() { private void getInitialTransportState() { Loading Loading @@ -295,6 +319,21 @@ public class KeyguardHostView extends KeyguardViewBase { } } } } } } @Override public void onPhoneStateChanged(int phoneState) { // We need to stop hotword detection when a call state is not idle anymore. if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection) && TelephonyManager.CALL_STATE_IDLE != phoneState) { if (DEBUG) Log.d(TAG, "Stopping due to call state not being idle"); maybeStopHotwordDetector(); } } @Override public void onUserSwitching(int userId) { if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) { maybeStopHotwordDetector(); } } }; }; private static final boolean isMusicPlaying(int playbackState) { private static final boolean isMusicPlaying(int playbackState) { Loading Loading @@ -778,6 +817,9 @@ public class KeyguardHostView extends KeyguardViewBase { // If the alternate unlock was suppressed, it can now be safely // If the alternate unlock was suppressed, it can now be safely // enabled because the user has left keyguard. // enabled because the user has left keyguard. KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true); KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true); if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)){ maybeStopHotwordDetector(); } // If there's a pending runnable because the user interacted with a widget // If there's a pending runnable because the user interacted with a widget // and we're leaving keyguard, then run it. // and we're leaving keyguard, then run it. Loading Loading @@ -942,6 +984,9 @@ public class KeyguardHostView extends KeyguardViewBase { // Emulate Activity life cycle // Emulate Activity life cycle if (oldView != null) { if (oldView != null) { if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) { maybeStopHotwordDetector(); } oldView.onPause(); oldView.onPause(); oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view oldView.setKeyguardCallback(mNullCallback); // ignore requests from old view } } Loading Loading @@ -982,6 +1027,7 @@ public class KeyguardHostView extends KeyguardViewBase { @Override @Override public void onScreenTurnedOn() { public void onScreenTurnedOn() { if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode())); if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode())); mIsScreenOn = true; showPrimarySecurityScreen(false); showPrimarySecurityScreen(false); getSecurityView(mCurrentSecuritySelection).onResume(KeyguardSecurityView.SCREEN_ON); getSecurityView(mCurrentSecuritySelection).onResume(KeyguardSecurityView.SCREEN_ON); Loading @@ -993,6 +1039,12 @@ public class KeyguardHostView extends KeyguardViewBase { if (mViewStateManager != null) { if (mViewStateManager != null) { mViewStateManager.showUsabilityHints(); mViewStateManager.showUsabilityHints(); } } // Start hotword detection on insecure Keyguard. if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) { maybeStartHotwordDetector(); } requestFocus(); requestFocus(); } } Loading @@ -1000,6 +1052,7 @@ public class KeyguardHostView extends KeyguardViewBase { public void onScreenTurnedOff() { public void onScreenTurnedOff() { if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s", if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s", Integer.toHexString(hashCode()), SystemClock.uptimeMillis())); Integer.toHexString(hashCode()), SystemClock.uptimeMillis())); mIsScreenOn = false; // Once the screen turns off, we no longer consider this to be first boot and we want the // Once the screen turns off, we no longer consider this to be first boot and we want the // biometric unlock to start next time keyguard is shown. // biometric unlock to start next time keyguard is shown. KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true); KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true); Loading @@ -1013,6 +1066,12 @@ public class KeyguardHostView extends KeyguardViewBase { if (cameraPage != null) { if (cameraPage != null) { cameraPage.onScreenTurnedOff(); cameraPage.onScreenTurnedOff(); } } // Stop hotword detection on insecure Keyguard. if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) { maybeStopHotwordDetector(); } clearFocus(); clearFocus(); } } Loading Loading @@ -1097,6 +1156,9 @@ public class KeyguardHostView extends KeyguardViewBase { new CameraWidgetFrame.Callbacks() { new CameraWidgetFrame.Callbacks() { @Override @Override public void onLaunchingCamera() { public void onLaunchingCamera() { if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) { maybeStopHotwordDetector(); } setSliderHandleAlpha(0); setSliderHandleAlpha(0); } } Loading Loading @@ -1626,6 +1688,9 @@ public class KeyguardHostView extends KeyguardViewBase { } } public void showAssistant() { public void showAssistant() { if (shouldRunHotwordInSecurityMode(mCurrentSecuritySelection)) { maybeStopHotwordDetector(); } final Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) final Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE)) .getAssistIntent(mContext, true, UserHandle.USER_CURRENT); .getAssistIntent(mContext, true, UserHandle.USER_CURRENT); Loading @@ -1640,4 +1705,130 @@ public class KeyguardHostView extends KeyguardViewBase { mActivityLauncher.launchActivityWithAnimation( mActivityLauncher.launchActivityWithAnimation( intent, false, opts.toBundle(), null, null); intent, false, opts.toBundle(), null, null); } } /** * Start the hotword detector if: * <li> ENABLE_HOTWORD is true and * <li> Hotword detection is not already running and * <li> TelephonyManager is in CALL_STATE_IDLE * <li> and Screen is turned on. */ private void maybeStartHotwordDetector() { if (!ENABLE_HOTWORD) return; if (sHotwordClient != null) { if (DEBUG) Log.d(TAG, "maybeStartHotwordDetector()"); // Don't start hotword detection if the screen is off. if (!mIsScreenOn) { if (DEBUG) Log.d(TAG, "screen was off, not starting"); return; } KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(getContext()); if (monitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE) { if (DEBUG) Log.d(TAG, "Call underway, not starting"); return; } try { sHotwordClient.startRecognition(mHotwordCallback); } catch(Exception ex) { // Don't allow hotword errors to make the keyguard unusable Log.e(TAG, "Failed to start hotword recognition", ex); sHotwordClient = null; } } } /** * Stop hotword detector if: * <li> ENABLE_HOTWORD is true * <li> and hotword is running. */ private void maybeStopHotwordDetector() { if (!ENABLE_HOTWORD) return; if (sHotwordClient != null) { if (DEBUG) Log.d(TAG, "maybeStopHotwordDetector()"); try { sHotwordClient.stopRecognition(); } catch(Exception ex) { // Don't allow hotword errors to make the keyguard unusable Log.e(TAG, "Failed to start hotword recognition", ex); } finally { sHotwordClient = null; } } } private final HotwordRecognitionListener mHotwordCallback = new HotwordRecognitionListener() { private static final String TAG = "HotwordRecognitionListener"; public void onHotwordRecognitionStarted() { if (DEBUG) Log.d(TAG, "onHotwordRecognitionStarted()"); } public void onHotwordRecognitionStopped() { if (DEBUG) Log.d(TAG, "onHotwordRecognitionStopped()"); } public void onHotwordEvent(int eventType, Bundle eventBundle) { if (DEBUG) Log.d(TAG, "onHotwordEvent: " + eventType); if (eventType == HotwordRecognizer.EVENT_TYPE_STATE_CHANGED) { if (eventBundle != null && eventBundle.containsKey(HotwordRecognizer.PROMPT_TEXT)) { new KeyguardMessageArea.Helper( (View) getSecurityView(mCurrentSecuritySelection)) .setMessage(eventBundle.getString(HotwordRecognizer.PROMPT_TEXT),true); } } } public void onHotwordRecognized(final PendingIntent intent) { if (DEBUG) Log.d(TAG, "onHotwordRecognized"); maybeStopHotwordDetector(); if (SecurityMode.None == mCurrentSecuritySelection) { if (intent != null) { try { intent.send(); } catch (PendingIntent.CanceledException e) { Log.w(TAG, "Failed to launch PendingIntent. Encountered CanceledException"); } } mCallback.userActivity(0); mCallback.dismiss(false); } else if (ENABLE_HOTWORD_SECURE && mLockPatternUtils.isSecure()) { setOnDismissAction(new OnDismissAction() { @Override public boolean onDismiss() { if (intent != null) { try { intent.send(); } catch (PendingIntent.CanceledException e) { Log.w(TAG, "Failed to launch PendingIntent." + "Encountered CanceledException"); } } return false; } }); getSecurityView(mCurrentSecuritySelection).showBouncer(0); } } public void onHotwordError(int errorCode) { if (DEBUG) Log.d(TAG, "onHotwordError: " + errorCode); // TODO: Inspect the error code and handle the errors appropriately // instead of blindly failing. maybeStopHotwordDetector(); } }; private boolean shouldRunHotwordInSecurityMode(SecurityMode mode) { // Enable hotoword for insecure keyguard, // and for pattern unlock if ENABLE_HOTWORD_SECURE is true. return ENABLE_HOTWORD && ((SecurityMode.None == mode) || (ENABLE_HOTWORD_SECURE && mLockPatternUtils.isSecure())); } } }
packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java +0 −133 Original line number Original line Diff line number Diff line Loading @@ -28,8 +28,6 @@ import android.os.Bundle; import android.os.PowerManager; import android.os.PowerManager; import android.os.UserHandle; import android.os.UserHandle; import android.provider.Settings; import android.provider.Settings; import android.speech.hotword.HotwordRecognitionListener; import android.speech.hotword.HotwordRecognizer; import android.telephony.TelephonyManager; import android.telephony.TelephonyManager; import android.util.AttributeSet; import android.util.AttributeSet; import android.util.Log; import android.util.Log; Loading @@ -48,12 +46,6 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri private static final String ASSIST_ICON_METADATA_NAME = private static final String ASSIST_ICON_METADATA_NAME = "com.android.systemui.action_assist_icon"; "com.android.systemui.action_assist_icon"; // Don't enable hotword on limited-memory devices. private static final boolean ENABLE_HOTWORD = !ActivityManager.isLowRamDeviceStatic(); // TODO: Fix this to be non-static. private static HotwordRecognizer sHotwordClient; private KeyguardSecurityCallback mCallback; private KeyguardSecurityCallback mCallback; private GlowPadView mGlowPadView; private GlowPadView mGlowPadView; private ObjectAnimator mAnim; private ObjectAnimator mAnim; Loading @@ -69,7 +61,6 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri public void onTrigger(View v, int target) { public void onTrigger(View v, int target) { final int resId = mGlowPadView.getResourceIdForTarget(target); final int resId = mGlowPadView.getResourceIdForTarget(target); maybeStopHotwordDetector(); switch (resId) { switch (resId) { case R.drawable.ic_action_assist_generic: case R.drawable.ic_action_assist_generic: Loading Loading @@ -129,22 +120,6 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri public void onSimStateChanged(State simState) { public void onSimStateChanged(State simState) { updateTargets(); updateTargets(); } } @Override public void onPhoneStateChanged(int phoneState) { if (ENABLE_HOTWORD) { // We need to stop hotword detection when a call state is not idle anymore. if (phoneState != TelephonyManager.CALL_STATE_IDLE) { if (DEBUG) Log.d(TAG, "Stopping due to call state not being idle"); maybeStopHotwordDetector(); } } } @Override public void onUserSwitching(int userId) { maybeStopHotwordDetector(); } }; }; private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() { private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() { Loading Loading @@ -183,9 +158,6 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this); mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this); View bouncerFrameView = findViewById(R.id.keyguard_selector_view_frame); View bouncerFrameView = findViewById(R.id.keyguard_selector_view_frame); mBouncerFrame = bouncerFrameView.getBackground(); mBouncerFrame = bouncerFrameView.getBackground(); if (ENABLE_HOTWORD && sHotwordClient == null) { sHotwordClient = HotwordRecognizer.createHotwordRecognizer(getContext()); } } } public void setCarrierArea(View carrierArea) { public void setCarrierArea(View carrierArea) { Loading Loading @@ -289,20 +261,11 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri @Override @Override public void onPause() { public void onPause() { KeyguardUpdateMonitor.getInstance(getContext()).removeCallback(mUpdateCallback); KeyguardUpdateMonitor.getInstance(getContext()).removeCallback(mUpdateCallback); maybeStopHotwordDetector(); } } @Override @Override public void onResume(int reason) { public void onResume(int reason) { KeyguardUpdateMonitor.getInstance(getContext()).registerCallback(mUpdateCallback); KeyguardUpdateMonitor.getInstance(getContext()).registerCallback(mUpdateCallback); // TODO: Figure out if there's a better way to do it. // onResume gets called multiple times, however we are interested in // the reason to figure out when to start/stop hotword detection. if (reason == SCREEN_ON) { if (!KeyguardUpdateMonitor.getInstance(getContext()).isSwitchingUser()) { maybeStartHotwordDetector(); } } } } @Override @Override Loading @@ -323,100 +286,4 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri KeyguardSecurityViewHelper. KeyguardSecurityViewHelper. hideBouncer(mSecurityMessageDisplay, mFadeView, mBouncerFrame, duration); hideBouncer(mSecurityMessageDisplay, mFadeView, mBouncerFrame, duration); } } /** * Start the hotword detector if: * <li> FLAG_HOTWORD is true and * <li> Hotword detection is not already running and * <li> TelephonyManager is in CALL_STATE_IDLE * * If this method is called when the screen is off, * it attempts to stop hotword detection if it's running. */ private void maybeStartHotwordDetector() { if (ENABLE_HOTWORD && sHotwordClient != null) { if (DEBUG) Log.d(TAG, "maybeStartHotwordDetector()"); // Don't start it if the screen is off or not showing PowerManager powerManager = (PowerManager) getContext().getSystemService( Context.POWER_SERVICE); if (!powerManager.isScreenOn()) { if (DEBUG) Log.d(TAG, "screen was off, not starting"); return; } KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(getContext()); if (monitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE) { if (DEBUG) Log.d(TAG, "Call underway, not starting"); return; } try { sHotwordClient.startRecognition(mHotwordCallback); } catch(Exception ex) { // Don't allow hotword errors to make the keyguard unusable Log.e(TAG, "Failed to start hotword recognition", ex); sHotwordClient = null; } } } /** * Stop hotword detector if HOTWORDING_ENABLED is true. */ private void maybeStopHotwordDetector() { if (ENABLE_HOTWORD && sHotwordClient != null) { if (DEBUG) Log.d(TAG, "maybeStopHotwordDetector()"); try { sHotwordClient.stopRecognition(); } catch(Exception ex) { // Don't allow hotword errors to make the keyguard unusable Log.e(TAG, "Failed to start hotword recognition", ex); } finally { sHotwordClient = null; } } } private final HotwordRecognitionListener mHotwordCallback = new HotwordRecognitionListener() { private static final String TAG = "HotwordRecognitionListener"; public void onHotwordRecognitionStarted() { if (DEBUG) Log.d(TAG, "onHotwordRecognitionStarted()"); } public void onHotwordRecognitionStopped() { if (DEBUG) Log.d(TAG, "onHotwordRecognitionStopped()"); } public void onHotwordEvent(int eventType, Bundle eventBundle) { if (DEBUG) Log.d(TAG, "onHotwordEvent: " + eventType); if (eventType == HotwordRecognizer.EVENT_TYPE_STATE_CHANGED) { if (eventBundle != null && eventBundle.containsKey(HotwordRecognizer.PROMPT_TEXT)) { mSecurityMessageDisplay.setMessage( eventBundle.getString(HotwordRecognizer.PROMPT_TEXT), true); } } } public void onHotwordRecognized(PendingIntent intent) { if (DEBUG) Log.d(TAG, "onHotwordRecognized"); maybeStopHotwordDetector(); if (intent != null) { try { intent.send(); } catch (PendingIntent.CanceledException e) { Log.w(TAG, "Failed to launch PendingIntent. Encountered CanceledException"); } } mCallback.userActivity(0); mCallback.dismiss(false); } public void onHotwordError(int errorCode) { if (DEBUG) Log.d(TAG, "onHotwordError: " + errorCode); // TODO: Inspect the error code and handle the errors appropriately // instead of blindly failing. maybeStopHotwordDetector(); } }; } }