1 /* 2 * Copyright (C) 2021 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 static com.android.systemui.DejankUtils.whitelistIpcs; 20 21 import android.app.ActivityOptions; 22 import android.app.ActivityTaskManager; 23 import android.content.Intent; 24 import android.content.res.Configuration; 25 import android.os.PowerManager; 26 import android.os.SystemClock; 27 import android.os.UserHandle; 28 import android.telecom.TelecomManager; 29 import android.telephony.TelephonyManager; 30 import android.util.Log; 31 32 import androidx.annotation.Nullable; 33 34 import com.android.internal.logging.MetricsLogger; 35 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 36 import com.android.keyguard.dagger.KeyguardBouncerScope; 37 import com.android.systemui.statusbar.phone.ShadeController; 38 import com.android.systemui.statusbar.policy.ConfigurationController; 39 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener; 40 import com.android.systemui.util.EmergencyDialerConstants; 41 import com.android.systemui.util.ViewController; 42 43 import javax.inject.Inject; 44 45 /** View Controller for {@link com.android.keyguard.EmergencyButton}. */ 46 @KeyguardBouncerScope 47 public class EmergencyButtonController extends ViewController<EmergencyButton> { 48 static final String LOG_TAG = "EmergencyButton"; 49 private final ConfigurationController mConfigurationController; 50 private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; 51 private final TelephonyManager mTelephonyManager; 52 private final PowerManager mPowerManager; 53 private final ActivityTaskManager mActivityTaskManager; 54 private ShadeController mShadeController; 55 private final TelecomManager mTelecomManager; 56 private final MetricsLogger mMetricsLogger; 57 58 private EmergencyButtonCallback mEmergencyButtonCallback; 59 60 private final KeyguardUpdateMonitorCallback mInfoCallback = 61 new KeyguardUpdateMonitorCallback() { 62 @Override 63 public void onSimStateChanged(int subId, int slotId, int simState) { 64 updateEmergencyCallButton(); 65 } 66 67 @Override 68 public void onPhoneStateChanged(int phoneState) { 69 updateEmergencyCallButton(); 70 } 71 }; 72 73 private final ConfigurationListener mConfigurationListener = new ConfigurationListener() { 74 @Override 75 public void onConfigChanged(Configuration newConfig) { 76 updateEmergencyCallButton(); 77 } 78 }; 79 EmergencyButtonController(@ullable EmergencyButton view, ConfigurationController configurationController, KeyguardUpdateMonitor keyguardUpdateMonitor, TelephonyManager telephonyManager, PowerManager powerManager, ActivityTaskManager activityTaskManager, ShadeController shadeController, @Nullable TelecomManager telecomManager, MetricsLogger metricsLogger)80 private EmergencyButtonController(@Nullable EmergencyButton view, 81 ConfigurationController configurationController, 82 KeyguardUpdateMonitor keyguardUpdateMonitor, TelephonyManager telephonyManager, 83 PowerManager powerManager, ActivityTaskManager activityTaskManager, 84 ShadeController shadeController, 85 @Nullable TelecomManager telecomManager, MetricsLogger metricsLogger) { 86 super(view); 87 mConfigurationController = configurationController; 88 mKeyguardUpdateMonitor = keyguardUpdateMonitor; 89 mTelephonyManager = telephonyManager; 90 mPowerManager = powerManager; 91 mActivityTaskManager = activityTaskManager; 92 mShadeController = shadeController; 93 mTelecomManager = telecomManager; 94 mMetricsLogger = metricsLogger; 95 } 96 97 @Override onInit()98 protected void onInit() { 99 whitelistIpcs(this::updateEmergencyCallButton); 100 } 101 102 @Override onViewAttached()103 protected void onViewAttached() { 104 mKeyguardUpdateMonitor.registerCallback(mInfoCallback); 105 mConfigurationController.addCallback(mConfigurationListener); 106 mView.setOnClickListener(v -> takeEmergencyCallAction()); 107 } 108 109 @Override onViewDetached()110 protected void onViewDetached() { 111 mKeyguardUpdateMonitor.removeCallback(mInfoCallback); 112 mConfigurationController.removeCallback(mConfigurationListener); 113 } 114 updateEmergencyCallButton()115 private void updateEmergencyCallButton() { 116 if (mView != null) { 117 mView.updateEmergencyCallButton( 118 mTelecomManager != null && mTelecomManager.isInCall(), 119 mTelephonyManager.isVoiceCapable(), 120 mKeyguardUpdateMonitor.isSimPinVoiceSecure()); 121 } 122 } 123 setEmergencyButtonCallback(EmergencyButtonCallback callback)124 public void setEmergencyButtonCallback(EmergencyButtonCallback callback) { 125 mEmergencyButtonCallback = callback; 126 } 127 /** 128 * Shows the emergency dialer or returns the user to the existing call. 129 */ takeEmergencyCallAction()130 public void takeEmergencyCallAction() { 131 mMetricsLogger.action(MetricsEvent.ACTION_EMERGENCY_CALL); 132 if (mPowerManager != null) { 133 mPowerManager.userActivity(SystemClock.uptimeMillis(), true); 134 } 135 mActivityTaskManager.stopSystemLockTaskMode(); 136 mShadeController.collapsePanel(false); 137 if (mTelecomManager != null && mTelecomManager.isInCall()) { 138 mTelecomManager.showInCallScreen(false); 139 if (mEmergencyButtonCallback != null) { 140 mEmergencyButtonCallback.onEmergencyButtonClickedWhenInCall(); 141 } 142 } else { 143 mKeyguardUpdateMonitor.reportEmergencyCallAction(true /* bypassHandler */); 144 if (mTelecomManager == null) { 145 Log.wtf(LOG_TAG, "TelecomManager was null, cannot launch emergency dialer"); 146 return; 147 } 148 Intent emergencyDialIntent = 149 mTelecomManager.createLaunchEmergencyDialerIntent(null /* number*/) 150 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 151 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS 152 | Intent.FLAG_ACTIVITY_CLEAR_TOP) 153 .putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE, 154 EmergencyDialerConstants.ENTRY_TYPE_LOCKSCREEN_BUTTON); 155 156 getContext().startActivityAsUser(emergencyDialIntent, 157 ActivityOptions.makeCustomAnimation(getContext(), 0, 0).toBundle(), 158 new UserHandle(KeyguardUpdateMonitor.getCurrentUser())); 159 } 160 } 161 162 /** */ 163 public interface EmergencyButtonCallback { 164 /** */ onEmergencyButtonClickedWhenInCall()165 void onEmergencyButtonClickedWhenInCall(); 166 } 167 168 /** Injectable Factory for creating {@link EmergencyButtonController}. */ 169 public static class Factory { 170 private final ConfigurationController mConfigurationController; 171 private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; 172 private final TelephonyManager mTelephonyManager; 173 private final PowerManager mPowerManager; 174 private final ActivityTaskManager mActivityTaskManager; 175 private ShadeController mShadeController; 176 @Nullable 177 private final TelecomManager mTelecomManager; 178 private final MetricsLogger mMetricsLogger; 179 180 @Inject Factory(ConfigurationController configurationController, KeyguardUpdateMonitor keyguardUpdateMonitor, TelephonyManager telephonyManager, PowerManager powerManager, ActivityTaskManager activityTaskManager, ShadeController shadeController, @Nullable TelecomManager telecomManager, MetricsLogger metricsLogger)181 public Factory(ConfigurationController configurationController, 182 KeyguardUpdateMonitor keyguardUpdateMonitor, TelephonyManager telephonyManager, 183 PowerManager powerManager, ActivityTaskManager activityTaskManager, 184 ShadeController shadeController, 185 @Nullable TelecomManager telecomManager, MetricsLogger metricsLogger) { 186 187 mConfigurationController = configurationController; 188 mKeyguardUpdateMonitor = keyguardUpdateMonitor; 189 mTelephonyManager = telephonyManager; 190 mPowerManager = powerManager; 191 mActivityTaskManager = activityTaskManager; 192 mShadeController = shadeController; 193 mTelecomManager = telecomManager; 194 mMetricsLogger = metricsLogger; 195 } 196 197 /** Construct an {@link com.android.keyguard.EmergencyButtonController}. */ create(EmergencyButton view)198 public EmergencyButtonController create(EmergencyButton view) { 199 return new EmergencyButtonController(view, mConfigurationController, 200 mKeyguardUpdateMonitor, mTelephonyManager, mPowerManager, mActivityTaskManager, 201 mShadeController, 202 mTelecomManager, mMetricsLogger); 203 } 204 } 205 } 206