Home | History | Annotate | Download | only in keyguard
      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 
     40     private static final int EMERGENCY_CALL_TIMEOUT = 10000; // screen timeout after starting e.d.
     41     private static final String ACTION_EMERGENCY_DIAL = "com.android.phone.EmergencyDialer.DIAL";
     42 
     43     KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
     44 
     45         @Override
     46         public void onSimStateChanged(State simState) {
     47             int phoneState = KeyguardUpdateMonitor.getInstance(mContext).getPhoneState();
     48             updateEmergencyCallButton(simState, phoneState);
     49         }
     50 
     51         void onPhoneStateChanged(int phoneState) {
     52             State simState = KeyguardUpdateMonitor.getInstance(mContext).getSimState();
     53             updateEmergencyCallButton(simState, phoneState);
     54         };
     55     };
     56     private LockPatternUtils mLockPatternUtils;
     57     private PowerManager mPowerManager;
     58 
     59     public EmergencyButton(Context context) {
     60         this(context, null);
     61     }
     62 
     63     public EmergencyButton(Context context, AttributeSet attrs) {
     64         super(context, attrs);
     65     }
     66 
     67     @Override
     68     protected void onAttachedToWindow() {
     69         super.onAttachedToWindow();
     70         KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mInfoCallback);
     71     }
     72 
     73     @Override
     74     protected void onDetachedFromWindow() {
     75         super.onDetachedFromWindow();
     76         KeyguardUpdateMonitor.getInstance(mContext).removeCallback(mInfoCallback);
     77     }
     78 
     79     @Override
     80     protected void onFinishInflate() {
     81         super.onFinishInflate();
     82         mLockPatternUtils = new LockPatternUtils(mContext);
     83         mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
     84         setOnClickListener(new OnClickListener() {
     85             public void onClick(View v) {
     86                 takeEmergencyCallAction();
     87             }
     88         });
     89         int phoneState = KeyguardUpdateMonitor.getInstance(mContext).getPhoneState();
     90         State simState = KeyguardUpdateMonitor.getInstance(mContext).getSimState();
     91         updateEmergencyCallButton(simState, phoneState);
     92     }
     93 
     94     /**
     95      * Shows the emergency dialer or returns the user to the existing call.
     96      */
     97     public void takeEmergencyCallAction() {
     98         // TODO: implement a shorter timeout once new PowerManager API is ready.
     99         // should be the equivalent to the old userActivity(EMERGENCY_CALL_TIMEOUT)
    100         mPowerManager.userActivity(SystemClock.uptimeMillis(), true);
    101         if (TelephonyManager.getDefault().getCallState()
    102                 == TelephonyManager.CALL_STATE_OFFHOOK) {
    103             mLockPatternUtils.resumeCall();
    104         } else {
    105             final boolean bypassHandler = true;
    106             KeyguardUpdateMonitor.getInstance(mContext).reportEmergencyCallAction(bypassHandler);
    107             Intent intent = new Intent(ACTION_EMERGENCY_DIAL);
    108             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
    109                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
    110             getContext().startActivityAsUser(intent,
    111                     new UserHandle(mLockPatternUtils.getCurrentUser()));
    112         }
    113     }
    114 
    115     private void updateEmergencyCallButton(State simState, int phoneState) {
    116         boolean enabled = false;
    117         if (phoneState == TelephonyManager.CALL_STATE_OFFHOOK) {
    118             enabled = true; // always show "return to call" if phone is off-hook
    119         } else if (mLockPatternUtils.isEmergencyCallCapable()) {
    120             boolean simLocked = KeyguardUpdateMonitor.getInstance(mContext).isSimLocked();
    121             if (simLocked) {
    122                 // Some countries can't handle emergency calls while SIM is locked.
    123                 enabled = mLockPatternUtils.isEmergencyCallEnabledWhileSimLocked();
    124             } else {
    125                 // True if we need to show a secure screen (pin/pattern/SIM pin/SIM puk);
    126                 // hides emergency button on "Slide" screen if device is not secure.
    127                 enabled = mLockPatternUtils.isSecure();
    128             }
    129         }
    130         mLockPatternUtils.updateEmergencyCallButtonState(this, phoneState, enabled, false);
    131     }
    132 
    133 }
    134