blob: 14ead04274788bdcff5ca2ac8d2c7888f06c660f [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;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080021import android.content.Context;
Jason Chang1e4a4bd2018-05-22 17:30:19 +080022import android.content.res.ColorStateList;
Gus Prevasab336792018-11-14 13:52:20 -050023import android.content.res.Resources;
Jim Miller3eb49712014-01-28 18:22:42 -080024import android.graphics.Canvas;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080025import android.media.AudioManager;
Jim Miller3eb49712014-01-28 18:22:42 -080026import android.os.SystemClock;
Adrian Roos94e15a52015-04-16 12:23:18 -070027import android.service.trust.TrustAgentService;
The Android Open Source Projectbc8d29f2009-03-05 20:00:44 -080028import android.telephony.TelephonyManager;
Karl Rosaenad297342009-03-24 18:55:19 -070029import android.util.AttributeSet;
Jean-Michel Trivic6802222012-04-30 11:15:03 -070030import android.util.Log;
Jim Miller838906b2012-10-19 18:41:25 -070031import android.view.KeyEvent;
32import android.widget.FrameLayout;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080033
Jim Miller3eb49712014-01-28 18:22:42 -080034import com.android.internal.widget.LockPatternUtils;
Jim Miller3eb49712014-01-28 18:22:42 -080035import com.android.keyguard.KeyguardSecurityContainer.SecurityCallback;
36import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
Lucas Dupinc80c67e2017-12-04 14:29:10 -080037import com.android.settingslib.Utils;
Jason Monk297c04e2018-08-23 17:16:59 -040038import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
Jim Miller3eb49712014-01-28 18:22:42 -080039
40import java.io.File;
41
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080042/**
Jim Millerdcb3d842012-08-23 19:18:12 -070043 * Base class for keyguard view. {@link #reset} is where you should
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080044 * reset the state of your view. Use the {@link KeyguardViewCallback} via
45 * {@link #getCallback()} to send information back (such as poking the wake lock,
46 * or finishing the keyguard).
47 *
48 * Handles intercepting of media keys that still work when the keyguard is
49 * showing.
50 */
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +010051public class KeyguardHostView extends FrameLayout implements SecurityCallback {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080052
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080053 private AudioManager mAudioManager;
The Android Open Source Projectbc8d29f2009-03-05 20:00:44 -080054 private TelephonyManager mTelephonyManager = null;
Jorim Jaggi5cf17872014-03-26 18:31:48 +010055 protected ViewMediatorCallback mViewMediatorCallback;
Jim Miller3eb49712014-01-28 18:22:42 -080056 protected LockPatternUtils mLockPatternUtils;
57 private OnDismissAction mDismissAction;
Jorim Jaggid9449862015-05-29 14:49:08 -070058 private Runnable mCancelAction;
Jim Millerdcb3d842012-08-23 19:18:12 -070059
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +010060 private final KeyguardUpdateMonitorCallback mUpdateCallback =
61 new KeyguardUpdateMonitorCallback() {
62
63 @Override
64 public void onUserSwitchComplete(int userId) {
65 getSecurityContainer().showPrimarySecurityScreen(false /* turning off */);
66 }
67
68 @Override
Adrian Roos94e15a52015-04-16 12:23:18 -070069 public void onTrustGrantedWithFlags(int flags, int userId) {
Adrian Roosd6aa6cb2015-04-16 19:31:29 -070070 if (userId != KeyguardUpdateMonitor.getCurrentUser()) return;
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +010071 if (!isAttachedToWindow()) return;
Adrian Roos94e15a52015-04-16 12:23:18 -070072 boolean bouncerVisible = isVisibleToUser();
73 boolean initiatedByUser =
74 (flags & TrustAgentService.FLAG_GRANT_TRUST_INITIATED_BY_USER) != 0;
75 boolean dismissKeyguard =
76 (flags & TrustAgentService.FLAG_GRANT_TRUST_DISMISS_KEYGUARD) != 0;
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +010077
Adrian Roos94e15a52015-04-16 12:23:18 -070078 if (initiatedByUser || dismissKeyguard) {
79 if (mViewMediatorCallback.isScreenOn() && (bouncerVisible || dismissKeyguard)) {
80 if (!bouncerVisible) {
81 // The trust agent dismissed the keyguard without the user proving
82 // that they are present (by swiping up to show the bouncer). That's fine if
83 // the user proved presence via some other way to the trust agent.
84 Log.i(TAG, "TrustAgent dismissed Keyguard.");
85 }
Vadim Tryshev8702ca72016-04-22 08:14:12 -070086 dismiss(false /* authenticated */, userId);
Adrian Roos94e15a52015-04-16 12:23:18 -070087 } else {
88 mViewMediatorCallback.playTrustedSound();
89 }
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +010090 }
91 }
92 };
93
Amith Yamasani2ef6f1b2011-12-01 14:01:30 -080094 // Whether the volume keys should be handled by keyguard. If true, then
95 // they will be handled here for specific media types such as music, otherwise
96 // the audio service will bring up the volume dialog.
John Spurlockae641c92014-06-30 18:11:40 -040097 private static final boolean KEYGUARD_MANAGES_VOLUME = false;
Jorim Jaggi5cf17872014-03-26 18:31:48 +010098 public static final boolean DEBUG = KeyguardConstants.DEBUG;
Jim Miller3eb49712014-01-28 18:22:42 -080099 private static final String TAG = "KeyguardViewBase";
100
101 private KeyguardSecurityContainer mSecurityContainer;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800102
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +0100103 public KeyguardHostView(Context context) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700104 this(context, null);
105 }
106
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +0100107 public KeyguardHostView(Context context, AttributeSet attrs) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700108 super(context, attrs);
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +0100109 KeyguardUpdateMonitor.getInstance(context).registerCallback(mUpdateCallback);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800110 }
111
Jim Miller3eb49712014-01-28 18:22:42 -0800112 @Override
113 protected void dispatchDraw(Canvas canvas) {
114 super.dispatchDraw(canvas);
115 if (mViewMediatorCallback != null) {
116 mViewMediatorCallback.keyguardDoneDrawing();
117 }
118 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800119
120 /**
Jim Miller3eb49712014-01-28 18:22:42 -0800121 * Sets an action to run when keyguard finishes.
122 *
123 * @param action
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800124 */
Jorim Jaggid9449862015-05-29 14:49:08 -0700125 public void setOnDismissAction(OnDismissAction action, Runnable cancelAction) {
126 if (mCancelAction != null) {
127 mCancelAction.run();
128 mCancelAction = null;
129 }
Jim Miller3eb49712014-01-28 18:22:42 -0800130 mDismissAction = action;
Jorim Jaggid9449862015-05-29 14:49:08 -0700131 mCancelAction = cancelAction;
132 }
133
Lucas Dupin6f0d71f2018-03-23 17:26:06 -0700134 public boolean hasDismissActions() {
135 return mDismissAction != null || mCancelAction != null;
136 }
137
Jorim Jaggid9449862015-05-29 14:49:08 -0700138 public void cancelDismissAction() {
139 setOnDismissAction(null, null);
Jim Miller3eb49712014-01-28 18:22:42 -0800140 }
141
142 @Override
143 protected void onFinishInflate() {
144 mSecurityContainer =
Alan Viverette51efddb2017-04-05 10:00:01 -0400145 findViewById(R.id.keyguard_security_container);
Jim Miller5e612cf2014-02-03 17:57:23 -0800146 mLockPatternUtils = new LockPatternUtils(mContext);
Jim Miller3eb49712014-01-28 18:22:42 -0800147 mSecurityContainer.setLockPatternUtils(mLockPatternUtils);
Jim Millerba7d94b2014-02-05 17:30:50 -0800148 mSecurityContainer.setSecurityCallback(this);
Jim Miller3eb49712014-01-28 18:22:42 -0800149 mSecurityContainer.showPrimarySecurityScreen(false);
Jim Miller3eb49712014-01-28 18:22:42 -0800150 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800151
152 /**
Brian Colonna4284e9d2011-09-28 12:08:58 -0400153 * Called when the view needs to be shown.
154 */
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100155 public void showPrimarySecurityScreen() {
Jim Miller3eb49712014-01-28 18:22:42 -0800156 if (DEBUG) Log.d(TAG, "show()");
157 mSecurityContainer.showPrimarySecurityScreen(false);
158 }
159
Lucas Dupin27321c42019-03-20 16:22:24 -0700160 public KeyguardSecurityView getCurrentSecurityView() {
161 return mSecurityContainer != null ? mSecurityContainer.getCurrentSecurityView() : null;
162 }
163
Jim Miller3eb49712014-01-28 18:22:42 -0800164 /**
Selim Cinek3122fa82015-06-18 01:38:59 -0700165 * Show a string explaining why the security view needs to be solved.
166 *
167 * @param reason a flag indicating which string should be shown, see
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700168 * {@link KeyguardSecurityView#PROMPT_REASON_NONE},
169 * {@link KeyguardSecurityView#PROMPT_REASON_RESTART} and
170 * {@link KeyguardSecurityView#PROMPT_REASON_TIMEOUT}.
Selim Cinek3122fa82015-06-18 01:38:59 -0700171 */
172 public void showPromptReason(int reason) {
173 mSecurityContainer.showPromptReason(reason);
174 }
175
Jason Chang1e4a4bd2018-05-22 17:30:19 +0800176 public void showMessage(CharSequence message, ColorStateList colorState) {
177 mSecurityContainer.showMessage(message, colorState);
Selim Cinekcfafe4e2015-08-11 14:58:44 -0700178 }
179
Lucas Dupinc80c67e2017-12-04 14:29:10 -0800180 public void showErrorMessage(CharSequence message) {
Jason Chang1e4a4bd2018-05-22 17:30:19 +0800181 showMessage(message, Utils.getColorError(mContext));
Lucas Dupinc80c67e2017-12-04 14:29:10 -0800182 }
183
Selim Cinek3122fa82015-06-18 01:38:59 -0700184 /**
Vadim Tryshev8702ca72016-04-22 08:14:12 -0700185 * Dismisses the keyguard by going to the next screen or making it gone.
186 * @param targetUserId a user that needs to be the foreground user at the dismissal completion.
187 * @return True if the keyguard is done.
Jim Miller3eb49712014-01-28 18:22:42 -0800188 */
Vadim Tryshev8702ca72016-04-22 08:14:12 -0700189 public boolean dismiss(int targetUserId) {
190 return dismiss(false, targetUserId);
Jim Miller3eb49712014-01-28 18:22:42 -0800191 }
192
Jim Miller3eb49712014-01-28 18:22:42 -0800193 public boolean handleBackKey() {
Jim Miller3eb49712014-01-28 18:22:42 -0800194 if (mSecurityContainer.getCurrentSecuritySelection() != SecurityMode.None) {
Vadim Tryshev8702ca72016-04-22 08:14:12 -0700195 mSecurityContainer.dismiss(false, KeyguardUpdateMonitor.getCurrentUser());
Jim Miller3eb49712014-01-28 18:22:42 -0800196 return true;
197 }
198 return false;
199 }
200
Jim Millerba7d94b2014-02-05 17:30:50 -0800201 protected KeyguardSecurityContainer getSecurityContainer() {
202 return mSecurityContainer;
203 }
Jim Miller3eb49712014-01-28 18:22:42 -0800204
Jim Millerba7d94b2014-02-05 17:30:50 -0800205 @Override
Vadim Tryshev8702ca72016-04-22 08:14:12 -0700206 public boolean dismiss(boolean authenticated, int targetUserId) {
207 return mSecurityContainer.showNextSecurityScreenOrFinish(authenticated, targetUserId);
Jim Miller3eb49712014-01-28 18:22:42 -0800208 }
209
210 /**
211 * Authentication has happened and it's time to dismiss keyguard. This function
212 * should clean up and inform KeyguardViewMediator.
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700213 *
214 * @param strongAuth whether the user has authenticated with strong authentication like
215 * pattern, password or PIN but not by trust agents or fingerprint
Vadim Tryshev8702ca72016-04-22 08:14:12 -0700216 * @param targetUserId a user that needs to be the foreground user at the dismissal completion.
Jim Miller3eb49712014-01-28 18:22:42 -0800217 */
Jim Millerba7d94b2014-02-05 17:30:50 -0800218 @Override
Vadim Tryshev8702ca72016-04-22 08:14:12 -0700219 public void finish(boolean strongAuth, int targetUserId) {
Jim Miller3eb49712014-01-28 18:22:42 -0800220 // If there's a pending runnable because the user interacted with a widget
221 // and we're leaving keyguard, then run it.
222 boolean deferKeyguardDone = false;
223 if (mDismissAction != null) {
224 deferKeyguardDone = mDismissAction.onDismiss();
225 mDismissAction = null;
Jorim Jaggid9449862015-05-29 14:49:08 -0700226 mCancelAction = null;
Jim Miller3eb49712014-01-28 18:22:42 -0800227 }
228 if (mViewMediatorCallback != null) {
229 if (deferKeyguardDone) {
Vadim Tryshev8702ca72016-04-22 08:14:12 -0700230 mViewMediatorCallback.keyguardDonePending(strongAuth, targetUserId);
Jim Miller3eb49712014-01-28 18:22:42 -0800231 } else {
Vadim Tryshev8702ca72016-04-22 08:14:12 -0700232 mViewMediatorCallback.keyguardDone(strongAuth, targetUserId);
Jim Miller3eb49712014-01-28 18:22:42 -0800233 }
234 }
235 }
236
Jim Millerba7d94b2014-02-05 17:30:50 -0800237 @Override
Andrew Lee72b46d42015-01-30 13:23:21 -0800238 public void reset() {
239 mViewMediatorCallback.resetKeyguard();
240 }
241
Aarthi Balachander0a427ef2018-07-13 15:00:58 -0700242 @Override
243 public void onCancelClicked() {
244 mViewMediatorCallback.onCancelClicked();
245 }
246
Lucas Dupin80180492018-05-08 17:06:06 -0700247 public void resetSecurityContainer() {
248 mSecurityContainer.reset();
249 }
250
Andrew Lee72b46d42015-01-30 13:23:21 -0800251 @Override
Jim Millerba7d94b2014-02-05 17:30:50 -0800252 public void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput) {
Jim Miller3eb49712014-01-28 18:22:42 -0800253 if (mViewMediatorCallback != null) {
Jim Millerba7d94b2014-02-05 17:30:50 -0800254 mViewMediatorCallback.setNeedsInput(needsInput);
Jim Miller3eb49712014-01-28 18:22:42 -0800255 }
256 }
257
Phil Weaver7d847b02018-02-13 16:02:35 -0800258 public CharSequence getAccessibilityTitleForCurrentMode() {
259 return mSecurityContainer.getTitle();
260 }
261
Jim Millerba7d94b2014-02-05 17:30:50 -0800262 public void userActivity() {
Jim Miller3eb49712014-01-28 18:22:42 -0800263 if (mViewMediatorCallback != null) {
264 mViewMediatorCallback.userActivity();
265 }
266 }
267
Jim Miller3eb49712014-01-28 18:22:42 -0800268 /**
Jorim Jaggia005f1b2014-04-16 19:06:10 +0200269 * Called when the Keyguard is not actively shown anymore on the screen.
Jim Miller3eb49712014-01-28 18:22:42 -0800270 */
Jorim Jaggia005f1b2014-04-16 19:06:10 +0200271 public void onPause() {
Jim Miller3eb49712014-01-28 18:22:42 -0800272 if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s",
273 Integer.toHexString(hashCode()), SystemClock.uptimeMillis()));
Jim Miller3eb49712014-01-28 18:22:42 -0800274 mSecurityContainer.showPrimarySecurityScreen(true);
275 mSecurityContainer.onPause();
276 clearFocus();
277 }
278
279 /**
Jorim Jaggia005f1b2014-04-16 19:06:10 +0200280 * Called when the Keyguard is actively shown on the screen.
Jim Miller3eb49712014-01-28 18:22:42 -0800281 */
Jorim Jaggia005f1b2014-04-16 19:06:10 +0200282 public void onResume() {
Jim Miller3eb49712014-01-28 18:22:42 -0800283 if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode()));
Jim Miller3eb49712014-01-28 18:22:42 -0800284 mSecurityContainer.onResume(KeyguardSecurityView.SCREEN_ON);
Jim Miller3eb49712014-01-28 18:22:42 -0800285 requestFocus();
286 }
Brian Colonna4284e9d2011-09-28 12:08:58 -0400287
288 /**
Jorim Jaggic14f8292014-05-27 02:25:45 +0200289 * Starts the animation when the Keyguard gets shown.
290 */
291 public void startAppearAnimation() {
292 mSecurityContainer.startAppearAnimation();
293 }
294
Jorim Jaggi76a16232014-08-08 17:00:47 +0200295 public void startDisappearAnimation(Runnable finishRunnable) {
Jorim Jaggi8de4311c2014-08-11 22:36:20 +0200296 if (!mSecurityContainer.startDisappearAnimation(finishRunnable) && finishRunnable != null) {
Jorim Jaggi76a16232014-08-08 17:00:47 +0200297 finishRunnable.run();
298 }
299 }
300
Jorim Jaggic14f8292014-05-27 02:25:45 +0200301 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800302 * Called before this view is being removed.
303 */
Jorim Jaggi6b88cdf2014-12-22 20:56:50 +0100304 public void cleanUp() {
305 getSecurityContainer().onPause();
306 }
Jeff Brownc7505bc2012-10-05 21:58:15 -0700307
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800308 @Override
309 public boolean dispatchKeyEvent(KeyEvent event) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800310 if (interceptMediaKey(event)) {
311 return true;
312 }
313 return super.dispatchKeyEvent(event);
314 }
315
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800316 /**
Marco Nelissen24d10562009-05-12 14:15:17 -0700317 * Allows the media keys to work when the keyguard is showing.
318 * The media keys should be of no interest to the actual keyguard view(s),
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800319 * so intercepting them here should not be of any harm.
320 * @param event The key event
321 * @return whether the event was consumed as a media key.
322 */
Jorim Jaggidf993512014-05-13 23:06:35 +0200323 public boolean interceptMediaKey(KeyEvent event) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800324 final int keyCode = event.getKeyCode();
325 if (event.getAction() == KeyEvent.ACTION_DOWN) {
326 switch (keyCode) {
Marco Nelissena6face42010-10-25 10:21:59 -0700327 case KeyEvent.KEYCODE_MEDIA_PLAY:
328 case KeyEvent.KEYCODE_MEDIA_PAUSE:
Andy Stadler8b89d692009-04-10 16:24:49 -0700329 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
Jeff Brown4d396052010-10-29 21:50:21 -0700330 /* Suppress PLAY/PAUSE toggle when phone is ringing or
The Android Open Source Projectbc8d29f2009-03-05 20:00:44 -0800331 * in-call to avoid music playback */
332 if (mTelephonyManager == null) {
333 mTelephonyManager = (TelephonyManager) getContext().getSystemService(
334 Context.TELEPHONY_SERVICE);
335 }
336 if (mTelephonyManager != null &&
337 mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE) {
338 return true; // suppress key event
339 }
Jeff Brown4d396052010-10-29 21:50:21 -0700340 case KeyEvent.KEYCODE_MUTE:
341 case KeyEvent.KEYCODE_HEADSETHOOK:
342 case KeyEvent.KEYCODE_MEDIA_STOP:
343 case KeyEvent.KEYCODE_MEDIA_NEXT:
344 case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
345 case KeyEvent.KEYCODE_MEDIA_REWIND:
346 case KeyEvent.KEYCODE_MEDIA_RECORD:
Jaekyun Seokbfdad8e2013-07-08 13:53:21 +0900347 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
348 case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
Jean-Michel Trivic6802222012-04-30 11:15:03 -0700349 handleMediaKeyEvent(event);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800350 return true;
351 }
352
353 case KeyEvent.KEYCODE_VOLUME_UP:
Jeff Brownb0418da2010-11-01 15:24:01 -0700354 case KeyEvent.KEYCODE_VOLUME_DOWN:
355 case KeyEvent.KEYCODE_VOLUME_MUTE: {
Amith Yamasani2ef6f1b2011-12-01 14:01:30 -0800356 if (KEYGUARD_MANAGES_VOLUME) {
357 synchronized (this) {
358 if (mAudioManager == null) {
359 mAudioManager = (AudioManager) getContext().getSystemService(
360 Context.AUDIO_SERVICE);
361 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800362 }
Jean-Michel Trivi3114ce32012-06-11 15:03:52 -0700363 // Volume buttons should only function for music (local or remote).
364 // TODO: Actually handle MUTE.
RoboErikd3c86422014-06-16 14:00:48 -0700365 mAudioManager.adjustSuggestedStreamVolume(
Jean-Michel Trivi3114ce32012-06-11 15:03:52 -0700366 keyCode == KeyEvent.KEYCODE_VOLUME_UP
367 ? AudioManager.ADJUST_RAISE
RoboErikd3c86422014-06-16 14:00:48 -0700368 : AudioManager.ADJUST_LOWER /* direction */,
369 AudioManager.STREAM_MUSIC /* stream */, 0 /* flags */);
Amith Yamasani2ef6f1b2011-12-01 14:01:30 -0800370 // Don't execute default volume behavior
371 return true;
372 } else {
373 return false;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800374 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800375 }
376 }
377 } else if (event.getAction() == KeyEvent.ACTION_UP) {
378 switch (keyCode) {
379 case KeyEvent.KEYCODE_MUTE:
Jeff Brown4d396052010-10-29 21:50:21 -0700380 case KeyEvent.KEYCODE_HEADSETHOOK:
381 case KeyEvent.KEYCODE_MEDIA_PLAY:
382 case KeyEvent.KEYCODE_MEDIA_PAUSE:
383 case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
384 case KeyEvent.KEYCODE_MEDIA_STOP:
385 case KeyEvent.KEYCODE_MEDIA_NEXT:
386 case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
387 case KeyEvent.KEYCODE_MEDIA_REWIND:
388 case KeyEvent.KEYCODE_MEDIA_RECORD:
Jaekyun Seokbfdad8e2013-07-08 13:53:21 +0900389 case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
390 case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
Jean-Michel Trivic6802222012-04-30 11:15:03 -0700391 handleMediaKeyEvent(event);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800392 return true;
393 }
394 }
395 }
396 return false;
397 }
398
Jim Miller3eb49712014-01-28 18:22:42 -0800399 private void handleMediaKeyEvent(KeyEvent keyEvent) {
RoboErikd3c86422014-06-16 14:00:48 -0700400 synchronized (this) {
401 if (mAudioManager == null) {
402 mAudioManager = (AudioManager) getContext().getSystemService(
403 Context.AUDIO_SERVICE);
Jean-Michel Trivic6802222012-04-30 11:15:03 -0700404 }
Jean-Michel Trivic6802222012-04-30 11:15:03 -0700405 }
RoboErikd3c86422014-06-16 14:00:48 -0700406 mAudioManager.dispatchMediaKeyEvent(keyEvent);
Jean-Michel Trivic6802222012-04-30 11:15:03 -0700407 }
408
Joe Onorato4671ce52011-01-27 21:15:42 -0800409 @Override
410 public void dispatchSystemUiVisibilityChanged(int visibility) {
411 super.dispatchSystemUiVisibilityChanged(visibility);
Jim Millerd6523da2012-10-21 16:47:02 -0700412
413 if (!(mContext instanceof Activity)) {
414 setSystemUiVisibility(STATUS_BAR_DISABLE_BACK);
415 }
Joe Onorato4671ce52011-01-27 21:15:42 -0800416 }
Jim Millerdcb3d842012-08-23 19:18:12 -0700417
Jim Miller3eb49712014-01-28 18:22:42 -0800418 /**
419 * In general, we enable unlocking the insecure keyguard with the menu key. However, there are
420 * some cases where we wish to disable it, notably when the menu button placement or technology
421 * is prone to false positives.
422 *
423 * @return true if the menu key should be enabled
424 */
425 private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key";
Selim Cinek28540192016-02-19 17:25:08 -0800426 public boolean shouldEnableMenuKey() {
Jim Miller3eb49712014-01-28 18:22:42 -0800427 final Resources res = getResources();
428 final boolean configDisabled = res.getBoolean(R.bool.config_disableMenuKeyInLockScreen);
429 final boolean isTestHarness = ActivityManager.isRunningInTestHarness();
430 final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists();
431 return !configDisabled || isTestHarness || fileOverride;
432 }
433
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100434 public void setViewMediatorCallback(ViewMediatorCallback viewMediatorCallback) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700435 mViewMediatorCallback = viewMediatorCallback;
Jim Millerba7d94b2014-02-05 17:30:50 -0800436 // Update ViewMediator with the current input method requirements
437 mViewMediatorCallback.setNeedsInput(mSecurityContainer.needsInput());
Jim Millerdcb3d842012-08-23 19:18:12 -0700438 }
Jim Miller3eb49712014-01-28 18:22:42 -0800439
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100440 public void setLockPatternUtils(LockPatternUtils utils) {
Jim Miller5e612cf2014-02-03 17:57:23 -0800441 mLockPatternUtils = utils;
442 mSecurityContainer.setLockPatternUtils(utils);
443 }
444
Jorim Jaggia005f1b2014-04-16 19:06:10 +0200445 public SecurityMode getSecurityMode() {
446 return mSecurityContainer.getSecurityMode();
447 }
448
Jorim Jaggi95e89ca2014-11-24 20:12:50 +0100449 public SecurityMode getCurrentSecurityMode() {
450 return mSecurityContainer.getCurrentSecurityMode();
451 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800452}