blob: d8e5b8ac613ced32c6b645ea1d64eec6cc149bf0 [file] [log] [blame]
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jim Miller5ecd8112013-01-09 18:50:26 -080017package com.android.keyguard;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080018
Jim Millerd6523da2012-10-21 16:47:02 -070019import android.app.Activity;
Jim Miller3eb49712014-01-28 18:22:42 -080020import android.app.ActivityManager;
21import android.app.ActivityOptions;
22import android.app.SearchManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080023import android.content.Context;
Jim Miller3eb49712014-01-28 18:22:42 -080024import android.content.Intent;
25import android.content.res.Resources;
26import android.graphics.Canvas;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080027import android.media.AudioManager;
Jean-Michel Trivic6802222012-04-30 11:15:03 -070028import android.media.IAudioService;
Jim Miller5e612cf2014-02-03 17:57:23 -080029import android.os.Bundle;
Jean-Michel Trivic6802222012-04-30 11:15:03 -070030import android.os.RemoteException;
31import android.os.ServiceManager;
Jim Miller3eb49712014-01-28 18:22:42 -080032import android.os.SystemClock;
33import android.os.UserHandle;
The Android Open Source Projectbc8d29f2009-03-05 20:00:44 -080034import android.telephony.TelephonyManager;
Karl Rosaenad297342009-03-24 18:55:19 -070035import android.util.AttributeSet;
Jean-Michel Trivic6802222012-04-30 11:15:03 -070036import android.util.Log;
37import android.util.Slog;
Jim Miller838906b2012-10-19 18:41:25 -070038import android.view.KeyEvent;
Jim Miller5e612cf2014-02-03 17:57:23 -080039import android.view.MotionEvent;
Jim Miller3eb49712014-01-28 18:22:42 -080040import android.view.View;
Jim Miller838906b2012-10-19 18:41:25 -070041import android.widget.FrameLayout;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080042
Jim Miller3eb49712014-01-28 18:22:42 -080043import com.android.internal.widget.LockPatternUtils;
44import com.android.keyguard.KeyguardHostView.OnDismissAction;
45import com.android.keyguard.KeyguardSecurityContainer.SecurityCallback;
46import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
47
48import java.io.File;
49
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080050/**
Jim Millerdcb3d842012-08-23 19:18:12 -070051 * Base class for keyguard view. {@link #reset} is where you should
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080052 * reset the state of your view. Use the {@link KeyguardViewCallback} via
53 * {@link #getCallback()} to send information back (such as poking the wake lock,
54 * or finishing the keyguard).
55 *
56 * Handles intercepting of media keys that still work when the keyguard is
57 * showing.
58 */
Jim Millerba7d94b2014-02-05 17:30:50 -080059public abstract class KeyguardViewBase extends FrameLayout implements SecurityCallback {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080060
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080061 private AudioManager mAudioManager;
The Android Open Source Projectbc8d29f2009-03-05 20:00:44 -080062 private TelephonyManager mTelephonyManager = null;
Jorim Jaggi5cf17872014-03-26 18:31:48 +010063 protected ViewMediatorCallback mViewMediatorCallback;
Jim Miller3eb49712014-01-28 18:22:42 -080064 protected LockPatternUtils mLockPatternUtils;
65 private OnDismissAction mDismissAction;
Jim Millerdcb3d842012-08-23 19:18:12 -070066
Amith Yamasani2ef6f1b2011-12-01 14:01:30 -080067 // Whether the volume keys should be handled by keyguard. If true, then
68 // they will be handled here for specific media types such as music, otherwise
69 // the audio service will bring up the volume dialog.
Amith Yamasani6243edd2011-12-05 19:58:48 -080070 private static final boolean KEYGUARD_MANAGES_VOLUME = true;
Jorim Jaggi5cf17872014-03-26 18:31:48 +010071 public static final boolean DEBUG = KeyguardConstants.DEBUG;
Jim Miller3eb49712014-01-28 18:22:42 -080072 private static final String TAG = "KeyguardViewBase";
73
74 private KeyguardSecurityContainer mSecurityContainer;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080075
Jim Millerdcb3d842012-08-23 19:18:12 -070076 public KeyguardViewBase(Context context) {
77 this(context, null);
78 }
79
80 public KeyguardViewBase(Context context, AttributeSet attrs) {
81 super(context, attrs);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080082 }
83
Jim Miller3eb49712014-01-28 18:22:42 -080084 @Override
85 protected void dispatchDraw(Canvas canvas) {
86 super.dispatchDraw(canvas);
87 if (mViewMediatorCallback != null) {
88 mViewMediatorCallback.keyguardDoneDrawing();
89 }
90 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080091
92 /**
Jim Miller3eb49712014-01-28 18:22:42 -080093 * Sets an action to run when keyguard finishes.
94 *
95 * @param action
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080096 */
Jim Miller3eb49712014-01-28 18:22:42 -080097 public void setOnDismissAction(OnDismissAction action) {
98 mDismissAction = action;
99 }
100
101 @Override
102 protected void onFinishInflate() {
103 mSecurityContainer =
104 (KeyguardSecurityContainer) findViewById(R.id.keyguard_security_container);
Jim Miller5e612cf2014-02-03 17:57:23 -0800105 mLockPatternUtils = new LockPatternUtils(mContext);
Jim Miller3eb49712014-01-28 18:22:42 -0800106 mSecurityContainer.setLockPatternUtils(mLockPatternUtils);
Jim Millerba7d94b2014-02-05 17:30:50 -0800107 mSecurityContainer.setSecurityCallback(this);
Jim Miller3eb49712014-01-28 18:22:42 -0800108 mSecurityContainer.showPrimarySecurityScreen(false);
109 // mSecurityContainer.updateSecurityViews(false /* not bouncing */);
Jim Miller3eb49712014-01-28 18:22:42 -0800110 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800111
112 /**
Brian Colonna4284e9d2011-09-28 12:08:58 -0400113 * Called when the view needs to be shown.
114 */
Jim Miller3eb49712014-01-28 18:22:42 -0800115 public void show() {
116 if (DEBUG) Log.d(TAG, "show()");
117 mSecurityContainer.showPrimarySecurityScreen(false);
118 }
119
120 /**
121 * Dismisses the keyguard by going to the next screen or making it gone.
Jorim Jaggi0bed7f22014-04-03 16:12:54 +0200122 *
123 * @return True if the keyguard is done.
Jim Miller3eb49712014-01-28 18:22:42 -0800124 */
Jorim Jaggi0bed7f22014-04-03 16:12:54 +0200125 public boolean dismiss() {
126 return dismiss(false);
Jim Miller3eb49712014-01-28 18:22:42 -0800127 }
128
Jim Miller3eb49712014-01-28 18:22:42 -0800129 protected void showBouncer(boolean show) {
130 CharSequence what = getContext().getResources().getText(
131 show ? R.string.keyguard_accessibility_show_bouncer
132 : R.string.keyguard_accessibility_hide_bouncer);
133 announceForAccessibility(what);
134 announceCurrentSecurityMethod();
135 }
136
137 public boolean handleBackKey() {
138 if (mSecurityContainer.getCurrentSecuritySelection() == SecurityMode.Account) {
Jorim Jaggie5c7a892014-04-10 20:37:32 +0200139 // go back to primary screen
Jim Miller3eb49712014-01-28 18:22:42 -0800140 mSecurityContainer.showPrimarySecurityScreen(false /*turningOff*/);
141 return true;
142 }
143 if (mSecurityContainer.getCurrentSecuritySelection() != SecurityMode.None) {
144 mSecurityContainer.dismiss(false);
145 return true;
146 }
147 return false;
148 }
149
150 protected void announceCurrentSecurityMethod() {
151 mSecurityContainer.announceCurrentSecurityMethod();
152 }
153
Jim Millerba7d94b2014-02-05 17:30:50 -0800154 protected KeyguardSecurityContainer getSecurityContainer() {
155 return mSecurityContainer;
156 }
Jim Miller3eb49712014-01-28 18:22:42 -0800157
Jim Millerba7d94b2014-02-05 17:30:50 -0800158 /**
159 * Extend display timeout
160 * @param timeout duration to delay timeout, in ms.
161 */
162 @Override
163 public void userActivity(long timeout) {
Jim Miller3eb49712014-01-28 18:22:42 -0800164 if (mViewMediatorCallback != null) {
Jim Millerba7d94b2014-02-05 17:30:50 -0800165 mViewMediatorCallback.userActivity(timeout);
Jim Miller3eb49712014-01-28 18:22:42 -0800166 }
167 }
168
Jim Millerba7d94b2014-02-05 17:30:50 -0800169 @Override
170 public boolean dismiss(boolean authenticated) {
171 return mSecurityContainer.showNextSecurityScreenOrFinish(authenticated);
Jim Miller3eb49712014-01-28 18:22:42 -0800172 }
173
174 /**
175 * Authentication has happened and it's time to dismiss keyguard. This function
176 * should clean up and inform KeyguardViewMediator.
177 */
Jim Millerba7d94b2014-02-05 17:30:50 -0800178 @Override
Jim Miller3eb49712014-01-28 18:22:42 -0800179 public void finish() {
180 // If the alternate unlock was suppressed, it can now be safely
181 // enabled because the user has left keyguard.
182 KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
183
184 // If there's a pending runnable because the user interacted with a widget
185 // and we're leaving keyguard, then run it.
186 boolean deferKeyguardDone = false;
187 if (mDismissAction != null) {
188 deferKeyguardDone = mDismissAction.onDismiss();
189 mDismissAction = null;
190 }
191 if (mViewMediatorCallback != null) {
192 if (deferKeyguardDone) {
193 mViewMediatorCallback.keyguardDonePending();
194 } else {
195 mViewMediatorCallback.keyguardDone(true);
196 }
197 }
198 }
199
Jim Millerba7d94b2014-02-05 17:30:50 -0800200 @Override
201 public void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput) {
Jim Miller3eb49712014-01-28 18:22:42 -0800202 if (mViewMediatorCallback != null) {
Jim Millerba7d94b2014-02-05 17:30:50 -0800203 mViewMediatorCallback.setNeedsInput(needsInput);
Jim Miller3eb49712014-01-28 18:22:42 -0800204 }
205 }
206
Jim Millerba7d94b2014-02-05 17:30:50 -0800207 public void userActivity() {
Jim Miller3eb49712014-01-28 18:22:42 -0800208 if (mViewMediatorCallback != null) {
209 mViewMediatorCallback.userActivity();
210 }
211 }
212
213 protected void onUserActivityTimeoutChanged() {
214 if (mViewMediatorCallback != null) {
215 mViewMediatorCallback.onUserActivityTimeoutChanged();
216 }
217 }
218
219 /**
Jorim Jaggia005f1b2014-04-16 19:06:10 +0200220 * Called when the Keyguard is not actively shown anymore on the screen.
Jim Miller3eb49712014-01-28 18:22:42 -0800221 */
Jorim Jaggia005f1b2014-04-16 19:06:10 +0200222 public void onPause() {
Jim Miller3eb49712014-01-28 18:22:42 -0800223 if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s",
224 Integer.toHexString(hashCode()), SystemClock.uptimeMillis()));
225 // Once the screen turns off, we no longer consider this to be first boot and we want the
226 // biometric unlock to start next time keyguard is shown.
227 KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
228 mSecurityContainer.showPrimarySecurityScreen(true);
229 mSecurityContainer.onPause();
230 clearFocus();
231 }
232
233 /**
Jorim Jaggia005f1b2014-04-16 19:06:10 +0200234 * Called when the Keyguard is actively shown on the screen.
Jim Miller3eb49712014-01-28 18:22:42 -0800235 */
Jorim Jaggia005f1b2014-04-16 19:06:10 +0200236 public void onResume() {
Jim Miller3eb49712014-01-28 18:22:42 -0800237 if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode()));
238 mSecurityContainer.showPrimarySecurityScreen(false);
239 mSecurityContainer.onResume(KeyguardSecurityView.SCREEN_ON);
240
241 // This is a an attempt to fix bug 7137389 where the device comes back on but the entire
242 // layout is blank but forcing a layout causes it to reappear (e.g. with with
243 // hierarchyviewer).
244 requestLayout();
245 requestFocus();
246 }
Brian Colonna4284e9d2011-09-28 12:08:58 -0400247
248 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800249 * Verify that the user can get past the keyguard securely. This is called,
250 * for example, when the phone disables the keyguard but then wants to launch
251 * something else that requires secure access.
252 *
253 * The result will be propogated back via {@link KeyguardViewCallback#keyguardDone(boolean)}
254 */
Jim Miller3eb49712014-01-28 18:22:42 -0800255 public void verifyUnlock() {
Jim Millerba7d94b2014-02-05 17:30:50 -0800256 SecurityMode securityMode = mSecurityContainer.getSecurityMode();
Jim Miller3eb49712014-01-28 18:22:42 -0800257 if (securityMode == KeyguardSecurityModel.SecurityMode.None) {
258 if (mViewMediatorCallback != null) {
259 mViewMediatorCallback.keyguardDone(true);
260 }
261 } else if (securityMode != KeyguardSecurityModel.SecurityMode.Pattern
262 && securityMode != KeyguardSecurityModel.SecurityMode.PIN
263 && securityMode != KeyguardSecurityModel.SecurityMode.Password) {
264 // can only verify unlock when in pattern/password mode
265 if (mViewMediatorCallback != null) {
266 mViewMediatorCallback.keyguardDone(false);
267 }
268 } else {
269 // otherwise, go to the unlock screen, see if they can verify it
270 mSecurityContainer.verifyUnlock();
271 }
272 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800273
274 /**
275 * Called before this view is being removed.
276 */
277 abstract public void cleanUp();
278
Jeff Brownc7505bc2012-10-05 21:58:15 -0700279 /**
280 * Gets the desired user activity timeout in milliseconds, or -1 if the
281 * default should be used.
282 */
283 abstract public long getUserActivityTimeout();
284
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800285 @Override
286 public boolean dispatchKeyEvent(KeyEvent event) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800287 if (interceptMediaKey(event)) {
288 return true;
289 }
290 return super.dispatchKeyEvent(event);
291 }
292
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800293 /**
Marco Nelissen24d10562009-05-12 14:15:17 -0700294 * Allows the media keys to work when the keyguard is showing.
295 * The media keys should be of no interest to the actual keyguard view(s),
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800296 * so intercepting them here should not be of any harm.
297 * @param event The key event
298 * @return whether the event was consumed as a media key.
299 */
300 private boolean interceptMediaKey(KeyEvent event) {
301 final int keyCode = event.getKeyCode();
302 if (event.getAction() == KeyEvent.ACTION_DOWN) {
303 switch (keyCode) {
Marco Nelissena6face42010-10-25 10:21:59 -0700304 case KeyEvent.KEYCODE_MEDIA_PLAY:
305 case KeyEvent.KEYCODE_MEDIA_PAUSE:
Andy Stadler8b89d692009-04-10 16:24:49 -0700306 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
Jeff Brown4d396052010-10-29 21:50:21 -0700307 /* Suppress PLAY/PAUSE toggle when phone is ringing or
The Android Open Source Projectbc8d29f2009-03-05 20:00:44 -0800308 * in-call to avoid music playback */
309 if (mTelephonyManager == null) {
310 mTelephonyManager = (TelephonyManager) getContext().getSystemService(
311 Context.TELEPHONY_SERVICE);
312 }
313 if (mTelephonyManager != null &&
314 mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE) {
315 return true; // suppress key event
316 }
Jeff Brown4d396052010-10-29 21:50:21 -0700317 case KeyEvent.KEYCODE_MUTE:
318 case KeyEvent.KEYCODE_HEADSETHOOK:
319 case KeyEvent.KEYCODE_MEDIA_STOP:
320 case KeyEvent.KEYCODE_MEDIA_NEXT:
321 case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
322 case KeyEvent.KEYCODE_MEDIA_REWIND:
323 case KeyEvent.KEYCODE_MEDIA_RECORD:
Jaekyun Seokbfdad8e2013-07-08 13:53:21 +0900324 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
325 case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
Jean-Michel Trivic6802222012-04-30 11:15:03 -0700326 handleMediaKeyEvent(event);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800327 return true;
328 }
329
330 case KeyEvent.KEYCODE_VOLUME_UP:
Jeff Brownb0418da2010-11-01 15:24:01 -0700331 case KeyEvent.KEYCODE_VOLUME_DOWN:
332 case KeyEvent.KEYCODE_VOLUME_MUTE: {
Amith Yamasani2ef6f1b2011-12-01 14:01:30 -0800333 if (KEYGUARD_MANAGES_VOLUME) {
334 synchronized (this) {
335 if (mAudioManager == null) {
336 mAudioManager = (AudioManager) getContext().getSystemService(
337 Context.AUDIO_SERVICE);
338 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800339 }
Jean-Michel Trivi3114ce32012-06-11 15:03:52 -0700340 // Volume buttons should only function for music (local or remote).
341 // TODO: Actually handle MUTE.
342 mAudioManager.adjustLocalOrRemoteStreamVolume(
343 AudioManager.STREAM_MUSIC,
344 keyCode == KeyEvent.KEYCODE_VOLUME_UP
345 ? AudioManager.ADJUST_RAISE
346 : AudioManager.ADJUST_LOWER);
Amith Yamasani2ef6f1b2011-12-01 14:01:30 -0800347 // Don't execute default volume behavior
348 return true;
349 } else {
350 return false;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800351 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800352 }
353 }
354 } else if (event.getAction() == KeyEvent.ACTION_UP) {
355 switch (keyCode) {
356 case KeyEvent.KEYCODE_MUTE:
Jeff Brown4d396052010-10-29 21:50:21 -0700357 case KeyEvent.KEYCODE_HEADSETHOOK:
358 case KeyEvent.KEYCODE_MEDIA_PLAY:
359 case KeyEvent.KEYCODE_MEDIA_PAUSE:
360 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
361 case KeyEvent.KEYCODE_MEDIA_STOP:
362 case KeyEvent.KEYCODE_MEDIA_NEXT:
363 case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
364 case KeyEvent.KEYCODE_MEDIA_REWIND:
365 case KeyEvent.KEYCODE_MEDIA_RECORD:
Jaekyun Seokbfdad8e2013-07-08 13:53:21 +0900366 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
367 case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
Jean-Michel Trivic6802222012-04-30 11:15:03 -0700368 handleMediaKeyEvent(event);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800369 return true;
370 }
371 }
372 }
373 return false;
374 }
375
Jim Miller3eb49712014-01-28 18:22:42 -0800376 private void handleMediaKeyEvent(KeyEvent keyEvent) {
Jean-Michel Trivic6802222012-04-30 11:15:03 -0700377 IAudioService audioService = IAudioService.Stub.asInterface(
378 ServiceManager.checkService(Context.AUDIO_SERVICE));
379 if (audioService != null) {
380 try {
381 audioService.dispatchMediaKeyEvent(keyEvent);
382 } catch (RemoteException e) {
383 Log.e("KeyguardViewBase", "dispatchMediaKeyEvent threw exception " + e);
384 }
385 } else {
386 Slog.w("KeyguardViewBase", "Unable to find IAudioService for media key event");
387 }
388 }
389
Joe Onorato4671ce52011-01-27 21:15:42 -0800390 @Override
391 public void dispatchSystemUiVisibilityChanged(int visibility) {
392 super.dispatchSystemUiVisibilityChanged(visibility);
Jim Millerd6523da2012-10-21 16:47:02 -0700393
394 if (!(mContext instanceof Activity)) {
395 setSystemUiVisibility(STATUS_BAR_DISABLE_BACK);
396 }
Joe Onorato4671ce52011-01-27 21:15:42 -0800397 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700398
Jim Miller3eb49712014-01-28 18:22:42 -0800399 /**
400 * In general, we enable unlocking the insecure keyguard with the menu key. However, there are
401 * some cases where we wish to disable it, notably when the menu button placement or technology
402 * is prone to false positives.
403 *
404 * @return true if the menu key should be enabled
405 */
406 private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key";
407 private boolean shouldEnableMenuKey() {
408 final Resources res = getResources();
409 final boolean configDisabled = res.getBoolean(R.bool.config_disableMenuKeyInLockScreen);
410 final boolean isTestHarness = ActivityManager.isRunningInTestHarness();
411 final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists();
412 return !configDisabled || isTestHarness || fileOverride;
413 }
414
415 public boolean handleMenuKey() {
416 // The following enables the MENU key to work for testing automation
417 if (shouldEnableMenuKey()) {
418 dismiss();
419 return true;
420 }
421 return false;
422 }
423
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100424 public void setViewMediatorCallback(ViewMediatorCallback viewMediatorCallback) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700425 mViewMediatorCallback = viewMediatorCallback;
Jim Millerba7d94b2014-02-05 17:30:50 -0800426 // Update ViewMediator with the current input method requirements
427 mViewMediatorCallback.setNeedsInput(mSecurityContainer.needsInput());
Jim Millerdcb3d842012-08-23 19:18:12 -0700428 }
Jim Miller3eb49712014-01-28 18:22:42 -0800429
430 protected KeyguardActivityLauncher getActivityLauncher() {
431 return mActivityLauncher;
432 }
433
434 private final KeyguardActivityLauncher mActivityLauncher = new KeyguardActivityLauncher() {
435 @Override
436 Context getContext() {
437 return mContext;
438 }
439
440 @Override
441 void setOnDismissAction(OnDismissAction action) {
442 KeyguardViewBase.this.setOnDismissAction(action);
443 }
444
445 @Override
446 LockPatternUtils getLockPatternUtils() {
447 return mLockPatternUtils;
448 }
449
450 @Override
451 void requestDismissKeyguard() {
452 KeyguardViewBase.this.dismiss(false);
453 }
454 };
455
456 public void showAssistant() {
457 final Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
458 .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
459
460 if (intent == null) return;
461
462 final ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
463 R.anim.keyguard_action_assist_enter, R.anim.keyguard_action_assist_exit,
464 getHandler(), null);
465
466 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
467 mActivityLauncher.launchActivityWithAnimation(intent, false, opts.toBundle(), null, null);
468 }
469
470 public void launchCamera() {
471 mActivityLauncher.launchCamera(getHandler(), null);
472 }
473
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100474 public void setLockPatternUtils(LockPatternUtils utils) {
Jim Miller5e612cf2014-02-03 17:57:23 -0800475 mLockPatternUtils = utils;
476 mSecurityContainer.setLockPatternUtils(utils);
477 }
478
Jorim Jaggia005f1b2014-04-16 19:06:10 +0200479 public SecurityMode getSecurityMode() {
480 return mSecurityContainer.getSecurityMode();
481 }
482
Jim Miller5e612cf2014-02-03 17:57:23 -0800483 protected abstract void onUserSwitching(boolean switching);
484
485 protected abstract void onCreateOptions(Bundle options);
486
487 protected abstract void onExternalMotionEvent(MotionEvent event);
488
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800489}