1 /* 2 * Copyright (C) 2008 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 17 package com.android.internal.policy.impl; 18 19 import com.android.internal.R; 20 import com.android.internal.telephony.IccCard; 21 import com.android.internal.widget.LockPatternUtils; 22 import com.android.internal.widget.SlidingTab; 23 24 import android.content.Context; 25 import android.content.res.Configuration; 26 import android.content.res.Resources; 27 import android.content.res.ColorStateList; 28 import android.text.format.DateFormat; 29 import android.view.KeyEvent; 30 import android.view.LayoutInflater; 31 import android.view.View; 32 import android.view.ViewGroup; 33 import android.widget.*; 34 import android.graphics.drawable.Drawable; 35 import android.util.Log; 36 import android.media.AudioManager; 37 import android.os.SystemClock; 38 import android.os.SystemProperties; 39 import android.provider.Settings; 40 41 import java.util.Date; 42 import java.io.File; 43 44 /** 45 * The screen within {@link LockPatternKeyguardView} that shows general 46 * information about the device depending on its state, and how to get 47 * past it, as applicable. 48 */ 49 class LockScreen extends LinearLayout implements KeyguardScreen, KeyguardUpdateMonitor.InfoCallback, 50 KeyguardUpdateMonitor.SimStateCallback, SlidingTab.OnTriggerListener { 51 52 private static final boolean DBG = false; 53 private static final String TAG = "LockScreen"; 54 private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key"; 55 56 private Status mStatus = Status.Normal; 57 58 private final LockPatternUtils mLockPatternUtils; 59 private final KeyguardUpdateMonitor mUpdateMonitor; 60 private final KeyguardScreenCallback mCallback; 61 62 private TextView mCarrier; 63 private SlidingTab mSelector; 64 private TextView mTime; 65 private TextView mDate; 66 private TextView mStatus1; 67 private TextView mStatus2; 68 private TextView mScreenLocked; 69 private TextView mEmergencyCallText; 70 private Button mEmergencyCallButton; 71 72 // current configuration state of keyboard and display 73 private int mKeyboardHidden; 74 private int mCreationOrientation; 75 76 // are we showing battery information? 77 private boolean mShowingBatteryInfo = false; 78 79 // last known plugged in state 80 private boolean mPluggedIn = false; 81 82 // last known battery level 83 private int mBatteryLevel = 100; 84 85 private String mNextAlarm = null; 86 private Drawable mAlarmIcon = null; 87 private String mCharging = null; 88 private Drawable mChargingIcon = null; 89 90 private boolean mSilentMode; 91 private AudioManager mAudioManager; 92 private String mDateFormatString; 93 private java.text.DateFormat mTimeFormat; 94 private boolean mEnableMenuKeyInLockScreen; 95 96 /** 97 * The status of this lock screen. 98 */ 99 enum Status { 100 /** 101 * Normal case (sim card present, it's not locked) 102 */ 103 Normal(true), 104 105 /** 106 * The sim card is 'network locked'. 107 */ 108 NetworkLocked(true), 109 110 /** 111 * The sim card is missing. 112 */ 113 SimMissing(false), 114 115 /** 116 * The sim card is missing, and this is the device isn't provisioned, so we don't let 117 * them get past the screen. 118 */ 119 SimMissingLocked(false), 120 121 /** 122 * The sim card is PUK locked, meaning they've entered the wrong sim unlock code too many 123 * times. 124 */ 125 SimPukLocked(false), 126 127 /** 128 * The sim card is locked. 129 */ 130 SimLocked(true); 131 132 private final boolean mShowStatusLines; 133 134 Status(boolean mShowStatusLines) { 135 this.mShowStatusLines = mShowStatusLines; 136 } 137 138 /** 139 * @return Whether the status lines (battery level and / or next alarm) are shown while 140 * in this state. Mostly dictated by whether this is room for them. 141 */ 142 public boolean showStatusLines() { 143 return mShowStatusLines; 144 } 145 } 146 147 /** 148 * In general, we enable unlocking the insecure key guard with the menu key. However, there are 149 * some cases where we wish to disable it, notably when the menu button placement or technology 150 * is prone to false positives. 151 * 152 * @return true if the menu key should be enabled 153 */ 154 private boolean shouldEnableMenuKey() { 155 final Resources res = getResources(); 156 final boolean configDisabled = res.getBoolean(R.bool.config_disableMenuKeyInLockScreen); 157 final boolean isMonkey = SystemProperties.getBoolean("ro.monkey", false); 158 final boolean fileOverride = (new File(ENABLE_MENU_KEY_FILE)).exists(); 159 return !configDisabled || isMonkey || fileOverride; 160 } 161 162 /** 163 * @param context Used to setup the view. 164 * @param configuration The current configuration. Used to use when selecting layout, etc. 165 * @param lockPatternUtils Used to know the state of the lock pattern settings. 166 * @param updateMonitor Used to register for updates on various keyguard related 167 * state, and query the initial state at setup. 168 * @param callback Used to communicate back to the host keyguard view. 169 */ 170 LockScreen(Context context, Configuration configuration, LockPatternUtils lockPatternUtils, 171 KeyguardUpdateMonitor updateMonitor, 172 KeyguardScreenCallback callback) { 173 super(context); 174 mLockPatternUtils = lockPatternUtils; 175 mUpdateMonitor = updateMonitor; 176 mCallback = callback; 177 178 mEnableMenuKeyInLockScreen = shouldEnableMenuKey(); 179 180 mCreationOrientation = configuration.orientation; 181 182 mKeyboardHidden = configuration.hardKeyboardHidden; 183 184 if (LockPatternKeyguardView.DEBUG_CONFIGURATION) { 185 Log.v(TAG, "***** CREATING LOCK SCREEN", new RuntimeException()); 186 Log.v(TAG, "Cur orient=" + mCreationOrientation 187 + " res orient=" + context.getResources().getConfiguration().orientation); 188 } 189 190 final LayoutInflater inflater = LayoutInflater.from(context); 191 if (DBG) Log.v(TAG, "Creation orientation = " + mCreationOrientation); 192 if (mCreationOrientation != Configuration.ORIENTATION_LANDSCAPE) { 193 inflater.inflate(R.layout.keyguard_screen_tab_unlock, this, true); 194 } else { 195 inflater.inflate(R.layout.keyguard_screen_tab_unlock_land, this, true); 196 } 197 198 mCarrier = (TextView) findViewById(R.id.carrier); 199 // Required for Marquee to work 200 mCarrier.setSelected(true); 201 mCarrier.setTextColor(0xffffffff); 202 203 mDate = (TextView) findViewById(R.id.date); 204 mStatus1 = (TextView) findViewById(R.id.status1); 205 mStatus2 = (TextView) findViewById(R.id.status2); 206 207 mScreenLocked = (TextView) findViewById(R.id.screenLocked); 208 mSelector = (SlidingTab) findViewById(R.id.tab_selector); 209 mSelector.setHoldAfterTrigger(true, false); 210 mSelector.setLeftHintText(R.string.lockscreen_unlock_label); 211 212 mEmergencyCallText = (TextView) findViewById(R.id.emergencyCallText); 213 mEmergencyCallButton = (Button) findViewById(R.id.emergencyCallButton); 214 mEmergencyCallButton.setText(R.string.lockscreen_emergency_call); 215 216 mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton); 217 mEmergencyCallButton.setOnClickListener(new View.OnClickListener() { 218 public void onClick(View v) { 219 mCallback.takeEmergencyCallAction(); 220 } 221 }); 222 223 224 setFocusable(true); 225 setFocusableInTouchMode(true); 226 setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); 227 228 updateMonitor.registerInfoCallback(this); 229 updateMonitor.registerSimStateCallback(this); 230 231 mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE); 232 mSilentMode = isSilentMode(); 233 234 mSelector.setLeftTabResources( 235 R.drawable.ic_jog_dial_unlock, 236 R.drawable.jog_tab_target_green, 237 R.drawable.jog_tab_bar_left_unlock, 238 R.drawable.jog_tab_left_unlock); 239 240 updateRightTabResources(); 241 242 mSelector.setOnTriggerListener(this); 243 244 resetStatusInfo(updateMonitor); 245 } 246 247 private boolean isSilentMode() { 248 return mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL; 249 } 250 251 private void updateRightTabResources() { 252 boolean vibe = mSilentMode 253 && (mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE); 254 255 mSelector.setRightTabResources( 256 mSilentMode ? ( vibe ? R.drawable.ic_jog_dial_vibrate_on 257 : R.drawable.ic_jog_dial_sound_off ) 258 : R.drawable.ic_jog_dial_sound_on, 259 mSilentMode ? R.drawable.jog_tab_target_yellow 260 : R.drawable.jog_tab_target_gray, 261 mSilentMode ? R.drawable.jog_tab_bar_right_sound_on 262 : R.drawable.jog_tab_bar_right_sound_off, 263 mSilentMode ? R.drawable.jog_tab_right_sound_on 264 : R.drawable.jog_tab_right_sound_off); 265 } 266 267 private void resetStatusInfo(KeyguardUpdateMonitor updateMonitor) { 268 mShowingBatteryInfo = updateMonitor.shouldShowBatteryInfo(); 269 mPluggedIn = updateMonitor.isDevicePluggedIn(); 270 mBatteryLevel = updateMonitor.getBatteryLevel(); 271 272 mStatus = getCurrentStatus(updateMonitor.getSimState()); 273 updateLayout(mStatus); 274 275 refreshBatteryStringAndIcon(); 276 refreshAlarmDisplay(); 277 278 mTimeFormat = DateFormat.getTimeFormat(getContext()); 279 mDateFormatString = getContext().getString(R.string.full_wday_month_day_no_year); 280 refreshTimeAndDateDisplay(); 281 updateStatusLines(); 282 } 283 284 @Override 285 public boolean onKeyDown(int keyCode, KeyEvent event) { 286 if (keyCode == KeyEvent.KEYCODE_MENU && mEnableMenuKeyInLockScreen) { 287 mCallback.goToUnlockScreen(); 288 } 289 return false; 290 } 291 292 /** {@inheritDoc} */ 293 public void onTrigger(View v, int whichHandle) { 294 if (whichHandle == SlidingTab.OnTriggerListener.LEFT_HANDLE) { 295 mCallback.goToUnlockScreen(); 296 } else if (whichHandle == SlidingTab.OnTriggerListener.RIGHT_HANDLE) { 297 // toggle silent mode 298 mSilentMode = !mSilentMode; 299 if (mSilentMode) { 300 final boolean vibe = (Settings.System.getInt( 301 getContext().getContentResolver(), 302 Settings.System.VIBRATE_IN_SILENT, 1) == 1); 303 304 mAudioManager.setRingerMode(vibe 305 ? AudioManager.RINGER_MODE_VIBRATE 306 : AudioManager.RINGER_MODE_SILENT); 307 } else { 308 mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL); 309 } 310 311 updateRightTabResources(); 312 313 String message = mSilentMode ? 314 getContext().getString(R.string.global_action_silent_mode_on_status) : 315 getContext().getString(R.string.global_action_silent_mode_off_status); 316 317 final int toastIcon = mSilentMode 318 ? R.drawable.ic_lock_ringer_off 319 : R.drawable.ic_lock_ringer_on; 320 321 final int toastColor = mSilentMode 322 ? getContext().getResources().getColor(R.color.keyguard_text_color_soundoff) 323 : getContext().getResources().getColor(R.color.keyguard_text_color_soundon); 324 toastMessage(mScreenLocked, message, toastColor, toastIcon); 325 mCallback.pokeWakelock(); 326 } 327 } 328 329 /** {@inheritDoc} */ 330 public void onGrabbedStateChange(View v, int grabbedState) { 331 if (grabbedState == SlidingTab.OnTriggerListener.RIGHT_HANDLE) { 332 mSilentMode = isSilentMode(); 333 mSelector.setRightHintText(mSilentMode ? R.string.lockscreen_sound_on_label 334 : R.string.lockscreen_sound_off_label); 335 } 336 mCallback.pokeWakelock(); 337 } 338 339 /** 340 * Displays a message in a text view and then restores the previous text. 341 * @param textView The text view. 342 * @param text The text. 343 * @param color The color to apply to the text, or 0 if the existing color should be used. 344 * @param iconResourceId The left hand icon. 345 */ 346 private void toastMessage(final TextView textView, final String text, final int color, final int iconResourceId) { 347 if (mPendingR1 != null) { 348 textView.removeCallbacks(mPendingR1); 349 mPendingR1 = null; 350 } 351 if (mPendingR2 != null) { 352 mPendingR2.run(); // fire immediately, restoring non-toasted appearance 353 textView.removeCallbacks(mPendingR2); 354 mPendingR2 = null; 355 } 356 357 final String oldText = textView.getText().toString(); 358 final ColorStateList oldColors = textView.getTextColors(); 359 360 mPendingR1 = new Runnable() { 361 public void run() { 362 textView.setText(text); 363 if (color != 0) { 364 textView.setTextColor(color); 365 } 366 textView.setCompoundDrawablesWithIntrinsicBounds(iconResourceId, 0, 0, 0); 367 } 368 }; 369 370 textView.postDelayed(mPendingR1, 0); 371 mPendingR2 = new Runnable() { 372 public void run() { 373 textView.setText(oldText); 374 textView.setTextColor(oldColors); 375 textView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); 376 } 377 }; 378 textView.postDelayed(mPendingR2, 3500); 379 } 380 private Runnable mPendingR1; 381 private Runnable mPendingR2; 382 383 private void refreshAlarmDisplay() { 384 mNextAlarm = mLockPatternUtils.getNextAlarm(); 385 if (mNextAlarm != null) { 386 mAlarmIcon = getContext().getResources().getDrawable(R.drawable.ic_lock_idle_alarm); 387 } 388 updateStatusLines(); 389 } 390 391 /** {@inheritDoc} */ 392 public void onRefreshBatteryInfo(boolean showBatteryInfo, boolean pluggedIn, 393 int batteryLevel) { 394 if (DBG) Log.d(TAG, "onRefreshBatteryInfo(" + showBatteryInfo + ", " + pluggedIn + ")"); 395 mShowingBatteryInfo = showBatteryInfo; 396 mPluggedIn = pluggedIn; 397 mBatteryLevel = batteryLevel; 398 399 refreshBatteryStringAndIcon(); 400 updateStatusLines(); 401 } 402 403 private void refreshBatteryStringAndIcon() { 404 if (!mShowingBatteryInfo) { 405 mCharging = null; 406 return; 407 } 408 409 if (mChargingIcon == null) { 410 mChargingIcon = 411 getContext().getResources().getDrawable(R.drawable.ic_lock_idle_charging); 412 } 413 414 if (mPluggedIn) { 415 if (mBatteryLevel >= 100) { 416 mCharging = getContext().getString(R.string.lockscreen_charged); 417 } else { 418 mCharging = getContext().getString(R.string.lockscreen_plugged_in, mBatteryLevel); 419 } 420 } else { 421 mCharging = getContext().getString(R.string.lockscreen_low_battery); 422 } 423 } 424 425 /** {@inheritDoc} */ 426 public void onTimeChanged() { 427 refreshTimeAndDateDisplay(); 428 } 429 430 private void refreshTimeAndDateDisplay() { 431 mDate.setText(DateFormat.format(mDateFormatString, new Date())); 432 } 433 434 private void updateStatusLines() { 435 if (!mStatus.showStatusLines() 436 || (mCharging == null && mNextAlarm == null)) { 437 mStatus1.setVisibility(View.INVISIBLE); 438 mStatus2.setVisibility(View.INVISIBLE); 439 } else if (mCharging != null && mNextAlarm == null) { 440 // charging only 441 mStatus1.setVisibility(View.VISIBLE); 442 mStatus2.setVisibility(View.INVISIBLE); 443 444 mStatus1.setText(mCharging); 445 mStatus1.setCompoundDrawablesWithIntrinsicBounds(mChargingIcon, null, null, null); 446 } else if (mNextAlarm != null && mCharging == null) { 447 // next alarm only 448 mStatus1.setVisibility(View.VISIBLE); 449 mStatus2.setVisibility(View.INVISIBLE); 450 451 mStatus1.setText(mNextAlarm); 452 mStatus1.setCompoundDrawablesWithIntrinsicBounds(mAlarmIcon, null, null, null); 453 } else if (mCharging != null && mNextAlarm != null) { 454 // both charging and next alarm 455 mStatus1.setVisibility(View.VISIBLE); 456 mStatus2.setVisibility(View.VISIBLE); 457 458 mStatus1.setText(mCharging); 459 mStatus1.setCompoundDrawablesWithIntrinsicBounds(mChargingIcon, null, null, null); 460 mStatus2.setText(mNextAlarm); 461 mStatus2.setCompoundDrawablesWithIntrinsicBounds(mAlarmIcon, null, null, null); 462 } 463 } 464 465 /** {@inheritDoc} */ 466 public void onRefreshCarrierInfo(CharSequence plmn, CharSequence spn) { 467 if (DBG) Log.d(TAG, "onRefreshCarrierInfo(" + plmn + ", " + spn + ")"); 468 updateLayout(mStatus); 469 } 470 471 /** 472 * Determine the current status of the lock screen given the sim state and other stuff. 473 */ 474 private Status getCurrentStatus(IccCard.State simState) { 475 boolean missingAndNotProvisioned = (!mUpdateMonitor.isDeviceProvisioned() 476 && simState == IccCard.State.ABSENT); 477 if (missingAndNotProvisioned) { 478 return Status.SimMissingLocked; 479 } 480 481 switch (simState) { 482 case ABSENT: 483 return Status.SimMissing; 484 case NETWORK_LOCKED: 485 return Status.SimMissingLocked; 486 case NOT_READY: 487 return Status.SimMissing; 488 case PIN_REQUIRED: 489 return Status.SimLocked; 490 case PUK_REQUIRED: 491 return Status.SimPukLocked; 492 case READY: 493 return Status.Normal; 494 case UNKNOWN: 495 return Status.SimMissing; 496 } 497 return Status.SimMissing; 498 } 499 500 /** 501 * Update the layout to match the current status. 502 */ 503 private void updateLayout(Status status) { 504 // The emergency call button no longer appears on this screen. 505 if (DBG) Log.d(TAG, "updateLayout: status=" + status); 506 507 mEmergencyCallButton.setVisibility(View.GONE); // in almost all cases 508 509 switch (status) { 510 case Normal: 511 // text 512 mCarrier.setText( 513 getCarrierString( 514 mUpdateMonitor.getTelephonyPlmn(), 515 mUpdateMonitor.getTelephonySpn())); 516 517 // Empty now, but used for sliding tab feedback 518 mScreenLocked.setText(""); 519 520 // layout 521 mScreenLocked.setVisibility(View.VISIBLE); 522 mSelector.setVisibility(View.VISIBLE); 523 mEmergencyCallText.setVisibility(View.GONE); 524 break; 525 case NetworkLocked: 526 // The carrier string shows both sim card status (i.e. No Sim Card) and 527 // carrier's name and/or "Emergency Calls Only" status 528 mCarrier.setText( 529 getCarrierString( 530 mUpdateMonitor.getTelephonyPlmn(), 531 getContext().getText(R.string.lockscreen_network_locked_message))); 532 mScreenLocked.setText(R.string.lockscreen_instructions_when_pattern_disabled); 533 534 // layout 535 mScreenLocked.setVisibility(View.VISIBLE); 536 mSelector.setVisibility(View.VISIBLE); 537 mEmergencyCallText.setVisibility(View.GONE); 538 break; 539 case SimMissing: 540 // text 541 mCarrier.setText(R.string.lockscreen_missing_sim_message_short); 542 mScreenLocked.setText(R.string.lockscreen_missing_sim_instructions); 543 544 // layout 545 mScreenLocked.setVisibility(View.VISIBLE); 546 mSelector.setVisibility(View.VISIBLE); 547 mEmergencyCallText.setVisibility(View.VISIBLE); 548 // do not need to show the e-call button; user may unlock 549 break; 550 case SimMissingLocked: 551 // text 552 mCarrier.setText( 553 getCarrierString( 554 mUpdateMonitor.getTelephonyPlmn(), 555 getContext().getText(R.string.lockscreen_missing_sim_message_short))); 556 mScreenLocked.setText(R.string.lockscreen_missing_sim_instructions); 557 558 // layout 559 mScreenLocked.setVisibility(View.VISIBLE); 560 mSelector.setVisibility(View.GONE); // cannot unlock 561 mEmergencyCallText.setVisibility(View.VISIBLE); 562 mEmergencyCallButton.setVisibility(View.VISIBLE); 563 break; 564 case SimLocked: 565 // text 566 mCarrier.setText( 567 getCarrierString( 568 mUpdateMonitor.getTelephonyPlmn(), 569 getContext().getText(R.string.lockscreen_sim_locked_message))); 570 571 // layout 572 mScreenLocked.setVisibility(View.INVISIBLE); 573 mSelector.setVisibility(View.VISIBLE); 574 mEmergencyCallText.setVisibility(View.GONE); 575 break; 576 case SimPukLocked: 577 // text 578 mCarrier.setText( 579 getCarrierString( 580 mUpdateMonitor.getTelephonyPlmn(), 581 getContext().getText(R.string.lockscreen_sim_puk_locked_message))); 582 mScreenLocked.setText(R.string.lockscreen_sim_puk_locked_instructions); 583 584 // layout 585 mScreenLocked.setVisibility(View.VISIBLE); 586 mSelector.setVisibility(View.GONE); // cannot unlock 587 mEmergencyCallText.setVisibility(View.VISIBLE); 588 mEmergencyCallButton.setVisibility(View.VISIBLE); 589 break; 590 } 591 } 592 593 static CharSequence getCarrierString(CharSequence telephonyPlmn, CharSequence telephonySpn) { 594 if (telephonyPlmn != null && telephonySpn == null) { 595 return telephonyPlmn; 596 } else if (telephonyPlmn != null && telephonySpn != null) { 597 return telephonyPlmn + "|" + telephonySpn; 598 } else if (telephonyPlmn == null && telephonySpn != null) { 599 return telephonySpn; 600 } else { 601 return ""; 602 } 603 } 604 605 public void onSimStateChanged(IccCard.State simState) { 606 if (DBG) Log.d(TAG, "onSimStateChanged(" + simState + ")"); 607 mStatus = getCurrentStatus(simState); 608 updateLayout(mStatus); 609 updateStatusLines(); 610 } 611 612 void updateConfiguration() { 613 Configuration newConfig = getResources().getConfiguration(); 614 if (newConfig.orientation != mCreationOrientation) { 615 mCallback.recreateMe(newConfig); 616 } else if (newConfig.hardKeyboardHidden != mKeyboardHidden) { 617 mKeyboardHidden = newConfig.hardKeyboardHidden; 618 final boolean isKeyboardOpen = mKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO; 619 if (mUpdateMonitor.isKeyguardBypassEnabled() && isKeyboardOpen) { 620 mCallback.goToUnlockScreen(); 621 } 622 } 623 } 624 625 @Override 626 protected void onAttachedToWindow() { 627 super.onAttachedToWindow(); 628 if (LockPatternKeyguardView.DEBUG_CONFIGURATION) { 629 Log.v(TAG, "***** LOCK ATTACHED TO WINDOW"); 630 Log.v(TAG, "Cur orient=" + mCreationOrientation 631 + ", new config=" + getResources().getConfiguration()); 632 } 633 updateConfiguration(); 634 } 635 636 /** {@inheritDoc} */ 637 @Override 638 protected void onConfigurationChanged(Configuration newConfig) { 639 super.onConfigurationChanged(newConfig); 640 if (LockPatternKeyguardView.DEBUG_CONFIGURATION) { 641 Log.w(TAG, "***** LOCK CONFIG CHANGING", new RuntimeException()); 642 Log.v(TAG, "Cur orient=" + mCreationOrientation 643 + ", new config=" + newConfig); 644 } 645 updateConfiguration(); 646 } 647 648 /** {@inheritDoc} */ 649 public boolean needsInput() { 650 return false; 651 } 652 653 /** {@inheritDoc} */ 654 public void onPause() { 655 656 } 657 658 /** {@inheritDoc} */ 659 public void onResume() { 660 resetStatusInfo(mUpdateMonitor); 661 mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton); 662 } 663 664 /** {@inheritDoc} */ 665 public void cleanUp() { 666 mUpdateMonitor.removeCallback(this); 667 } 668 669 /** {@inheritDoc} */ 670 public void onRingerModeChanged(int state) { 671 boolean silent = AudioManager.RINGER_MODE_NORMAL != state; 672 if (silent != mSilentMode) { 673 mSilentMode = silent; 674 updateRightTabResources(); 675 } 676 } 677 678 public void onPhoneStateChanged(String newState) { 679 mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton); 680 } 681 } 682