blob: 1c4084c77cd17e26c0b18b0b0219db8e48902cd7 [file] [log] [blame]
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.policy.impl;
import com.android.internal.R;
import com.android.internal.telephony.IccCard;
import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.SlidingTab;
import com.android.internal.widget.WaveView;
import com.android.internal.widget.WaveView.OnTriggerListener;
import com.android.internal.widget.multiwaveview.MultiWaveView;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.ColorStateList;
import android.text.format.DateFormat;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.media.AudioManager;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.provider.Settings;
import java.util.Date;
import java.io.File;
/**
* The screen within {@link LockPatternKeyguardView} that shows general
* information about the device depending on its state, and how to get
* past it, as applicable.
*/
class LockScreen extends LinearLayout implements KeyguardScreen,
KeyguardUpdateMonitor.InfoCallback,
KeyguardUpdateMonitor.SimStateCallback {
private static final boolean DBG = false;
private static final String TAG = "LockScreen";
private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key";
private Status mStatus = Status.Normal;
private LockPatternUtils mLockPatternUtils;
private KeyguardUpdateMonitor mUpdateMonitor;
private KeyguardScreenCallback mCallback;
private TextView mScreenLocked;
private TextView mEmergencyCallText;
private Button mEmergencyCallButton;
// current configuration state of keyboard and display
private int mKeyboardHidden;
private int mCreationOrientation;
// are we showing battery information?
private boolean mShowingBatteryInfo = false;
// last known plugged in state
private boolean mPluggedIn = false;
// last known battery level
private int mBatteryLevel = 100;
private boolean mSilentMode;
private AudioManager mAudioManager;
private String mDateFormatString;
private java.text.DateFormat mTimeFormat;
private boolean mEnableMenuKeyInLockScreen;
private StatusView mStatusView;
private UnlockWidgetCommonMethods mUnlockWidgetMethods;
private View mUnlockWidget;
/**
* The status of this lock screen.
*/
enum Status {
/**
* Normal case (sim card present, it's not locked)
*/
Normal(true),
/**
* The sim card is 'network locked'.
*/
NetworkLocked(true),
/**
* The sim card is missing.
*/
SimMissing(false),
/**
* The sim card is missing, and this is the device isn't provisioned, so we don't let
* them get past the screen.
*/
SimMissingLocked(false),
/**
* The sim card is PUK locked, meaning they've entered the wrong sim unlock code too many
* times.
*/
SimPukLocked(false),
/**
* The sim card is locked.
*/
SimLocked(true),
/**
* The sim card is permanently disabled due to puk unlock failure
*/
SimPermDisabled(false);
private final boolean mShowStatusLines;
Status(boolean mShowStatusLines) {
this.mShowStatusLines = mShowStatusLines;
}
/**
* @return Whether the status lines (battery level and / or next alarm) are shown while
* in this state. Mostly dictated by whether this is room for them.
*/
public boolean showStatusLines() {
return mShowStatusLines;
}
}
private interface UnlockWidgetCommonMethods {
// Update resources based on phone state
public void updateResources();
// Get the view associated with this widget
public View getView();
// Reset the view
public void reset(boolean animate);
// Animate the widget if it supports ping()
public void ping();
}
class SlidingTabMethods implements SlidingTab.OnTriggerListener, UnlockWidgetCommonMethods {
private final SlidingTab mSlidingTab;
SlidingTabMethods(SlidingTab slidingTab) {
mSlidingTab = slidingTab;
}
public void updateResources() {
boolean vibe = mSilentMode
&& (mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE);
mSlidingTab.setRightTabResources(
mSilentMode ? ( vibe ? R.drawable.ic_jog_dial_vibrate_on
: R.drawable.ic_jog_dial_sound_off )
: R.drawable.ic_jog_dial_sound_on,
mSilentMode ? R.drawable.jog_tab_target_yellow
: R.drawable.jog_tab_target_gray,
mSilentMode ? R.drawable.jog_tab_bar_right_sound_on
: R.drawable.jog_tab_bar_right_sound_off,
mSilentMode ? R.drawable.jog_tab_right_sound_on
: R.drawable.jog_tab_right_sound_off);
}
/** {@inheritDoc} */
public void onTrigger(View v, int whichHandle) {
if (whichHandle == SlidingTab.OnTriggerListener.LEFT_HANDLE) {
mCallback.goToUnlockScreen();
} else if (whichHandle == SlidingTab.OnTriggerListener.RIGHT_HANDLE) {
toggleRingMode();
doSilenceRingToast();
mCallback.pokeWakelock();
}
}
/** {@inheritDoc} */
public void onGrabbedStateChange(View v, int grabbedState) {
if (grabbedState == SlidingTab.OnTriggerListener.RIGHT_HANDLE) {
mSilentMode = isSilentMode();
mSlidingTab.setRightHintText(mSilentMode ? R.string.lockscreen_sound_on_label
: R.string.lockscreen_sound_off_label);
}
// Don't poke the wake lock when returning to a state where the handle is
// not grabbed since that can happen when the system (instead of the user)
// cancels the grab.
if (grabbedState != SlidingTab.OnTriggerListener.NO_HANDLE) {
mCallback.pokeWakelock();
}
}
public View getView() {
return mSlidingTab;
}
public void reset(boolean animate) {
mSlidingTab.reset(animate);
}
public void ping() {
}
}
private static final int WAIT_FOR_ANIMATION_TIMEOUT = 0;
private static final int STAY_ON_WHILE_GRABBED_TIMEOUT = 30000;
class WaveViewMethods implements WaveView.OnTriggerListener, UnlockWidgetCommonMethods {
private final WaveView mWaveView;
WaveViewMethods(WaveView waveView) {
mWaveView = waveView;
}
/** {@inheritDoc} */
public void onTrigger(View v, int whichHandle) {
if (whichHandle == WaveView.OnTriggerListener.CENTER_HANDLE) {
requestUnlockScreen();
}
}
/** {@inheritDoc} */
public void onGrabbedStateChange(View v, int grabbedState) {
// Don't poke the wake lock when returning to a state where the handle is
// not grabbed since that can happen when the system (instead of the user)
// cancels the grab.
if (grabbedState == WaveView.OnTriggerListener.CENTER_HANDLE) {
mCallback.pokeWakelock(STAY_ON_WHILE_GRABBED_TIMEOUT);
}
}
public void updateResources() {
}
public View getView() {
return mWaveView;
}
public void reset(boolean animate) {
mWaveView.reset();
}
public void ping() {
}
}
class MultiWaveViewMethods implements MultiWaveView.OnTriggerListener,
UnlockWidgetCommonMethods {
private final MultiWaveView mMultiWaveView;
MultiWaveViewMethods(MultiWaveView multiWaveView) {
mMultiWaveView = multiWaveView;
}
public void updateResources() {
mMultiWaveView.setTargetResources(mSilentMode ? R.array.lockscreen_targets_when_silent
: R.array.lockscreen_targets_when_soundon);
}
public void onGrabbed(View v, int handle) {
}
public void onReleased(View v, int handle) {
}
public void onTrigger(View v, int target) {
if (target == 0) { // TODO: Use resources to determine which handle was used
mCallback.goToUnlockScreen();
} else if (target == 2) {
toggleRingMode();
doSilenceRingToast();
mUnlockWidgetMethods.updateResources();
mCallback.pokeWakelock();
}
}
public void onGrabbedStateChange(View v, int handle) {
// Don't poke the wake lock when returning to a state where the handle is
// not grabbed since that can happen when the system (instead of the user)
// cancels the grab.
if (handle != MultiWaveView.OnTriggerListener.NO_HANDLE) {
mCallback.pokeWakelock();
}
}
public View getView() {
return mMultiWaveView;
}
public void reset(boolean animate) {
mMultiWaveView.reset(animate);
}
public void ping() {
mMultiWaveView.ping();
}
}
private void requestUnlockScreen() {
// Delay hiding lock screen long enough for animation to finish
postDelayed(new Runnable() {
public void run() {
mCallback.goToUnlockScreen();
}
}, WAIT_FOR_ANIMATION_TIMEOUT);
}
private void doSilenceRingToast() {
String message = mSilentMode ?
getContext().getString(R.string.global_action_silent_mode_on_status) :
getContext().getString(R.string.global_action_silent_mode_off_status);
final int toastIcon = mSilentMode
? R.drawable.ic_lock_ringer_off
: R.drawable.ic_lock_ringer_on;
final int toastColor = mSilentMode
? getContext().getResources().getColor(R.color.keyguard_text_color_soundoff)
: getContext().getResources().getColor(R.color.keyguard_text_color_soundon);
toastMessage(mScreenLocked, message, toastColor, toastIcon);
}
private void toggleRingMode() {
// toggle silent mode
mSilentMode = !mSilentMode;
if (mSilentMode) {
final boolean vibe = (Settings.System.getInt(
getContext().getContentResolver(),
Settings.System.VIBRATE_IN_SILENT, 1) == 1);
mAudioManager.setRingerMode(vibe
? AudioManager.RINGER_MODE_VIBRATE
: AudioManager.RINGER_MODE_SILENT);
} else {
mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
}
}
/**
* In general, we enable unlocking the insecure key guard with the menu key. However, there are
* some cases where we wish to disable it, notably when the menu button placement or technology
* is prone to false positives.
*
* @return true if the menu key should be enabled
*/
private 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;
}
/**
* @param context Used to setup the view.
* @param configuration The current configuration. Used to use when selecting layout, etc.
* @param lockPatternUtils Used to know the state of the lock pattern settings.
* @param updateMonitor Used to register for updates on various keyguard related
* state, and query the initial state at setup.
* @param callback Used to communicate back to the host keyguard view.
*/
LockScreen(Context context, Configuration configuration, LockPatternUtils lockPatternUtils,
KeyguardUpdateMonitor updateMonitor,
KeyguardScreenCallback callback) {
super(context);
mLockPatternUtils = lockPatternUtils;
mUpdateMonitor = updateMonitor;
mCallback = callback;
mEnableMenuKeyInLockScreen = shouldEnableMenuKey();
mCreationOrientation = configuration.orientation;
mKeyboardHidden = configuration.hardKeyboardHidden;
if (LockPatternKeyguardView.DEBUG_CONFIGURATION) {
Log.v(TAG, "***** CREATING LOCK SCREEN", new RuntimeException());
Log.v(TAG, "Cur orient=" + mCreationOrientation
+ " res orient=" + context.getResources().getConfiguration().orientation);
}
final LayoutInflater inflater = LayoutInflater.from(context);
if (DBG) Log.v(TAG, "Creation orientation = " + mCreationOrientation);
if (mCreationOrientation != Configuration.ORIENTATION_LANDSCAPE) {
inflater.inflate(R.layout.keyguard_screen_tab_unlock, this, true);
} else {
inflater.inflate(R.layout.keyguard_screen_tab_unlock_land, this, true);
}
mStatusView = new StatusView(this, mUpdateMonitor, mLockPatternUtils);
mScreenLocked = (TextView) findViewById(R.id.screenLocked);
mEmergencyCallText = (TextView) findViewById(R.id.emergencyCallText);
mEmergencyCallButton = (Button) findViewById(R.id.emergencyCallButton);
mEmergencyCallButton.setText(R.string.lockscreen_emergency_call);
mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton);
mEmergencyCallButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
mCallback.takeEmergencyCallAction();
}
});
setFocusable(true);
setFocusableInTouchMode(true);
setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
mUpdateMonitor.registerInfoCallback(this);
mUpdateMonitor.registerSimStateCallback(this);
mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
mSilentMode = isSilentMode();
mUnlockWidget = findViewById(R.id.unlock_widget);
if (mUnlockWidget instanceof SlidingTab) {
SlidingTab slidingTabView = (SlidingTab) mUnlockWidget;
slidingTabView.setHoldAfterTrigger(true, false);
slidingTabView.setLeftHintText(R.string.lockscreen_unlock_label);
slidingTabView.setLeftTabResources(
R.drawable.ic_jog_dial_unlock,
R.drawable.jog_tab_target_green,
R.drawable.jog_tab_bar_left_unlock,
R.drawable.jog_tab_left_unlock);
SlidingTabMethods slidingTabMethods = new SlidingTabMethods(slidingTabView);
slidingTabView.setOnTriggerListener(slidingTabMethods);
mUnlockWidgetMethods = slidingTabMethods;
} else if (mUnlockWidget instanceof WaveView) {
WaveView waveView = (WaveView) mUnlockWidget;
WaveViewMethods waveViewMethods = new WaveViewMethods(waveView);
waveView.setOnTriggerListener(waveViewMethods);
mUnlockWidgetMethods = waveViewMethods;
} else if (mUnlockWidget instanceof MultiWaveView) {
MultiWaveView multiWaveView = (MultiWaveView) mUnlockWidget;
MultiWaveViewMethods multiWaveViewMethods = new MultiWaveViewMethods(multiWaveView);
multiWaveView.setOnTriggerListener(multiWaveViewMethods);
mUnlockWidgetMethods = multiWaveViewMethods;
} else {
throw new IllegalStateException("Unrecognized unlock widget: " + mUnlockWidget);
}
// Update widget with initial ring state
mUnlockWidgetMethods.updateResources();
if (DBG) Log.v(TAG, "*** LockScreen accel is "
+ (mUnlockWidget.isHardwareAccelerated() ? "on":"off"));
resetStatusInfo(updateMonitor);
}
private boolean isSilentMode() {
return mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL;
}
private void resetStatusInfo(KeyguardUpdateMonitor updateMonitor) {
mShowingBatteryInfo = updateMonitor.shouldShowBatteryInfo();
mPluggedIn = updateMonitor.isDevicePluggedIn();
mBatteryLevel = updateMonitor.getBatteryLevel();
mStatus = getCurrentStatus(updateMonitor.getSimState());
updateLayout(mStatus);
mTimeFormat = DateFormat.getTimeFormat(getContext());
mDateFormatString = getContext().getString(R.string.full_wday_month_day_no_year);
refreshTimeAndDateDisplay();
updateStatusLines();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_MENU && mEnableMenuKeyInLockScreen) {
mCallback.goToUnlockScreen();
}
return false;
}
/**
* Displays a message in a text view and then restores the previous text.
* @param textView The text view.
* @param text The text.
* @param color The color to apply to the text, or 0 if the existing color should be used.
* @param iconResourceId The left hand icon.
*/
private void toastMessage(final TextView textView, final String text, final int color, final int iconResourceId) {
if (mPendingR1 != null) {
textView.removeCallbacks(mPendingR1);
mPendingR1 = null;
}
if (mPendingR2 != null) {
mPendingR2.run(); // fire immediately, restoring non-toasted appearance
textView.removeCallbacks(mPendingR2);
mPendingR2 = null;
}
final String oldText = textView.getText().toString();
final ColorStateList oldColors = textView.getTextColors();
mPendingR1 = new Runnable() {
public void run() {
textView.setText(text);
if (color != 0) {
textView.setTextColor(color);
}
textView.setCompoundDrawablesWithIntrinsicBounds(iconResourceId, 0, 0, 0);
}
};
textView.postDelayed(mPendingR1, 0);
mPendingR2 = new Runnable() {
public void run() {
textView.setText(oldText);
textView.setTextColor(oldColors);
textView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
}
};
textView.postDelayed(mPendingR2, 3500);
}
private Runnable mPendingR1;
private Runnable mPendingR2;
/** {@inheritDoc} */
public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn,
int batteryLevel) {
if (DBG) Log.d(TAG, "onRefreshBatteryInfo(" + showBatteryInfo + ", " + pluggedIn + ")");
mStatusView.onRefreshBatteryInfo(showBatteryInfo, pluggedIn, batteryLevel);
mShowingBatteryInfo = showBatteryInfo;
mPluggedIn = pluggedIn;
mBatteryLevel = batteryLevel;
updateStatusLines();
}
/** {@inheritDoc} */
public void onTimeChanged() {
refreshTimeAndDateDisplay();
}
private void refreshTimeAndDateDisplay() {
mStatusView.refreshTimeAndDateDisplay();
}
private void updateStatusLines() {
mStatusView.updateStatusLines(mStatus.showStatusLines());
}
/** {@inheritDoc} */
public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) {
if (DBG) Log.d(TAG, "onRefreshCarrierInfo(" + plmn + ", " + spn + ")");
updateLayout(mStatus);
}
/**
* Determine the current status of the lock screen given the sim state and other stuff.
*/
private Status getCurrentStatus(IccCard.State simState) {
boolean missingAndNotProvisioned = (!mUpdateMonitor.isDeviceProvisioned()
&& (simState == IccCard.State.ABSENT
|| simState == IccCard.State.PERM_DISABLED));
if (missingAndNotProvisioned) {
return Status.SimMissingLocked;
}
switch (simState) {
case ABSENT:
return Status.SimMissing;
case NETWORK_LOCKED:
return Status.SimMissingLocked;
case NOT_READY:
return Status.SimMissing;
case PIN_REQUIRED:
return Status.SimLocked;
case PUK_REQUIRED:
return Status.SimPukLocked;
case READY:
return Status.Normal;
case PERM_DISABLED:
return Status.SimPermDisabled;
case UNKNOWN:
return Status.SimMissing;
}
return Status.SimMissing;
}
/**
* Enables unlocking of this screen. Typically just shows the unlock widget.
*/
private void enableUnlock() {
mUnlockWidgetMethods.getView().setVisibility(View.VISIBLE);
}
/**
* Disable unlocking of this screen. Typically just hides the unlock widget.
*/
private void disableUnlock() {
mUnlockWidgetMethods.getView().setVisibility(View.GONE);
}
/**
* Update the layout to match the current status.
*/
private void updateLayout(Status status) {
// The emergency call button no longer appears on this screen.
if (DBG) Log.d(TAG, "updateLayout: status=" + status);
mEmergencyCallButton.setVisibility(View.GONE); // in almost all cases
switch (status) {
case Normal:
// text
mStatusView.setCarrierText(
getCarrierString(
mUpdateMonitor.getTelephonyPlmn(),
mUpdateMonitor.getTelephonySpn()));
// Empty now, but used for sliding tab feedback
mScreenLocked.setText("");
// layout
mScreenLocked.setVisibility(View.INVISIBLE);
mEmergencyCallText.setVisibility(View.GONE);
enableUnlock();
break;
case NetworkLocked:
// The carrier string shows both sim card status (i.e. No Sim Card) and
// carrier's name and/or "Emergency Calls Only" status
mStatusView.setCarrierText(
getCarrierString(
mUpdateMonitor.getTelephonyPlmn(),
getContext().getText(R.string.lockscreen_network_locked_message)));
mScreenLocked.setText(R.string.lockscreen_instructions_when_pattern_disabled);
// layout
mScreenLocked.setVisibility(View.VISIBLE);
mEmergencyCallText.setVisibility(View.GONE);
enableUnlock();
break;
case SimMissing:
// text
mStatusView.setCarrierText(R.string.lockscreen_missing_sim_message_short);
mScreenLocked.setText(R.string.lockscreen_missing_sim_instructions_long);
// layout
mScreenLocked.setVisibility(View.VISIBLE);
mLockPatternUtils.updateEmergencyCallText(mEmergencyCallText);
enableUnlock(); // do not need to show the e-call button; user may unlock
break;
case SimPermDisabled:
// text
mStatusView.setCarrierText(R.string.lockscreen_missing_sim_message_short);
mScreenLocked.setText(
R.string.lockscreen_permanent_disabled_sim_instructions);
// layout
mScreenLocked.setVisibility(View.VISIBLE);
mLockPatternUtils.updateEmergencyCallText(mEmergencyCallText);
enableUnlock(); // do not need to show the e-call button; user may unlock
break;
case SimMissingLocked:
// text
mStatusView.setCarrierText(
getCarrierString(
mUpdateMonitor.getTelephonyPlmn(),
getContext().getText(R.string.lockscreen_missing_sim_message_short)));
mScreenLocked.setText(R.string.lockscreen_missing_sim_instructions);
// layout
mScreenLocked.setVisibility(View.VISIBLE);
mLockPatternUtils.updateEmergencyCallText(mEmergencyCallText);
mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton);
disableUnlock();
break;
case SimLocked:
// text
mStatusView.setCarrierText(
getCarrierString(
mUpdateMonitor.getTelephonyPlmn(),
getContext().getText(R.string.lockscreen_sim_locked_message)));
// layout
mScreenLocked.setVisibility(View.INVISIBLE);
mEmergencyCallText.setVisibility(View.GONE);
enableUnlock();
break;
case SimPukLocked:
// text
mStatusView.setCarrierText(
getCarrierString(
mUpdateMonitor.getTelephonyPlmn(),
getContext().getText(R.string.lockscreen_sim_puk_locked_message)));
mScreenLocked.setText(R.string.lockscreen_sim_puk_locked_instructions);
// layout
mLockPatternUtils.updateEmergencyCallText(mEmergencyCallText);
mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton);
if (mLockPatternUtils.isPukUnlockScreenEnable()) {
mScreenLocked.setVisibility(View.INVISIBLE);
enableUnlock();
} else {
mScreenLocked.setVisibility(View.VISIBLE);
disableUnlock();
}
break;
}
}
static CharSequence getCarrierString(CharSequence telephonyPlmn, CharSequence telephonySpn) {
if (telephonyPlmn != null && telephonySpn == null) {
return telephonyPlmn;
} else if (telephonyPlmn != null && telephonySpn != null) {
return telephonyPlmn + "|" + telephonySpn;
} else if (telephonyPlmn == null && telephonySpn != null) {
return telephonySpn;
} else {
return "";
}
}
public void onSimStateChanged(IccCard.State simState) {
if (DBG) Log.d(TAG, "onSimStateChanged(" + simState + ")");
mStatus = getCurrentStatus(simState);
updateLayout(mStatus);
updateStatusLines();
}
void updateConfiguration() {
Configuration newConfig = getResources().getConfiguration();
if (newConfig.orientation != mCreationOrientation) {
mCallback.recreateMe(newConfig);
} else if (newConfig.hardKeyboardHidden != mKeyboardHidden) {
mKeyboardHidden = newConfig.hardKeyboardHidden;
final boolean isKeyboardOpen = mKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO;
if (mUpdateMonitor.isKeyguardBypassEnabled() && isKeyboardOpen) {
mCallback.goToUnlockScreen();
}
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (LockPatternKeyguardView.DEBUG_CONFIGURATION) {
Log.v(TAG, "***** LOCK ATTACHED TO WINDOW");
Log.v(TAG, "Cur orient=" + mCreationOrientation
+ ", new config=" + getResources().getConfiguration());
}
updateConfiguration();
}
/** {@inheritDoc} */
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (LockPatternKeyguardView.DEBUG_CONFIGURATION) {
Log.w(TAG, "***** LOCK CONFIG CHANGING", new RuntimeException());
Log.v(TAG, "Cur orient=" + mCreationOrientation
+ ", new config=" + newConfig);
}
updateConfiguration();
}
/** {@inheritDoc} */
public boolean needsInput() {
return false;
}
/** {@inheritDoc} */
public void onPause() {
mUnlockWidgetMethods.reset(false);
}
/** {@inheritDoc} */
public void onResume() {
resetStatusInfo(mUpdateMonitor);
mUnlockWidgetMethods.ping();
}
/** {@inheritDoc} */
public void cleanUp() {
mUpdateMonitor.removeCallback(this); // this must be first
mLockPatternUtils = null;
mUpdateMonitor = null;
mCallback = null;
}
/** {@inheritDoc} */
public void onRingerModeChanged(int state) {
boolean silent = AudioManager.RINGER_MODE_NORMAL != state;
if (silent != mSilentMode) {
mSilentMode = silent;
mUnlockWidgetMethods.updateResources();
}
}
public void onPhoneStateChanged(String newState) {
}
}