package com.android.keyguard;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.media.AudioManager;
import android.os.SystemClock;
import android.service.trust.TrustAgentService;
import android.telephony.TelephonyManager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.accessibility.AccessibilityEvent;
import android.widget.FrameLayout;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardSecurityContainer.SecurityCallback;
import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
import com.android.settingslib.Utils;
import java.io.File;
public class KeyguardHostView extends FrameLayout implements SecurityCallback {
public interface OnDismissAction {
boolean onDismiss();
}
private AudioManager mAudioManager;
private TelephonyManager mTelephonyManager = null;
protected ViewMediatorCallback mViewMediatorCallback;
protected LockPatternUtils mLockPatternUtils;
private OnDismissAction mDismissAction;
private Runnable mCancelAction;
private final KeyguardUpdateMonitorCallback mUpdateCallback =
new KeyguardUpdateMonitorCallback() {
@Override
public void onUserSwitchComplete(int userId) {
getSecurityContainer().showPrimarySecurityScreen(false );
}
@Override
public void onTrustGrantedWithFlags(int flags, int userId) {
if (userId != KeyguardUpdateMonitor.getCurrentUser()) return;
if (!isAttachedToWindow()) return;
boolean bouncerVisible = isVisibleToUser();
boolean initiatedByUser =
(flags & TrustAgentService.FLAG_GRANT_TRUST_INITIATED_BY_USER) != 0;
boolean dismissKeyguard =
(flags & TrustAgentService.FLAG_GRANT_TRUST_DISMISS_KEYGUARD) != 0;
if (initiatedByUser || dismissKeyguard) {
if (mViewMediatorCallback.isScreenOn() && (bouncerVisible || dismissKeyguard)) {
if (!bouncerVisible) {
Log.i(TAG, "TrustAgent dismissed Keyguard.");
}
dismiss(false , userId);
} else {
mViewMediatorCallback.playTrustedSound();
}
}
}
};
private static final boolean KEYGUARD_MANAGES_VOLUME = false;
public static final boolean DEBUG = KeyguardConstants.DEBUG;
private static final String TAG = "KeyguardViewBase";
private KeyguardSecurityContainer mSecurityContainer;
public KeyguardHostView(Context context) {
this(context, null);
}
public KeyguardHostView(Context context, AttributeSet attrs) {
super(context, attrs);
KeyguardUpdateMonitor.getInstance(context).registerCallback(mUpdateCallback);
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if (mViewMediatorCallback != null) {
mViewMediatorCallback.keyguardDoneDrawing();
}
}
public void setOnDismissAction(OnDismissAction action, Runnable cancelAction) {
if (mCancelAction != null) {
mCancelAction.run();
mCancelAction = null;
}
mDismissAction = action;
mCancelAction = cancelAction;
}
public boolean hasDismissActions() {
return mDismissAction != null || mCancelAction != null;
}
public void cancelDismissAction() {
setOnDismissAction(null, null);
}
@Override
protected void onFinishInflate() {
mSecurityContainer =
findViewById(R.id.keyguard_security_container);
mLockPatternUtils = new LockPatternUtils(mContext);
mSecurityContainer.setLockPatternUtils(mLockPatternUtils);
mSecurityContainer.setSecurityCallback(this);
mSecurityContainer.showPrimarySecurityScreen(false);
}
public void showPrimarySecurityScreen() {
if (DEBUG) Log.d(TAG, "show()");
mSecurityContainer.showPrimarySecurityScreen(false);
}
public void showPromptReason(int reason) {
mSecurityContainer.showPromptReason(reason);
}
public void showMessage(CharSequence message, int color) {
mSecurityContainer.showMessage(message, color);
}
public void showErrorMessage(CharSequence message) {
showMessage(message, Utils.getColorError(mContext));
}
public boolean dismiss(int targetUserId) {
return dismiss(false, targetUserId);
}
public boolean handleBackKey() {
if (mSecurityContainer.getCurrentSecuritySelection() != SecurityMode.None) {
mSecurityContainer.dismiss(false, KeyguardUpdateMonitor.getCurrentUser());
return true;
}
return false;
}
protected KeyguardSecurityContainer getSecurityContainer() {
return mSecurityContainer;
}
@Override
public boolean dismiss(boolean authenticated, int targetUserId) {
return mSecurityContainer.showNextSecurityScreenOrFinish(authenticated, targetUserId);
}
@Override
public void finish(boolean strongAuth, int targetUserId) {
boolean deferKeyguardDone = false;
if (mDismissAction != null) {
deferKeyguardDone = mDismissAction.onDismiss();
mDismissAction = null;
mCancelAction = null;
}
if (mViewMediatorCallback != null) {
if (deferKeyguardDone) {
mViewMediatorCallback.keyguardDonePending(strongAuth, targetUserId);
} else {
mViewMediatorCallback.keyguardDone(strongAuth, targetUserId);
}
}
}
@Override
public void reset() {
mViewMediatorCallback.resetKeyguard();
}
public void resetSecurityContainer() {
mSecurityContainer.reset();
}
@Override
public void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput) {
if (mViewMediatorCallback != null) {
mViewMediatorCallback.setNeedsInput(needsInput);
}
}
public CharSequence getAccessibilityTitleForCurrentMode() {
return mSecurityContainer.getTitle();
}
public void userActivity() {
if (mViewMediatorCallback != null) {
mViewMediatorCallback.userActivity();
}
}
public void onPause() {
if (DEBUG) Log.d(TAG, String.format("screen off, instance %s at %s",
Integer.toHexString(hashCode()), SystemClock.uptimeMillis()));
mSecurityContainer.showPrimarySecurityScreen(true);
mSecurityContainer.onPause();
clearFocus();
}
public void onResume() {
if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode()));
mSecurityContainer.onResume(KeyguardSecurityView.SCREEN_ON);
requestFocus();
}
public void startAppearAnimation() {
mSecurityContainer.startAppearAnimation();
}
public void startDisappearAnimation(Runnable finishRunnable) {
if (!mSecurityContainer.startDisappearAnimation(finishRunnable) && finishRunnable != null) {
finishRunnable.run();
}
}
public void cleanUp() {
getSecurityContainer().onPause();
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (interceptMediaKey(event)) {
return true;
}
return super.dispatchKeyEvent(event);
}
public boolean interceptMediaKey(KeyEvent event) {
final int keyCode = event.getKeyCode();
if (event.getAction() == KeyEvent.ACTION_DOWN) {
switch (keyCode) {
case KeyEvent.KEYCODE_MEDIA_PLAY:
case KeyEvent.KEYCODE_MEDIA_PAUSE:
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
if (mTelephonyManager == null) {
mTelephonyManager = (TelephonyManager) getContext().getSystemService(
Context.TELEPHONY_SERVICE);
}
if (mTelephonyManager != null &&
mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE) {
return true;
}
case KeyEvent.KEYCODE_MUTE:
case KeyEvent.KEYCODE_HEADSETHOOK:
case KeyEvent.KEYCODE_MEDIA_STOP:
case KeyEvent.KEYCODE_MEDIA_NEXT:
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
case KeyEvent.KEYCODE_MEDIA_REWIND:
case KeyEvent.KEYCODE_MEDIA_RECORD:
case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
handleMediaKeyEvent(event);
return true;
}
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_MUTE: {
if (KEYGUARD_MANAGES_VOLUME) {
synchronized (this) {
if (mAudioManager == null) {
mAudioManager = (AudioManager) getContext().getSystemService(
Context.AUDIO_SERVICE);
}
}
mAudioManager.adjustSuggestedStreamVolume(
keyCode == KeyEvent.KEYCODE_VOLUME_UP
? AudioManager.ADJUST_RAISE
: AudioManager.ADJUST_LOWER ,
AudioManager.STREAM_MUSIC , 0 );
return true;
} else {
return false;
}
}
}
} else if (event.getAction() == KeyEvent.ACTION_UP) {
switch (keyCode) {
case KeyEvent.KEYCODE_MUTE:
case KeyEvent.KEYCODE_HEADSETHOOK:
case KeyEvent.KEYCODE_MEDIA_PLAY:
case KeyEvent.KEYCODE_MEDIA_PAUSE:
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
case KeyEvent.KEYCODE_MEDIA_STOP:
case KeyEvent.KEYCODE_MEDIA_NEXT:
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
case KeyEvent.KEYCODE_MEDIA_REWIND:
case KeyEvent.KEYCODE_MEDIA_RECORD:
case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
case KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK: {
handleMediaKeyEvent(event);
return true;
}
}
}
return false;
}
private void handleMediaKeyEvent(KeyEvent keyEvent) {
synchronized (this) {
if (mAudioManager == null) {
mAudioManager = (AudioManager) getContext().getSystemService(
Context.AUDIO_SERVICE);
}
}
mAudioManager.dispatchMediaKeyEvent(keyEvent);
}
@Override
public void dispatchSystemUiVisibilityChanged(int visibility) {
super.dispatchSystemUiVisibilityChanged(visibility);
if (!(mContext instanceof Activity)) {
setSystemUiVisibility(STATUS_BAR_DISABLE_BACK);
}
}
private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key";
public boolean shouldEnableMenuKey() {
final Resources res = getResources();
final boolean configDisabled = res.getBoolean(R.bool.config_disableMenuKeyInLockScreen);
final boolean isTestHarness = ActivityManager.isRunningInTestHarness();
final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists();
return !configDisabled || isTestHarness || fileOverride;
}
public void setViewMediatorCallback(ViewMediatorCallback viewMediatorCallback) {
mViewMediatorCallback = viewMediatorCallback;
mViewMediatorCallback.setNeedsInput(mSecurityContainer.needsInput());
}
public void setLockPatternUtils(LockPatternUtils utils) {
mLockPatternUtils = utils;
mSecurityContainer.setLockPatternUtils(utils);
}
public SecurityMode getSecurityMode() {
return mSecurityContainer.getSecurityMode();
}
public SecurityMode getCurrentSecurityMode() {
return mSecurityContainer.getCurrentSecurityMode();
}
}