| /* |
| * 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) { |
| } |
| } |