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