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.text.TextUtils; 21 import android.util.AttributeSet; 22 import android.view.MotionEvent; 23 import android.view.View; 24 import android.view.ViewConfiguration; 25 import android.widget.Button; 26 27 import com.android.internal.util.EmergencyAffordanceManager; 28 29 /** 30 * This class implements a smart emergency button that updates itself based 31 * on telephony state. When the phone is idle, it is an emergency call button. 32 * When there's a call in progress, it presents an appropriate message and 33 * allows the user to return to the call. 34 */ 35 public class EmergencyButton extends Button { 36 37 private final EmergencyAffordanceManager mEmergencyAffordanceManager; 38 39 private int mDownX; 40 private int mDownY; 41 private boolean mLongPressWasDragged; 42 43 private final boolean mEnableEmergencyCallWhileSimLocked; 44 EmergencyButton(Context context)45 public EmergencyButton(Context context) { 46 this(context, null); 47 } 48 EmergencyButton(Context context, AttributeSet attrs)49 public EmergencyButton(Context context, AttributeSet attrs) { 50 super(context, attrs); 51 mEnableEmergencyCallWhileSimLocked = mContext.getResources().getBoolean( 52 com.android.internal.R.bool.config_enable_emergency_call_while_sim_locked); 53 mEmergencyAffordanceManager = new EmergencyAffordanceManager(context); 54 } 55 56 @Override onFinishInflate()57 protected void onFinishInflate() { 58 super.onFinishInflate(); 59 if (mEmergencyAffordanceManager.needsEmergencyAffordance()) { 60 setOnLongClickListener(v -> { 61 boolean isEmergencyCallButton = getVisibility() == View.VISIBLE 62 && TextUtils.equals(getText(), getEmergencyButtonLabel()); 63 if (isEmergencyCallButton 64 && !mLongPressWasDragged 65 && mEmergencyAffordanceManager.needsEmergencyAffordance()) { 66 mEmergencyAffordanceManager.performEmergencyCall(); 67 return true; 68 } 69 return false; 70 }); 71 } 72 } 73 74 @Override onTouchEvent(MotionEvent event)75 public boolean onTouchEvent(MotionEvent event) { 76 final int x = (int) event.getX(); 77 final int y = (int) event.getY(); 78 if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { 79 mDownX = x; 80 mDownY = y; 81 mLongPressWasDragged = false; 82 } else { 83 final int xDiff = Math.abs(x - mDownX); 84 final int yDiff = Math.abs(y - mDownY); 85 int touchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop(); 86 if (Math.abs(yDiff) > touchSlop || Math.abs(xDiff) > touchSlop) { 87 mLongPressWasDragged = true; 88 } 89 } 90 return super.onTouchEvent(event); 91 } 92 93 @Override performLongClick()94 public boolean performLongClick() { 95 return super.performLongClick(); 96 } 97 updateEmergencyCallButton(boolean isInCall, boolean hasTelephonyRadio, boolean simLocked, boolean isSecure)98 void updateEmergencyCallButton(boolean isInCall, boolean hasTelephonyRadio, boolean simLocked, 99 boolean isSecure) { 100 boolean visible = false; 101 if (hasTelephonyRadio) { 102 // Emergency calling requires a telephony radio. 103 if (isInCall) { 104 visible = true; // always show "return to call" if phone is off-hook 105 } else { 106 if (simLocked) { 107 // Some countries can't handle emergency calls while SIM is locked. 108 visible = mEnableEmergencyCallWhileSimLocked; 109 } else { 110 // Only show if there is a secure screen (pin/pattern/SIM pin/SIM puk); 111 visible = isSecure; 112 } 113 } 114 } 115 if (visible) { 116 setVisibility(View.VISIBLE); 117 118 int textId; 119 if (isInCall) { 120 textId = com.android.internal.R.string.lockscreen_return_to_call; 121 } else { 122 textId = com.android.internal.R.string.lockscreen_emergency_call; 123 } 124 setText(textId); 125 } else { 126 setVisibility(View.GONE); 127 } 128 } 129 getEmergencyButtonLabel()130 private String getEmergencyButtonLabel() { 131 return mContext.getString(com.android.internal.R.string.lockscreen_emergency_call); 132 } 133 } 134