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.keyguard; 18 19 import android.content.Context; 20 import android.content.Intent; 21 import android.os.PowerManager; 22 import android.os.SystemClock; 23 import android.os.UserHandle; 24 import android.telephony.TelephonyManager; 25 import android.util.AttributeSet; 26 import android.view.View; 27 import android.widget.Button; 28 29 import com.android.internal.telephony.IccCardConstants.State; 30 import com.android.internal.widget.LockPatternUtils; 31 32 /** 33 * This class implements a smart emergency button that updates itself based 34 * on telephony state. When the phone is idle, it is an emergency call button. 35 * When there's a call in progress, it presents an appropriate message and 36 * allows the user to return to the call. 37 */ 38 public class EmergencyButton extends Button { 39 private static final String ACTION_EMERGENCY_DIAL = "com.android.phone.EmergencyDialer.DIAL"; 40 41 KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() { 42 43 @Override 44 public void onSimStateChanged(int subId, int slotId, State simState) { 45 updateEmergencyCallButton(); 46 } 47 48 @Override 49 public void onPhoneStateChanged(int phoneState) { 50 updateEmergencyCallButton(); 51 } 52 }; 53 private LockPatternUtils mLockPatternUtils; 54 private PowerManager mPowerManager; 55 EmergencyButton(Context context)56 public EmergencyButton(Context context) { 57 this(context, null); 58 } 59 EmergencyButton(Context context, AttributeSet attrs)60 public EmergencyButton(Context context, AttributeSet attrs) { 61 super(context, attrs); 62 } 63 64 @Override onAttachedToWindow()65 protected void onAttachedToWindow() { 66 super.onAttachedToWindow(); 67 KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mInfoCallback); 68 } 69 70 @Override onDetachedFromWindow()71 protected void onDetachedFromWindow() { 72 super.onDetachedFromWindow(); 73 KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mInfoCallback); 74 } 75 76 @Override onFinishInflate()77 protected void onFinishInflate() { 78 super.onFinishInflate(); 79 mLockPatternUtils = new LockPatternUtils(mContext); 80 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 81 setOnClickListener(new OnClickListener() { 82 public void onClick(View v) { 83 takeEmergencyCallAction(); 84 } 85 }); 86 updateEmergencyCallButton(); 87 } 88 89 /** 90 * Shows the emergency dialer or returns the user to the existing call. 91 */ takeEmergencyCallAction()92 public void takeEmergencyCallAction() { 93 // TODO: implement a shorter timeout once new PowerManager API is ready. 94 // should be the equivalent to the old userActivity(EMERGENCY_CALL_TIMEOUT) 95 mPowerManager.userActivity(SystemClock.uptimeMillis(), true); 96 if (mLockPatternUtils.isInCall()) { 97 mLockPatternUtils.resumeCall(); 98 } else { 99 final boolean bypassHandler = true; 100 KeyguardUpdateMonitor.getInstance(mContext).reportEmergencyCallAction(bypassHandler); 101 Intent intent = new Intent(ACTION_EMERGENCY_DIAL); 102 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 103 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 104 getContext().startActivityAsUser(intent, 105 new UserHandle(mLockPatternUtils.getCurrentUser())); 106 } 107 } 108 updateEmergencyCallButton()109 private void updateEmergencyCallButton() { 110 boolean enabled = false; 111 if (mLockPatternUtils.isInCall()) { 112 enabled = true; // always show "return to call" if phone is off-hook 113 } else if (mLockPatternUtils.isEmergencyCallCapable()) { 114 final boolean simLocked = KeyguardUpdateMonitor.getInstance(mContext).isSimPinVoiceSecure(); 115 if (simLocked) { 116 // Some countries can't handle emergency calls while SIM is locked. 117 enabled = mLockPatternUtils.isEmergencyCallEnabledWhileSimLocked(); 118 } else { 119 // True if we need to show a secure screen (pin/pattern/SIM pin/SIM puk); 120 // hides emergency button on "Slide" screen if device is not secure. 121 enabled = mLockPatternUtils.isSecure(); 122 } 123 } 124 mLockPatternUtils.updateEmergencyCallButtonState(this, enabled, false); 125 } 126 127 } 128