Merge changes from topic "change-13630081" into sc-dev
* changes: Revert^2 "Remove final calls to Dependency.get from keyguard." Revert^2 "Remove Dependency.get from KeyguardStatusView." Revert^2 "Add injection to ClockProvider." Revert^2 "Remove Dependency.get from KeyguardSliceTextView." Revert^2 "Add Controller for Emergency Button." Revert^2 "Add ViewController to CarrierText." Create central TelephonyListenerManager.
This commit is contained in:
@@ -24,41 +24,14 @@ import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.R;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class CarrierText extends TextView {
|
||||
private static final boolean DEBUG = KeyguardConstants.DEBUG;
|
||||
private static final String TAG = "CarrierText";
|
||||
private final boolean mShowMissingSim;
|
||||
|
||||
private static CharSequence mSeparator;
|
||||
|
||||
private boolean mShowMissingSim;
|
||||
|
||||
private boolean mShowAirplaneMode;
|
||||
private boolean mShouldMarquee;
|
||||
|
||||
private CarrierTextController mCarrierTextController;
|
||||
|
||||
private CarrierTextController.CarrierTextCallback mCarrierTextCallback =
|
||||
new CarrierTextController.CarrierTextCallback() {
|
||||
@Override
|
||||
public void updateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) {
|
||||
setText(info.carrierText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startedGoingToSleep() {
|
||||
setSelected(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishedWakingUp() {
|
||||
setSelected(true);
|
||||
}
|
||||
};
|
||||
private final boolean mShowAirplaneMode;
|
||||
|
||||
public CarrierText(Context context) {
|
||||
this(context, null);
|
||||
@@ -78,30 +51,6 @@ public class CarrierText extends TextView {
|
||||
}
|
||||
setTransformationMethod(new CarrierTextTransformationMethod(mContext, useAllCaps));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
mSeparator = getResources().getString(
|
||||
com.android.internal.R.string.kg_text_message_separator);
|
||||
mCarrierTextController = new CarrierTextController(mContext, mSeparator, mShowAirplaneMode,
|
||||
mShowMissingSim);
|
||||
mShouldMarquee = Dependency.get(KeyguardUpdateMonitor.class).isDeviceInteractive();
|
||||
setSelected(mShouldMarquee); // Allow marquee to work.
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
mCarrierTextController.setListening(mCarrierTextCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
mCarrierTextController.setListening(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onVisibilityChanged(View changedView, int visibility) {
|
||||
super.onVisibilityChanged(changedView, visibility);
|
||||
@@ -113,7 +62,15 @@ public class CarrierText extends TextView {
|
||||
}
|
||||
}
|
||||
|
||||
private class CarrierTextTransformationMethod extends SingleLineTransformationMethod {
|
||||
public boolean getShowAirplaneMode() {
|
||||
return mShowAirplaneMode;
|
||||
}
|
||||
|
||||
public boolean getShowMissingSim() {
|
||||
return mShowMissingSim;
|
||||
}
|
||||
|
||||
private static class CarrierTextTransformationMethod extends SingleLineTransformationMethod {
|
||||
private final Locale mLocale;
|
||||
private final boolean mAllCaps;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,680 +16,60 @@
|
||||
|
||||
package com.android.keyguard;
|
||||
|
||||
import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
|
||||
import static android.telephony.PhoneStateListener.LISTEN_NONE;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Handler;
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settingslib.WirelessUtils;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.keyguard.WakefulnessLifecycle;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import com.android.systemui.util.ViewController;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Controller that generates text including the carrier names and/or the status of all the SIM
|
||||
* interfaces in the device. Through a callback, the updates can be retrieved either as a list or
|
||||
* separated by a given separator {@link CharSequence}.
|
||||
* Controller for {@link CarrierText}.
|
||||
*/
|
||||
public class CarrierTextController {
|
||||
private static final boolean DEBUG = KeyguardConstants.DEBUG;
|
||||
private static final String TAG = "CarrierTextController";
|
||||
|
||||
private final boolean mIsEmergencyCallCapable;
|
||||
private final Handler mMainHandler;
|
||||
private final Handler mBgHandler;
|
||||
private boolean mTelephonyCapable;
|
||||
private boolean mShowMissingSim;
|
||||
private boolean mShowAirplaneMode;
|
||||
private final AtomicBoolean mNetworkSupported = new AtomicBoolean();
|
||||
@VisibleForTesting
|
||||
protected KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
private WifiManager mWifiManager;
|
||||
private boolean[] mSimErrorState;
|
||||
private final int mSimSlotsNumber;
|
||||
@Nullable // Check for nullability before dispatching
|
||||
private CarrierTextCallback mCarrierTextCallback;
|
||||
private Context mContext;
|
||||
private CharSequence mSeparator;
|
||||
private WakefulnessLifecycle mWakefulnessLifecycle;
|
||||
private final WakefulnessLifecycle.Observer mWakefulnessObserver =
|
||||
new WakefulnessLifecycle.Observer() {
|
||||
public class CarrierTextController extends ViewController<CarrierText> {
|
||||
private final CarrierTextManager mCarrierTextManager;
|
||||
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
private final CarrierTextManager.CarrierTextCallback mCarrierTextCallback =
|
||||
new CarrierTextManager.CarrierTextCallback() {
|
||||
@Override
|
||||
public void onFinishedWakingUp() {
|
||||
final CarrierTextCallback callback = mCarrierTextCallback;
|
||||
if (callback != null) callback.finishedWakingUp();
|
||||
public void updateCarrierInfo(CarrierTextManager.CarrierTextCallbackInfo info) {
|
||||
mView.setText(info.carrierText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartedGoingToSleep() {
|
||||
final CarrierTextCallback callback = mCarrierTextCallback;
|
||||
if (callback != null) callback.startedGoingToSleep();
|
||||
public void startedGoingToSleep() {
|
||||
mView.setSelected(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishedWakingUp() {
|
||||
mView.setSelected(true);
|
||||
}
|
||||
};
|
||||
|
||||
@VisibleForTesting
|
||||
protected final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
|
||||
@Override
|
||||
public void onRefreshCarrierInfo() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onRefreshCarrierInfo(), mTelephonyCapable: "
|
||||
+ Boolean.toString(mTelephonyCapable));
|
||||
}
|
||||
updateCarrierText();
|
||||
}
|
||||
@Inject
|
||||
public CarrierTextController(CarrierText view,
|
||||
CarrierTextManager.Builder carrierTextManagerBuilder,
|
||||
KeyguardUpdateMonitor keyguardUpdateMonitor) {
|
||||
super(view);
|
||||
|
||||
@Override
|
||||
public void onTelephonyCapable(boolean capable) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onTelephonyCapable() mTelephonyCapable: "
|
||||
+ Boolean.toString(capable));
|
||||
}
|
||||
mTelephonyCapable = capable;
|
||||
updateCarrierText();
|
||||
}
|
||||
|
||||
public void onSimStateChanged(int subId, int slotId, int simState) {
|
||||
if (slotId < 0 || slotId >= mSimSlotsNumber) {
|
||||
Log.d(TAG, "onSimStateChanged() - slotId invalid: " + slotId
|
||||
+ " mTelephonyCapable: " + Boolean.toString(mTelephonyCapable));
|
||||
return;
|
||||
}
|
||||
|
||||
if (DEBUG) Log.d(TAG, "onSimStateChanged: " + getStatusForIccState(simState));
|
||||
if (getStatusForIccState(simState) == CarrierTextController.StatusMode.SimIoError) {
|
||||
mSimErrorState[slotId] = true;
|
||||
updateCarrierText();
|
||||
} else if (mSimErrorState[slotId]) {
|
||||
mSimErrorState[slotId] = false;
|
||||
updateCarrierText();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
|
||||
@Override
|
||||
public void onActiveDataSubscriptionIdChanged(int subId) {
|
||||
mActiveMobileDataSubscription = subId;
|
||||
if (mNetworkSupported.get() && mCarrierTextCallback != null) {
|
||||
updateCarrierText();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The status of this lock screen. Primarily used for widgets on LockScreen.
|
||||
*/
|
||||
private enum StatusMode {
|
||||
Normal, // Normal case (sim card present, it's not locked)
|
||||
NetworkLocked, // SIM card is 'network locked'.
|
||||
SimMissing, // SIM card is missing.
|
||||
SimMissingLocked, // SIM card is missing, and device isn't provisioned; don't allow access
|
||||
SimPukLocked, // SIM card is PUK locked because SIM entered wrong too many times
|
||||
SimLocked, // SIM card is currently locked
|
||||
SimPermDisabled, // SIM card is permanently disabled due to PUK unlock failure
|
||||
SimNotReady, // SIM is not ready yet. May never be on devices w/o a SIM.
|
||||
SimIoError, // SIM card is faulty
|
||||
SimUnknown // SIM card is unknown
|
||||
mCarrierTextManager = carrierTextManagerBuilder
|
||||
.setShowAirplaneMode(mView.getShowAirplaneMode())
|
||||
.setShowMissingSim(mView.getShowMissingSim())
|
||||
.build();
|
||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controller that provides updates on text with carriers names or SIM status.
|
||||
* Used by {@link CarrierText}.
|
||||
*
|
||||
* @param separator Separator between different parts of the text
|
||||
*/
|
||||
public CarrierTextController(Context context, CharSequence separator, boolean showAirplaneMode,
|
||||
boolean showMissingSim) {
|
||||
mContext = context;
|
||||
mIsEmergencyCallCapable = getTelephonyManager().isVoiceCapable();
|
||||
|
||||
mShowAirplaneMode = showAirplaneMode;
|
||||
mShowMissingSim = showMissingSim;
|
||||
|
||||
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||
mSeparator = separator;
|
||||
mWakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class);
|
||||
mSimSlotsNumber = getTelephonyManager().getSupportedModemCount();
|
||||
mSimErrorState = new boolean[mSimSlotsNumber];
|
||||
mMainHandler = Dependency.get(Dependency.MAIN_HANDLER);
|
||||
mBgHandler = new Handler(Dependency.get(Dependency.BG_LOOPER));
|
||||
mKeyguardUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
|
||||
mBgHandler.post(() -> {
|
||||
boolean supported =
|
||||
mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
|
||||
if (supported && mNetworkSupported.compareAndSet(false, supported)) {
|
||||
// This will set/remove the listeners appropriately. Note that it will never double
|
||||
// add the listeners.
|
||||
handleSetListening(mCarrierTextCallback);
|
||||
}
|
||||
});
|
||||
@Override
|
||||
protected void onInit() {
|
||||
super.onInit();
|
||||
mView.setSelected(mKeyguardUpdateMonitor.isDeviceInteractive());
|
||||
}
|
||||
|
||||
private TelephonyManager getTelephonyManager() {
|
||||
return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
@Override
|
||||
protected void onViewAttached() {
|
||||
mCarrierTextManager.setListening(mCarrierTextCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there are faulty cards. Adds the text depending on the slot of the card
|
||||
*
|
||||
* @param text: current carrier text based on the sim state
|
||||
* @param carrierNames names order by subscription order
|
||||
* @param subOrderBySlot array containing the sub index for each slot ID
|
||||
* @param noSims: whether a valid sim card is inserted
|
||||
* @return text
|
||||
*/
|
||||
private CharSequence updateCarrierTextWithSimIoError(CharSequence text,
|
||||
CharSequence[] carrierNames, int[] subOrderBySlot, boolean noSims) {
|
||||
final CharSequence carrier = "";
|
||||
CharSequence carrierTextForSimIOError = getCarrierTextForSimState(
|
||||
TelephonyManager.SIM_STATE_CARD_IO_ERROR, carrier);
|
||||
// mSimErrorState has the state of each sim indexed by slotID.
|
||||
for (int index = 0; index < getTelephonyManager().getActiveModemCount(); index++) {
|
||||
if (!mSimErrorState[index]) {
|
||||
continue;
|
||||
}
|
||||
// In the case when no sim cards are detected but a faulty card is inserted
|
||||
// overwrite the text and only show "Invalid card"
|
||||
if (noSims) {
|
||||
return concatenate(carrierTextForSimIOError,
|
||||
getContext().getText(
|
||||
com.android.internal.R.string.emergency_calls_only),
|
||||
mSeparator);
|
||||
} else if (subOrderBySlot[index] != -1) {
|
||||
int subIndex = subOrderBySlot[index];
|
||||
// prepend "Invalid card" when faulty card is inserted in slot 0 or 1
|
||||
carrierNames[subIndex] = concatenate(carrierTextForSimIOError,
|
||||
carrierNames[subIndex],
|
||||
mSeparator);
|
||||
} else {
|
||||
// concatenate "Invalid card" when faulty card is inserted in other slot
|
||||
text = concatenate(text, carrierTextForSimIOError, mSeparator);
|
||||
}
|
||||
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* This may be called internally after retrieving the correct value of {@code mNetworkSupported}
|
||||
* (assumed false to start). In that case, the following happens:
|
||||
* <ul>
|
||||
* <li> If there was a registered callback, and the network is supported, it will register
|
||||
* listeners.
|
||||
* <li> If there was not a registered callback, it will try to remove unregistered listeners
|
||||
* which is a no-op
|
||||
* </ul>
|
||||
*
|
||||
* This call will always be processed in a background thread.
|
||||
*/
|
||||
private void handleSetListening(CarrierTextCallback callback) {
|
||||
TelephonyManager telephonyManager = getTelephonyManager();
|
||||
if (callback != null) {
|
||||
mCarrierTextCallback = callback;
|
||||
if (mNetworkSupported.get()) {
|
||||
// Keyguard update monitor expects callbacks from main thread
|
||||
mMainHandler.post(() -> mKeyguardUpdateMonitor.registerCallback(mCallback));
|
||||
mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
|
||||
telephonyManager.listen(mPhoneStateListener,
|
||||
LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
|
||||
} else {
|
||||
// Don't listen and clear out the text when the device isn't a phone.
|
||||
mMainHandler.post(() -> callback.updateCarrierInfo(
|
||||
new CarrierTextCallbackInfo("", null, false, null)
|
||||
));
|
||||
}
|
||||
} else {
|
||||
mCarrierTextCallback = null;
|
||||
mMainHandler.post(() -> mKeyguardUpdateMonitor.removeCallback(mCallback));
|
||||
mWakefulnessLifecycle.removeObserver(mWakefulnessObserver);
|
||||
telephonyManager.listen(mPhoneStateListener, LISTEN_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the listening status of this controller. If the callback is null, it is set to
|
||||
* not listening.
|
||||
*
|
||||
* @param callback Callback to provide text updates
|
||||
*/
|
||||
public void setListening(CarrierTextCallback callback) {
|
||||
mBgHandler.post(() -> handleSetListening(callback));
|
||||
}
|
||||
|
||||
protected List<SubscriptionInfo> getSubscriptionInfo() {
|
||||
return mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(false);
|
||||
}
|
||||
|
||||
protected void updateCarrierText() {
|
||||
boolean allSimsMissing = true;
|
||||
boolean anySimReadyAndInService = false;
|
||||
CharSequence displayText = null;
|
||||
List<SubscriptionInfo> subs = getSubscriptionInfo();
|
||||
|
||||
final int numSubs = subs.size();
|
||||
final int[] subsIds = new int[numSubs];
|
||||
// This array will contain in position i, the index of subscription in slot ID i.
|
||||
// -1 if no subscription in that slot
|
||||
final int[] subOrderBySlot = new int[mSimSlotsNumber];
|
||||
for (int i = 0; i < mSimSlotsNumber; i++) {
|
||||
subOrderBySlot[i] = -1;
|
||||
}
|
||||
final CharSequence[] carrierNames = new CharSequence[numSubs];
|
||||
if (DEBUG) Log.d(TAG, "updateCarrierText(): " + numSubs);
|
||||
|
||||
for (int i = 0; i < numSubs; i++) {
|
||||
int subId = subs.get(i).getSubscriptionId();
|
||||
carrierNames[i] = "";
|
||||
subsIds[i] = subId;
|
||||
subOrderBySlot[subs.get(i).getSimSlotIndex()] = i;
|
||||
int simState = mKeyguardUpdateMonitor.getSimState(subId);
|
||||
CharSequence carrierName = subs.get(i).getCarrierName();
|
||||
CharSequence carrierTextForSimState = getCarrierTextForSimState(simState, carrierName);
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Handling (subId=" + subId + "): " + simState + " " + carrierName);
|
||||
}
|
||||
if (carrierTextForSimState != null) {
|
||||
allSimsMissing = false;
|
||||
carrierNames[i] = carrierTextForSimState;
|
||||
}
|
||||
if (simState == TelephonyManager.SIM_STATE_READY) {
|
||||
ServiceState ss = mKeyguardUpdateMonitor.mServiceStates.get(subId);
|
||||
if (ss != null && ss.getDataRegistrationState() == ServiceState.STATE_IN_SERVICE) {
|
||||
// hack for WFC (IWLAN) not turning off immediately once
|
||||
// Wi-Fi is disassociated or disabled
|
||||
if (ss.getRilDataRadioTechnology() != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
|
||||
|| (mWifiManager.isWifiEnabled()
|
||||
&& mWifiManager.getConnectionInfo() != null
|
||||
&& mWifiManager.getConnectionInfo().getBSSID() != null)) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "SIM ready and in service: subId=" + subId + ", ss=" + ss);
|
||||
}
|
||||
anySimReadyAndInService = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Only create "No SIM card" if no cards with CarrierName && no wifi when some sim is READY
|
||||
// This condition will also be true always when numSubs == 0
|
||||
if (allSimsMissing && !anySimReadyAndInService) {
|
||||
if (numSubs != 0) {
|
||||
// Shows "No SIM card | Emergency calls only" on devices that are voice-capable.
|
||||
// This depends on mPlmn containing the text "Emergency calls only" when the radio
|
||||
// has some connectivity. Otherwise, it should be null or empty and just show
|
||||
// "No SIM card"
|
||||
// Grab the first subscripton, because they all should contain the emergency text,
|
||||
// described above.
|
||||
displayText = makeCarrierStringOnEmergencyCapable(
|
||||
getMissingSimMessage(), subs.get(0).getCarrierName());
|
||||
} else {
|
||||
// We don't have a SubscriptionInfo to get the emergency calls only from.
|
||||
// Grab it from the old sticky broadcast if possible instead. We can use it
|
||||
// here because no subscriptions are active, so we don't have
|
||||
// to worry about MSIM clashing.
|
||||
CharSequence text =
|
||||
getContext().getText(com.android.internal.R.string.emergency_calls_only);
|
||||
Intent i = getContext().registerReceiver(null,
|
||||
new IntentFilter(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED));
|
||||
if (i != null) {
|
||||
String spn = "";
|
||||
String plmn = "";
|
||||
if (i.getBooleanExtra(TelephonyManager.EXTRA_SHOW_SPN, false)) {
|
||||
spn = i.getStringExtra(TelephonyManager.EXTRA_SPN);
|
||||
}
|
||||
if (i.getBooleanExtra(TelephonyManager.EXTRA_SHOW_PLMN, false)) {
|
||||
plmn = i.getStringExtra(TelephonyManager.EXTRA_PLMN);
|
||||
}
|
||||
if (DEBUG) Log.d(TAG, "Getting plmn/spn sticky brdcst " + plmn + "/" + spn);
|
||||
if (Objects.equals(plmn, spn)) {
|
||||
text = plmn;
|
||||
} else {
|
||||
text = concatenate(plmn, spn, mSeparator);
|
||||
}
|
||||
}
|
||||
displayText = makeCarrierStringOnEmergencyCapable(getMissingSimMessage(), text);
|
||||
}
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(displayText)) displayText = joinNotEmpty(mSeparator, carrierNames);
|
||||
|
||||
displayText = updateCarrierTextWithSimIoError(displayText, carrierNames, subOrderBySlot,
|
||||
allSimsMissing);
|
||||
|
||||
boolean airplaneMode = false;
|
||||
// APM (airplane mode) != no carrier state. There are carrier services
|
||||
// (e.g. WFC = Wi-Fi calling) which may operate in APM.
|
||||
if (!anySimReadyAndInService && WirelessUtils.isAirplaneModeOn(mContext)) {
|
||||
displayText = getAirplaneModeMessage();
|
||||
airplaneMode = true;
|
||||
}
|
||||
|
||||
final CarrierTextCallbackInfo info = new CarrierTextCallbackInfo(
|
||||
displayText,
|
||||
carrierNames,
|
||||
!allSimsMissing,
|
||||
subsIds,
|
||||
airplaneMode);
|
||||
postToCallback(info);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected void postToCallback(CarrierTextCallbackInfo info) {
|
||||
final CarrierTextCallback callback = mCarrierTextCallback;
|
||||
if (callback != null) {
|
||||
mMainHandler.post(() -> callback.updateCarrierInfo(info));
|
||||
}
|
||||
}
|
||||
|
||||
private Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
private String getMissingSimMessage() {
|
||||
return mShowMissingSim && mTelephonyCapable
|
||||
? getContext().getString(R.string.keyguard_missing_sim_message_short) : "";
|
||||
}
|
||||
|
||||
private String getAirplaneModeMessage() {
|
||||
return mShowAirplaneMode
|
||||
? getContext().getString(R.string.airplane_mode) : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Top-level function for creating carrier text. Makes text based on simState, PLMN
|
||||
* and SPN as well as device capabilities, such as being emergency call capable.
|
||||
*
|
||||
* @return Carrier text if not in missing state, null otherwise.
|
||||
*/
|
||||
private CharSequence getCarrierTextForSimState(int simState, CharSequence text) {
|
||||
CharSequence carrierText = null;
|
||||
CarrierTextController.StatusMode status = getStatusForIccState(simState);
|
||||
switch (status) {
|
||||
case Normal:
|
||||
carrierText = text;
|
||||
break;
|
||||
|
||||
case SimNotReady:
|
||||
// Null is reserved for denoting missing, in this case we have nothing to display.
|
||||
carrierText = ""; // nothing to display yet.
|
||||
break;
|
||||
|
||||
case NetworkLocked:
|
||||
carrierText = makeCarrierStringOnEmergencyCapable(
|
||||
mContext.getText(R.string.keyguard_network_locked_message), text);
|
||||
break;
|
||||
|
||||
case SimMissing:
|
||||
carrierText = null;
|
||||
break;
|
||||
|
||||
case SimPermDisabled:
|
||||
carrierText = makeCarrierStringOnEmergencyCapable(
|
||||
getContext().getText(
|
||||
R.string.keyguard_permanent_disabled_sim_message_short),
|
||||
text);
|
||||
break;
|
||||
|
||||
case SimMissingLocked:
|
||||
carrierText = null;
|
||||
break;
|
||||
|
||||
case SimLocked:
|
||||
carrierText = makeCarrierStringOnLocked(
|
||||
getContext().getText(R.string.keyguard_sim_locked_message),
|
||||
text);
|
||||
break;
|
||||
|
||||
case SimPukLocked:
|
||||
carrierText = makeCarrierStringOnLocked(
|
||||
getContext().getText(R.string.keyguard_sim_puk_locked_message),
|
||||
text);
|
||||
break;
|
||||
case SimIoError:
|
||||
carrierText = makeCarrierStringOnEmergencyCapable(
|
||||
getContext().getText(R.string.keyguard_sim_error_message_short),
|
||||
text);
|
||||
break;
|
||||
case SimUnknown:
|
||||
carrierText = null;
|
||||
break;
|
||||
}
|
||||
|
||||
return carrierText;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add emergencyCallMessage to carrier string only if phone supports emergency calls.
|
||||
*/
|
||||
private CharSequence makeCarrierStringOnEmergencyCapable(
|
||||
CharSequence simMessage, CharSequence emergencyCallMessage) {
|
||||
if (mIsEmergencyCallCapable) {
|
||||
return concatenate(simMessage, emergencyCallMessage, mSeparator);
|
||||
}
|
||||
return simMessage;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add "SIM card is locked" in parenthesis after carrier name, so it is easily associated in
|
||||
* DSDS
|
||||
*/
|
||||
private CharSequence makeCarrierStringOnLocked(CharSequence simMessage,
|
||||
CharSequence carrierName) {
|
||||
final boolean simMessageValid = !TextUtils.isEmpty(simMessage);
|
||||
final boolean carrierNameValid = !TextUtils.isEmpty(carrierName);
|
||||
if (simMessageValid && carrierNameValid) {
|
||||
return mContext.getString(R.string.keyguard_carrier_name_with_sim_locked_template,
|
||||
carrierName, simMessage);
|
||||
} else if (simMessageValid) {
|
||||
return simMessage;
|
||||
} else if (carrierNameValid) {
|
||||
return carrierName;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the current status of the lock screen given the SIM state and other stuff.
|
||||
*/
|
||||
private CarrierTextController.StatusMode getStatusForIccState(int simState) {
|
||||
final boolean missingAndNotProvisioned =
|
||||
!mKeyguardUpdateMonitor.isDeviceProvisioned()
|
||||
&& (simState == TelephonyManager.SIM_STATE_ABSENT
|
||||
|| simState == TelephonyManager.SIM_STATE_PERM_DISABLED);
|
||||
|
||||
// Assume we're NETWORK_LOCKED if not provisioned
|
||||
simState = missingAndNotProvisioned ? TelephonyManager.SIM_STATE_NETWORK_LOCKED : simState;
|
||||
switch (simState) {
|
||||
case TelephonyManager.SIM_STATE_ABSENT:
|
||||
return CarrierTextController.StatusMode.SimMissing;
|
||||
case TelephonyManager.SIM_STATE_NETWORK_LOCKED:
|
||||
return CarrierTextController.StatusMode.SimMissingLocked;
|
||||
case TelephonyManager.SIM_STATE_NOT_READY:
|
||||
return CarrierTextController.StatusMode.SimNotReady;
|
||||
case TelephonyManager.SIM_STATE_PIN_REQUIRED:
|
||||
return CarrierTextController.StatusMode.SimLocked;
|
||||
case TelephonyManager.SIM_STATE_PUK_REQUIRED:
|
||||
return CarrierTextController.StatusMode.SimPukLocked;
|
||||
case TelephonyManager.SIM_STATE_READY:
|
||||
return CarrierTextController.StatusMode.Normal;
|
||||
case TelephonyManager.SIM_STATE_PERM_DISABLED:
|
||||
return CarrierTextController.StatusMode.SimPermDisabled;
|
||||
case TelephonyManager.SIM_STATE_UNKNOWN:
|
||||
return CarrierTextController.StatusMode.SimUnknown;
|
||||
case TelephonyManager.SIM_STATE_CARD_IO_ERROR:
|
||||
return CarrierTextController.StatusMode.SimIoError;
|
||||
}
|
||||
return CarrierTextController.StatusMode.SimUnknown;
|
||||
}
|
||||
|
||||
private static CharSequence concatenate(CharSequence plmn, CharSequence spn,
|
||||
CharSequence separator) {
|
||||
final boolean plmnValid = !TextUtils.isEmpty(plmn);
|
||||
final boolean spnValid = !TextUtils.isEmpty(spn);
|
||||
if (plmnValid && spnValid) {
|
||||
return new StringBuilder().append(plmn).append(separator).append(spn).toString();
|
||||
} else if (plmnValid) {
|
||||
return plmn;
|
||||
} else if (spnValid) {
|
||||
return spn;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins the strings in a sequence using a separator. Empty strings are discarded with no extra
|
||||
* separator added so there are no extra separators that are not needed.
|
||||
*/
|
||||
private static CharSequence joinNotEmpty(CharSequence separator, CharSequence[] sequences) {
|
||||
int length = sequences.length;
|
||||
if (length == 0) return "";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (!TextUtils.isEmpty(sequences[i])) {
|
||||
if (!TextUtils.isEmpty(sb)) {
|
||||
sb.append(separator);
|
||||
}
|
||||
sb.append(sequences[i]);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static List<CharSequence> append(List<CharSequence> list, CharSequence string) {
|
||||
if (!TextUtils.isEmpty(string)) {
|
||||
list.add(string);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private CharSequence getCarrierHelpTextForSimState(int simState,
|
||||
String plmn, String spn) {
|
||||
int carrierHelpTextId = 0;
|
||||
CarrierTextController.StatusMode status = getStatusForIccState(simState);
|
||||
switch (status) {
|
||||
case NetworkLocked:
|
||||
carrierHelpTextId = R.string.keyguard_instructions_when_pattern_disabled;
|
||||
break;
|
||||
|
||||
case SimMissing:
|
||||
carrierHelpTextId = R.string.keyguard_missing_sim_instructions_long;
|
||||
break;
|
||||
|
||||
case SimPermDisabled:
|
||||
carrierHelpTextId = R.string.keyguard_permanent_disabled_sim_instructions;
|
||||
break;
|
||||
|
||||
case SimMissingLocked:
|
||||
carrierHelpTextId = R.string.keyguard_missing_sim_instructions;
|
||||
break;
|
||||
|
||||
case Normal:
|
||||
case SimLocked:
|
||||
case SimPukLocked:
|
||||
break;
|
||||
}
|
||||
|
||||
return mContext.getText(carrierHelpTextId);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final Context mContext;
|
||||
private final String mSeparator;
|
||||
private boolean mShowAirplaneMode;
|
||||
private boolean mShowMissingSim;
|
||||
|
||||
@Inject
|
||||
public Builder(Context context, @Main Resources resources) {
|
||||
mContext = context;
|
||||
mSeparator = resources.getString(
|
||||
com.android.internal.R.string.kg_text_message_separator);
|
||||
}
|
||||
|
||||
|
||||
public Builder setShowAirplaneMode(boolean showAirplaneMode) {
|
||||
mShowAirplaneMode = showAirplaneMode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setShowMissingSim(boolean showMissingSim) {
|
||||
mShowMissingSim = showMissingSim;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CarrierTextController build() {
|
||||
return new CarrierTextController(
|
||||
mContext, mSeparator, mShowAirplaneMode, mShowMissingSim);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Data structure for passing information to CarrierTextController subscribers
|
||||
*/
|
||||
public static final class CarrierTextCallbackInfo {
|
||||
public final CharSequence carrierText;
|
||||
public final CharSequence[] listOfCarriers;
|
||||
public final boolean anySimReady;
|
||||
public final int[] subscriptionIds;
|
||||
public boolean airplaneMode;
|
||||
|
||||
@VisibleForTesting
|
||||
public CarrierTextCallbackInfo(CharSequence carrierText, CharSequence[] listOfCarriers,
|
||||
boolean anySimReady, int[] subscriptionIds) {
|
||||
this(carrierText, listOfCarriers, anySimReady, subscriptionIds, false);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public CarrierTextCallbackInfo(CharSequence carrierText, CharSequence[] listOfCarriers,
|
||||
boolean anySimReady, int[] subscriptionIds, boolean airplaneMode) {
|
||||
this.carrierText = carrierText;
|
||||
this.listOfCarriers = listOfCarriers;
|
||||
this.anySimReady = anySimReady;
|
||||
this.subscriptionIds = subscriptionIds;
|
||||
this.airplaneMode = airplaneMode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to communicate to Views
|
||||
*/
|
||||
public interface CarrierTextCallback {
|
||||
/**
|
||||
* Provides updated carrier information.
|
||||
*/
|
||||
default void updateCarrierInfo(CarrierTextCallbackInfo info) {};
|
||||
|
||||
/**
|
||||
* Notifies the View that the device is going to sleep
|
||||
*/
|
||||
default void startedGoingToSleep() {};
|
||||
|
||||
/**
|
||||
* Notifies the View that the device finished waking up
|
||||
*/
|
||||
default void finishedWakingUp() {};
|
||||
@Override
|
||||
protected void onViewDetached() {
|
||||
mCarrierTextManager.setListening(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,721 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.keyguard;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settingslib.WirelessUtils;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.dagger.qualifiers.Background;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.keyguard.WakefulnessLifecycle;
|
||||
import com.android.systemui.telephony.TelephonyListenerManager;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Controller that generates text including the carrier names and/or the status of all the SIM
|
||||
* interfaces in the device. Through a callback, the updates can be retrieved either as a list or
|
||||
* separated by a given separator {@link CharSequence}.
|
||||
*/
|
||||
public class CarrierTextManager {
|
||||
private static final boolean DEBUG = KeyguardConstants.DEBUG;
|
||||
private static final String TAG = "CarrierTextController";
|
||||
|
||||
private final boolean mIsEmergencyCallCapable;
|
||||
private final Executor mMainExecutor;
|
||||
private final Executor mBgExecutor;
|
||||
private boolean mTelephonyCapable;
|
||||
private final boolean mShowMissingSim;
|
||||
private final boolean mShowAirplaneMode;
|
||||
private final AtomicBoolean mNetworkSupported = new AtomicBoolean();
|
||||
@VisibleForTesting
|
||||
protected KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
private final WifiManager mWifiManager;
|
||||
private final boolean[] mSimErrorState;
|
||||
private final int mSimSlotsNumber;
|
||||
@Nullable // Check for nullability before dispatching
|
||||
private CarrierTextCallback mCarrierTextCallback;
|
||||
private final Context mContext;
|
||||
private final TelephonyManager mTelephonyManager;
|
||||
private final CharSequence mSeparator;
|
||||
private final TelephonyListenerManager mTelephonyListenerManager;
|
||||
private final WakefulnessLifecycle mWakefulnessLifecycle;
|
||||
private final WakefulnessLifecycle.Observer mWakefulnessObserver =
|
||||
new WakefulnessLifecycle.Observer() {
|
||||
@Override
|
||||
public void onFinishedWakingUp() {
|
||||
final CarrierTextCallback callback = mCarrierTextCallback;
|
||||
if (callback != null) callback.finishedWakingUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartedGoingToSleep() {
|
||||
final CarrierTextCallback callback = mCarrierTextCallback;
|
||||
if (callback != null) callback.startedGoingToSleep();
|
||||
}
|
||||
};
|
||||
|
||||
@VisibleForTesting
|
||||
protected final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
|
||||
@Override
|
||||
public void onRefreshCarrierInfo() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onRefreshCarrierInfo(), mTelephonyCapable: "
|
||||
+ Boolean.toString(mTelephonyCapable));
|
||||
}
|
||||
updateCarrierText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTelephonyCapable(boolean capable) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onTelephonyCapable() mTelephonyCapable: "
|
||||
+ Boolean.toString(capable));
|
||||
}
|
||||
mTelephonyCapable = capable;
|
||||
updateCarrierText();
|
||||
}
|
||||
|
||||
public void onSimStateChanged(int subId, int slotId, int simState) {
|
||||
if (slotId < 0 || slotId >= mSimSlotsNumber) {
|
||||
Log.d(TAG, "onSimStateChanged() - slotId invalid: " + slotId
|
||||
+ " mTelephonyCapable: " + Boolean.toString(mTelephonyCapable));
|
||||
return;
|
||||
}
|
||||
|
||||
if (DEBUG) Log.d(TAG, "onSimStateChanged: " + getStatusForIccState(simState));
|
||||
if (getStatusForIccState(simState) == CarrierTextManager.StatusMode.SimIoError) {
|
||||
mSimErrorState[slotId] = true;
|
||||
updateCarrierText();
|
||||
} else if (mSimErrorState[slotId]) {
|
||||
mSimErrorState[slotId] = false;
|
||||
updateCarrierText();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final ActiveDataSubscriptionIdListener mPhoneStateListener =
|
||||
new ActiveDataSubscriptionIdListener() {
|
||||
@Override
|
||||
public void onActiveDataSubscriptionIdChanged(int subId) {
|
||||
if (mNetworkSupported.get() && mCarrierTextCallback != null) {
|
||||
updateCarrierText();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* The status of this lock screen. Primarily used for widgets on LockScreen.
|
||||
*/
|
||||
private enum StatusMode {
|
||||
Normal, // Normal case (sim card present, it's not locked)
|
||||
NetworkLocked, // SIM card is 'network locked'.
|
||||
SimMissing, // SIM card is missing.
|
||||
SimMissingLocked, // SIM card is missing, and device isn't provisioned; don't allow access
|
||||
SimPukLocked, // SIM card is PUK locked because SIM entered wrong too many times
|
||||
SimLocked, // SIM card is currently locked
|
||||
SimPermDisabled, // SIM card is permanently disabled due to PUK unlock failure
|
||||
SimNotReady, // SIM is not ready yet. May never be on devices w/o a SIM.
|
||||
SimIoError, // SIM card is faulty
|
||||
SimUnknown // SIM card is unknown
|
||||
}
|
||||
|
||||
/**
|
||||
* Controller that provides updates on text with carriers names or SIM status.
|
||||
* Used by {@link CarrierText}.
|
||||
*
|
||||
* @param separator Separator between different parts of the text
|
||||
*/
|
||||
private CarrierTextManager(Context context, CharSequence separator, boolean showAirplaneMode,
|
||||
boolean showMissingSim, @Nullable WifiManager wifiManager,
|
||||
TelephonyManager telephonyManager, TelephonyListenerManager telephonyListenerManager,
|
||||
WakefulnessLifecycle wakefulnessLifecycle, @Main Executor mainExecutor,
|
||||
@Background Executor bgExecutor, KeyguardUpdateMonitor keyguardUpdateMonitor) {
|
||||
mContext = context;
|
||||
mIsEmergencyCallCapable = telephonyManager.isVoiceCapable();
|
||||
|
||||
mShowAirplaneMode = showAirplaneMode;
|
||||
mShowMissingSim = showMissingSim;
|
||||
|
||||
mWifiManager = wifiManager;
|
||||
mTelephonyManager = telephonyManager;
|
||||
mSeparator = separator;
|
||||
mTelephonyListenerManager = telephonyListenerManager;
|
||||
mWakefulnessLifecycle = wakefulnessLifecycle;
|
||||
mSimSlotsNumber = getTelephonyManager().getSupportedModemCount();
|
||||
mSimErrorState = new boolean[mSimSlotsNumber];
|
||||
mMainExecutor = mainExecutor;
|
||||
mBgExecutor = bgExecutor;
|
||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
||||
mBgExecutor.execute(() -> {
|
||||
boolean supported = mContext.getPackageManager()
|
||||
.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
|
||||
if (supported && mNetworkSupported.compareAndSet(false, supported)) {
|
||||
// This will set/remove the listeners appropriately. Note that it will never double
|
||||
// add the listeners.
|
||||
handleSetListening(mCarrierTextCallback);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private TelephonyManager getTelephonyManager() {
|
||||
return mTelephonyManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there are faulty cards. Adds the text depending on the slot of the card
|
||||
*
|
||||
* @param text: current carrier text based on the sim state
|
||||
* @param carrierNames names order by subscription order
|
||||
* @param subOrderBySlot array containing the sub index for each slot ID
|
||||
* @param noSims: whether a valid sim card is inserted
|
||||
* @return text
|
||||
*/
|
||||
private CharSequence updateCarrierTextWithSimIoError(CharSequence text,
|
||||
CharSequence[] carrierNames, int[] subOrderBySlot, boolean noSims) {
|
||||
final CharSequence carrier = "";
|
||||
CharSequence carrierTextForSimIOError = getCarrierTextForSimState(
|
||||
TelephonyManager.SIM_STATE_CARD_IO_ERROR, carrier);
|
||||
// mSimErrorState has the state of each sim indexed by slotID.
|
||||
for (int index = 0; index < getTelephonyManager().getActiveModemCount(); index++) {
|
||||
if (!mSimErrorState[index]) {
|
||||
continue;
|
||||
}
|
||||
// In the case when no sim cards are detected but a faulty card is inserted
|
||||
// overwrite the text and only show "Invalid card"
|
||||
if (noSims) {
|
||||
return concatenate(carrierTextForSimIOError,
|
||||
getContext().getText(
|
||||
com.android.internal.R.string.emergency_calls_only),
|
||||
mSeparator);
|
||||
} else if (subOrderBySlot[index] != -1) {
|
||||
int subIndex = subOrderBySlot[index];
|
||||
// prepend "Invalid card" when faulty card is inserted in slot 0 or 1
|
||||
carrierNames[subIndex] = concatenate(carrierTextForSimIOError,
|
||||
carrierNames[subIndex],
|
||||
mSeparator);
|
||||
} else {
|
||||
// concatenate "Invalid card" when faulty card is inserted in other slot
|
||||
text = concatenate(text, carrierTextForSimIOError, mSeparator);
|
||||
}
|
||||
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* This may be called internally after retrieving the correct value of {@code mNetworkSupported}
|
||||
* (assumed false to start). In that case, the following happens:
|
||||
* <ul>
|
||||
* <li> If there was a registered callback, and the network is supported, it will register
|
||||
* listeners.
|
||||
* <li> If there was not a registered callback, it will try to remove unregistered listeners
|
||||
* which is a no-op
|
||||
* </ul>
|
||||
*
|
||||
* This call will always be processed in a background thread.
|
||||
*/
|
||||
private void handleSetListening(CarrierTextCallback callback) {
|
||||
if (callback != null) {
|
||||
mCarrierTextCallback = callback;
|
||||
if (mNetworkSupported.get()) {
|
||||
// Keyguard update monitor expects callbacks from main thread
|
||||
mMainExecutor.execute(() -> mKeyguardUpdateMonitor.registerCallback(mCallback));
|
||||
mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
|
||||
mTelephonyListenerManager.addActiveDataSubscriptionIdListener(mPhoneStateListener);
|
||||
} else {
|
||||
// Don't listen and clear out the text when the device isn't a phone.
|
||||
mMainExecutor.execute(() -> callback.updateCarrierInfo(
|
||||
new CarrierTextCallbackInfo("", null, false, null)
|
||||
));
|
||||
}
|
||||
} else {
|
||||
mCarrierTextCallback = null;
|
||||
mMainExecutor.execute(() -> mKeyguardUpdateMonitor.removeCallback(mCallback));
|
||||
mWakefulnessLifecycle.removeObserver(mWakefulnessObserver);
|
||||
mTelephonyListenerManager.removeActiveDataSubscriptionIdListener(mPhoneStateListener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the listening status of this controller. If the callback is null, it is set to
|
||||
* not listening.
|
||||
*
|
||||
* @param callback Callback to provide text updates
|
||||
*/
|
||||
public void setListening(CarrierTextCallback callback) {
|
||||
mBgExecutor.execute(() -> handleSetListening(callback));
|
||||
}
|
||||
|
||||
protected List<SubscriptionInfo> getSubscriptionInfo() {
|
||||
return mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(false);
|
||||
}
|
||||
|
||||
protected void updateCarrierText() {
|
||||
boolean allSimsMissing = true;
|
||||
boolean anySimReadyAndInService = false;
|
||||
CharSequence displayText = null;
|
||||
List<SubscriptionInfo> subs = getSubscriptionInfo();
|
||||
|
||||
final int numSubs = subs.size();
|
||||
final int[] subsIds = new int[numSubs];
|
||||
// This array will contain in position i, the index of subscription in slot ID i.
|
||||
// -1 if no subscription in that slot
|
||||
final int[] subOrderBySlot = new int[mSimSlotsNumber];
|
||||
for (int i = 0; i < mSimSlotsNumber; i++) {
|
||||
subOrderBySlot[i] = -1;
|
||||
}
|
||||
final CharSequence[] carrierNames = new CharSequence[numSubs];
|
||||
if (DEBUG) Log.d(TAG, "updateCarrierText(): " + numSubs);
|
||||
|
||||
for (int i = 0; i < numSubs; i++) {
|
||||
int subId = subs.get(i).getSubscriptionId();
|
||||
carrierNames[i] = "";
|
||||
subsIds[i] = subId;
|
||||
subOrderBySlot[subs.get(i).getSimSlotIndex()] = i;
|
||||
int simState = mKeyguardUpdateMonitor.getSimState(subId);
|
||||
CharSequence carrierName = subs.get(i).getCarrierName();
|
||||
CharSequence carrierTextForSimState = getCarrierTextForSimState(simState, carrierName);
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Handling (subId=" + subId + "): " + simState + " " + carrierName);
|
||||
}
|
||||
if (carrierTextForSimState != null) {
|
||||
allSimsMissing = false;
|
||||
carrierNames[i] = carrierTextForSimState;
|
||||
}
|
||||
if (simState == TelephonyManager.SIM_STATE_READY) {
|
||||
ServiceState ss = mKeyguardUpdateMonitor.mServiceStates.get(subId);
|
||||
if (ss != null && ss.getDataRegistrationState() == ServiceState.STATE_IN_SERVICE) {
|
||||
// hack for WFC (IWLAN) not turning off immediately once
|
||||
// Wi-Fi is disassociated or disabled
|
||||
if (ss.getRilDataRadioTechnology() != ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
|
||||
|| (mWifiManager != null && mWifiManager.isWifiEnabled()
|
||||
&& mWifiManager.getConnectionInfo() != null
|
||||
&& mWifiManager.getConnectionInfo().getBSSID() != null)) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "SIM ready and in service: subId=" + subId + ", ss=" + ss);
|
||||
}
|
||||
anySimReadyAndInService = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Only create "No SIM card" if no cards with CarrierName && no wifi when some sim is READY
|
||||
// This condition will also be true always when numSubs == 0
|
||||
if (allSimsMissing && !anySimReadyAndInService) {
|
||||
if (numSubs != 0) {
|
||||
// Shows "No SIM card | Emergency calls only" on devices that are voice-capable.
|
||||
// This depends on mPlmn containing the text "Emergency calls only" when the radio
|
||||
// has some connectivity. Otherwise, it should be null or empty and just show
|
||||
// "No SIM card"
|
||||
// Grab the first subscripton, because they all should contain the emergency text,
|
||||
// described above.
|
||||
displayText = makeCarrierStringOnEmergencyCapable(
|
||||
getMissingSimMessage(), subs.get(0).getCarrierName());
|
||||
} else {
|
||||
// We don't have a SubscriptionInfo to get the emergency calls only from.
|
||||
// Grab it from the old sticky broadcast if possible instead. We can use it
|
||||
// here because no subscriptions are active, so we don't have
|
||||
// to worry about MSIM clashing.
|
||||
CharSequence text =
|
||||
getContext().getText(com.android.internal.R.string.emergency_calls_only);
|
||||
Intent i = getContext().registerReceiver(null,
|
||||
new IntentFilter(TelephonyManager.ACTION_SERVICE_PROVIDERS_UPDATED));
|
||||
if (i != null) {
|
||||
String spn = "";
|
||||
String plmn = "";
|
||||
if (i.getBooleanExtra(TelephonyManager.EXTRA_SHOW_SPN, false)) {
|
||||
spn = i.getStringExtra(TelephonyManager.EXTRA_SPN);
|
||||
}
|
||||
if (i.getBooleanExtra(TelephonyManager.EXTRA_SHOW_PLMN, false)) {
|
||||
plmn = i.getStringExtra(TelephonyManager.EXTRA_PLMN);
|
||||
}
|
||||
if (DEBUG) Log.d(TAG, "Getting plmn/spn sticky brdcst " + plmn + "/" + spn);
|
||||
if (Objects.equals(plmn, spn)) {
|
||||
text = plmn;
|
||||
} else {
|
||||
text = concatenate(plmn, spn, mSeparator);
|
||||
}
|
||||
}
|
||||
displayText = makeCarrierStringOnEmergencyCapable(getMissingSimMessage(), text);
|
||||
}
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(displayText)) displayText = joinNotEmpty(mSeparator, carrierNames);
|
||||
|
||||
displayText = updateCarrierTextWithSimIoError(displayText, carrierNames, subOrderBySlot,
|
||||
allSimsMissing);
|
||||
|
||||
boolean airplaneMode = false;
|
||||
// APM (airplane mode) != no carrier state. There are carrier services
|
||||
// (e.g. WFC = Wi-Fi calling) which may operate in APM.
|
||||
if (!anySimReadyAndInService && WirelessUtils.isAirplaneModeOn(mContext)) {
|
||||
displayText = getAirplaneModeMessage();
|
||||
airplaneMode = true;
|
||||
}
|
||||
|
||||
final CarrierTextCallbackInfo info = new CarrierTextCallbackInfo(
|
||||
displayText,
|
||||
carrierNames,
|
||||
!allSimsMissing,
|
||||
subsIds,
|
||||
airplaneMode);
|
||||
postToCallback(info);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected void postToCallback(CarrierTextCallbackInfo info) {
|
||||
final CarrierTextCallback callback = mCarrierTextCallback;
|
||||
if (callback != null) {
|
||||
mMainExecutor.execute(() -> callback.updateCarrierInfo(info));
|
||||
}
|
||||
}
|
||||
|
||||
private Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
private String getMissingSimMessage() {
|
||||
return mShowMissingSim && mTelephonyCapable
|
||||
? getContext().getString(R.string.keyguard_missing_sim_message_short) : "";
|
||||
}
|
||||
|
||||
private String getAirplaneModeMessage() {
|
||||
return mShowAirplaneMode
|
||||
? getContext().getString(R.string.airplane_mode) : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Top-level function for creating carrier text. Makes text based on simState, PLMN
|
||||
* and SPN as well as device capabilities, such as being emergency call capable.
|
||||
*
|
||||
* @return Carrier text if not in missing state, null otherwise.
|
||||
*/
|
||||
private CharSequence getCarrierTextForSimState(int simState, CharSequence text) {
|
||||
CharSequence carrierText = null;
|
||||
CarrierTextManager.StatusMode status = getStatusForIccState(simState);
|
||||
switch (status) {
|
||||
case Normal:
|
||||
carrierText = text;
|
||||
break;
|
||||
|
||||
case SimNotReady:
|
||||
// Null is reserved for denoting missing, in this case we have nothing to display.
|
||||
carrierText = ""; // nothing to display yet.
|
||||
break;
|
||||
|
||||
case NetworkLocked:
|
||||
carrierText = makeCarrierStringOnEmergencyCapable(
|
||||
mContext.getText(R.string.keyguard_network_locked_message), text);
|
||||
break;
|
||||
|
||||
case SimMissing:
|
||||
carrierText = null;
|
||||
break;
|
||||
|
||||
case SimPermDisabled:
|
||||
carrierText = makeCarrierStringOnEmergencyCapable(
|
||||
getContext().getText(
|
||||
R.string.keyguard_permanent_disabled_sim_message_short),
|
||||
text);
|
||||
break;
|
||||
|
||||
case SimMissingLocked:
|
||||
carrierText = null;
|
||||
break;
|
||||
|
||||
case SimLocked:
|
||||
carrierText = makeCarrierStringOnLocked(
|
||||
getContext().getText(R.string.keyguard_sim_locked_message),
|
||||
text);
|
||||
break;
|
||||
|
||||
case SimPukLocked:
|
||||
carrierText = makeCarrierStringOnLocked(
|
||||
getContext().getText(R.string.keyguard_sim_puk_locked_message),
|
||||
text);
|
||||
break;
|
||||
case SimIoError:
|
||||
carrierText = makeCarrierStringOnEmergencyCapable(
|
||||
getContext().getText(R.string.keyguard_sim_error_message_short),
|
||||
text);
|
||||
break;
|
||||
case SimUnknown:
|
||||
carrierText = null;
|
||||
break;
|
||||
}
|
||||
|
||||
return carrierText;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add emergencyCallMessage to carrier string only if phone supports emergency calls.
|
||||
*/
|
||||
private CharSequence makeCarrierStringOnEmergencyCapable(
|
||||
CharSequence simMessage, CharSequence emergencyCallMessage) {
|
||||
if (mIsEmergencyCallCapable) {
|
||||
return concatenate(simMessage, emergencyCallMessage, mSeparator);
|
||||
}
|
||||
return simMessage;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add "SIM card is locked" in parenthesis after carrier name, so it is easily associated in
|
||||
* DSDS
|
||||
*/
|
||||
private CharSequence makeCarrierStringOnLocked(CharSequence simMessage,
|
||||
CharSequence carrierName) {
|
||||
final boolean simMessageValid = !TextUtils.isEmpty(simMessage);
|
||||
final boolean carrierNameValid = !TextUtils.isEmpty(carrierName);
|
||||
if (simMessageValid && carrierNameValid) {
|
||||
return mContext.getString(R.string.keyguard_carrier_name_with_sim_locked_template,
|
||||
carrierName, simMessage);
|
||||
} else if (simMessageValid) {
|
||||
return simMessage;
|
||||
} else if (carrierNameValid) {
|
||||
return carrierName;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the current status of the lock screen given the SIM state and other stuff.
|
||||
*/
|
||||
private CarrierTextManager.StatusMode getStatusForIccState(int simState) {
|
||||
final boolean missingAndNotProvisioned =
|
||||
!mKeyguardUpdateMonitor.isDeviceProvisioned()
|
||||
&& (simState == TelephonyManager.SIM_STATE_ABSENT
|
||||
|| simState == TelephonyManager.SIM_STATE_PERM_DISABLED);
|
||||
|
||||
// Assume we're NETWORK_LOCKED if not provisioned
|
||||
simState = missingAndNotProvisioned ? TelephonyManager.SIM_STATE_NETWORK_LOCKED : simState;
|
||||
switch (simState) {
|
||||
case TelephonyManager.SIM_STATE_ABSENT:
|
||||
return CarrierTextManager.StatusMode.SimMissing;
|
||||
case TelephonyManager.SIM_STATE_NETWORK_LOCKED:
|
||||
return CarrierTextManager.StatusMode.SimMissingLocked;
|
||||
case TelephonyManager.SIM_STATE_NOT_READY:
|
||||
return CarrierTextManager.StatusMode.SimNotReady;
|
||||
case TelephonyManager.SIM_STATE_PIN_REQUIRED:
|
||||
return CarrierTextManager.StatusMode.SimLocked;
|
||||
case TelephonyManager.SIM_STATE_PUK_REQUIRED:
|
||||
return CarrierTextManager.StatusMode.SimPukLocked;
|
||||
case TelephonyManager.SIM_STATE_READY:
|
||||
return CarrierTextManager.StatusMode.Normal;
|
||||
case TelephonyManager.SIM_STATE_PERM_DISABLED:
|
||||
return CarrierTextManager.StatusMode.SimPermDisabled;
|
||||
case TelephonyManager.SIM_STATE_UNKNOWN:
|
||||
return CarrierTextManager.StatusMode.SimUnknown;
|
||||
case TelephonyManager.SIM_STATE_CARD_IO_ERROR:
|
||||
return CarrierTextManager.StatusMode.SimIoError;
|
||||
}
|
||||
return CarrierTextManager.StatusMode.SimUnknown;
|
||||
}
|
||||
|
||||
private static CharSequence concatenate(CharSequence plmn, CharSequence spn,
|
||||
CharSequence separator) {
|
||||
final boolean plmnValid = !TextUtils.isEmpty(plmn);
|
||||
final boolean spnValid = !TextUtils.isEmpty(spn);
|
||||
if (plmnValid && spnValid) {
|
||||
return new StringBuilder().append(plmn).append(separator).append(spn).toString();
|
||||
} else if (plmnValid) {
|
||||
return plmn;
|
||||
} else if (spnValid) {
|
||||
return spn;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins the strings in a sequence using a separator. Empty strings are discarded with no extra
|
||||
* separator added so there are no extra separators that are not needed.
|
||||
*/
|
||||
private static CharSequence joinNotEmpty(CharSequence separator, CharSequence[] sequences) {
|
||||
int length = sequences.length;
|
||||
if (length == 0) return "";
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (!TextUtils.isEmpty(sequences[i])) {
|
||||
if (!TextUtils.isEmpty(sb)) {
|
||||
sb.append(separator);
|
||||
}
|
||||
sb.append(sequences[i]);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static List<CharSequence> append(List<CharSequence> list, CharSequence string) {
|
||||
if (!TextUtils.isEmpty(string)) {
|
||||
list.add(string);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private CharSequence getCarrierHelpTextForSimState(int simState,
|
||||
String plmn, String spn) {
|
||||
int carrierHelpTextId = 0;
|
||||
CarrierTextManager.StatusMode status = getStatusForIccState(simState);
|
||||
switch (status) {
|
||||
case NetworkLocked:
|
||||
carrierHelpTextId = R.string.keyguard_instructions_when_pattern_disabled;
|
||||
break;
|
||||
|
||||
case SimMissing:
|
||||
carrierHelpTextId = R.string.keyguard_missing_sim_instructions_long;
|
||||
break;
|
||||
|
||||
case SimPermDisabled:
|
||||
carrierHelpTextId = R.string.keyguard_permanent_disabled_sim_instructions;
|
||||
break;
|
||||
|
||||
case SimMissingLocked:
|
||||
carrierHelpTextId = R.string.keyguard_missing_sim_instructions;
|
||||
break;
|
||||
|
||||
case Normal:
|
||||
case SimLocked:
|
||||
case SimPukLocked:
|
||||
break;
|
||||
}
|
||||
|
||||
return mContext.getText(carrierHelpTextId);
|
||||
}
|
||||
|
||||
/** Injectable Buildeer for {@#link CarrierTextManager}. */
|
||||
public static class Builder {
|
||||
private final Context mContext;
|
||||
private final String mSeparator;
|
||||
private final WifiManager mWifiManager;
|
||||
private final TelephonyManager mTelephonyManager;
|
||||
private final TelephonyListenerManager mTelephonyListenerManager;
|
||||
private final WakefulnessLifecycle mWakefulnessLifecycle;
|
||||
private final Executor mMainExecutor;
|
||||
private final Executor mBgExecutor;
|
||||
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
private boolean mShowAirplaneMode;
|
||||
private boolean mShowMissingSim;
|
||||
|
||||
@Inject
|
||||
public Builder(Context context, @Main Resources resources,
|
||||
@Nullable WifiManager wifiManager,
|
||||
TelephonyManager telephonyManager,
|
||||
TelephonyListenerManager telephonyListenerManager,
|
||||
WakefulnessLifecycle wakefulnessLifecycle,
|
||||
@Main Executor mainExecutor, @Background Executor bgExecutor,
|
||||
KeyguardUpdateMonitor keyguardUpdateMonitor) {
|
||||
mContext = context;
|
||||
mSeparator = resources.getString(
|
||||
com.android.internal.R.string.kg_text_message_separator);
|
||||
mWifiManager = wifiManager;
|
||||
mTelephonyManager = telephonyManager;
|
||||
mTelephonyListenerManager = telephonyListenerManager;
|
||||
mWakefulnessLifecycle = wakefulnessLifecycle;
|
||||
mMainExecutor = mainExecutor;
|
||||
mBgExecutor = bgExecutor;
|
||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
||||
}
|
||||
|
||||
/** */
|
||||
public Builder setShowAirplaneMode(boolean showAirplaneMode) {
|
||||
mShowAirplaneMode = showAirplaneMode;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** */
|
||||
public Builder setShowMissingSim(boolean showMissingSim) {
|
||||
mShowMissingSim = showMissingSim;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Create a CarrierTextManager. */
|
||||
public CarrierTextManager build() {
|
||||
return new CarrierTextManager(
|
||||
mContext, mSeparator, mShowAirplaneMode, mShowMissingSim, mWifiManager,
|
||||
mTelephonyManager, mTelephonyListenerManager,
|
||||
mWakefulnessLifecycle, mMainExecutor, mBgExecutor, mKeyguardUpdateMonitor);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Data structure for passing information to CarrierTextController subscribers
|
||||
*/
|
||||
public static final class CarrierTextCallbackInfo {
|
||||
public final CharSequence carrierText;
|
||||
public final CharSequence[] listOfCarriers;
|
||||
public final boolean anySimReady;
|
||||
public final int[] subscriptionIds;
|
||||
public boolean airplaneMode;
|
||||
|
||||
@VisibleForTesting
|
||||
public CarrierTextCallbackInfo(CharSequence carrierText, CharSequence[] listOfCarriers,
|
||||
boolean anySimReady, int[] subscriptionIds) {
|
||||
this(carrierText, listOfCarriers, anySimReady, subscriptionIds, false);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public CarrierTextCallbackInfo(CharSequence carrierText, CharSequence[] listOfCarriers,
|
||||
boolean anySimReady, int[] subscriptionIds, boolean airplaneMode) {
|
||||
this.carrierText = carrierText;
|
||||
this.listOfCarriers = listOfCarriers;
|
||||
this.anySimReady = anySimReady;
|
||||
this.subscriptionIds = subscriptionIds;
|
||||
this.airplaneMode = airplaneMode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to communicate to Views
|
||||
*/
|
||||
public interface CarrierTextCallback {
|
||||
/**
|
||||
* Provides updated carrier information.
|
||||
*/
|
||||
default void updateCarrierInfo(CarrierTextCallbackInfo info) {};
|
||||
|
||||
/**
|
||||
* Notifies the View that the device is going to sleep
|
||||
*/
|
||||
default void startedGoingToSleep() {};
|
||||
|
||||
/**
|
||||
* Notifies the View that the device finished waking up
|
||||
*/
|
||||
default void finishedWakingUp() {};
|
||||
}
|
||||
}
|
||||
@@ -16,34 +16,16 @@
|
||||
|
||||
package com.android.keyguard;
|
||||
|
||||
import static com.android.systemui.DejankUtils.whitelistIpcs;
|
||||
|
||||
import android.app.ActivityOptions;
|
||||
import android.app.ActivityTaskManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.PowerManager;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.util.EmergencyAffordanceManager;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.util.EmergencyDialerConstants;
|
||||
|
||||
/**
|
||||
* This class implements a smart emergency button that updates itself based
|
||||
@@ -53,34 +35,14 @@ import com.android.systemui.util.EmergencyDialerConstants;
|
||||
*/
|
||||
public class EmergencyButton extends Button {
|
||||
|
||||
private static final String LOG_TAG = "EmergencyButton";
|
||||
private final EmergencyAffordanceManager mEmergencyAffordanceManager;
|
||||
|
||||
private int mDownX;
|
||||
private int mDownY;
|
||||
KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
|
||||
|
||||
@Override
|
||||
public void onSimStateChanged(int subId, int slotId, int simState) {
|
||||
updateEmergencyCallButton();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPhoneStateChanged(int phoneState) {
|
||||
updateEmergencyCallButton();
|
||||
}
|
||||
};
|
||||
private boolean mLongPressWasDragged;
|
||||
|
||||
public interface EmergencyButtonCallback {
|
||||
public void onEmergencyButtonClickedWhenInCall();
|
||||
}
|
||||
|
||||
private LockPatternUtils mLockPatternUtils;
|
||||
private PowerManager mPowerManager;
|
||||
private EmergencyButtonCallback mEmergencyButtonCallback;
|
||||
|
||||
private final boolean mIsVoiceCapable;
|
||||
private final boolean mEnableEmergencyCallWhileSimLocked;
|
||||
|
||||
public EmergencyButton(Context context) {
|
||||
@@ -89,34 +51,15 @@ public class EmergencyButton extends Button {
|
||||
|
||||
public EmergencyButton(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
mIsVoiceCapable = getTelephonyManager().isVoiceCapable();
|
||||
mEnableEmergencyCallWhileSimLocked = mContext.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_enable_emergency_call_while_sim_locked);
|
||||
mEmergencyAffordanceManager = new EmergencyAffordanceManager(context);
|
||||
}
|
||||
|
||||
private TelephonyManager getTelephonyManager() {
|
||||
return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
Dependency.get(KeyguardUpdateMonitor.class).registerCallback(mInfoCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
Dependency.get(KeyguardUpdateMonitor.class).removeCallback(mInfoCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
mLockPatternUtils = new LockPatternUtils(mContext);
|
||||
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
|
||||
setOnClickListener(v -> takeEmergencyCallAction());
|
||||
if (mEmergencyAffordanceManager.needsEmergencyAffordance()) {
|
||||
setOnLongClickListener(v -> {
|
||||
if (!mLongPressWasDragged
|
||||
@@ -127,7 +70,6 @@ public class EmergencyButton extends Button {
|
||||
return false;
|
||||
});
|
||||
}
|
||||
whitelistIpcs(this::updateEmergencyCallButton);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -165,65 +107,13 @@ public class EmergencyButton extends Button {
|
||||
return super.performLongClick();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
updateEmergencyCallButton();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the emergency dialer or returns the user to the existing call.
|
||||
*/
|
||||
public void takeEmergencyCallAction() {
|
||||
MetricsLogger.action(mContext, MetricsEvent.ACTION_EMERGENCY_CALL);
|
||||
if (mPowerManager != null) {
|
||||
mPowerManager.userActivity(SystemClock.uptimeMillis(), true);
|
||||
}
|
||||
try {
|
||||
ActivityTaskManager.getService().stopSystemLockTaskMode();
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(LOG_TAG, "Failed to stop app pinning");
|
||||
}
|
||||
if (isInCall()) {
|
||||
resumeCall();
|
||||
if (mEmergencyButtonCallback != null) {
|
||||
mEmergencyButtonCallback.onEmergencyButtonClickedWhenInCall();
|
||||
}
|
||||
} else {
|
||||
KeyguardUpdateMonitor updateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
|
||||
if (updateMonitor != null) {
|
||||
updateMonitor.reportEmergencyCallAction(true /* bypassHandler */);
|
||||
} else {
|
||||
Log.w(LOG_TAG, "KeyguardUpdateMonitor was null, launching intent anyway.");
|
||||
}
|
||||
TelecomManager telecomManager = getTelecommManager();
|
||||
if (telecomManager == null) {
|
||||
Log.wtf(LOG_TAG, "TelecomManager was null, cannot launch emergency dialer");
|
||||
return;
|
||||
}
|
||||
Intent emergencyDialIntent =
|
||||
telecomManager.createLaunchEmergencyDialerIntent(null /* number*/)
|
||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
|
||||
| Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
.putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE,
|
||||
EmergencyDialerConstants.ENTRY_TYPE_LOCKSCREEN_BUTTON);
|
||||
|
||||
getContext().startActivityAsUser(emergencyDialIntent,
|
||||
ActivityOptions.makeCustomAnimation(getContext(), 0, 0).toBundle(),
|
||||
new UserHandle(KeyguardUpdateMonitor.getCurrentUser()));
|
||||
}
|
||||
}
|
||||
|
||||
private void updateEmergencyCallButton() {
|
||||
void updateEmergencyCallButton(boolean isInCall, boolean isVoiceCapable, boolean simLocked) {
|
||||
boolean visible = false;
|
||||
if (mIsVoiceCapable) {
|
||||
if (isVoiceCapable) {
|
||||
// Emergency calling requires voice capability.
|
||||
if (isInCall()) {
|
||||
if (isInCall) {
|
||||
visible = true; // always show "return to call" if phone is off-hook
|
||||
} else {
|
||||
final boolean simLocked = Dependency.get(KeyguardUpdateMonitor.class)
|
||||
.isSimPinVoiceSecure();
|
||||
if (simLocked) {
|
||||
// Some countries can't handle emergency calls while SIM is locked.
|
||||
visible = mEnableEmergencyCallWhileSimLocked;
|
||||
@@ -237,7 +127,7 @@ public class EmergencyButton extends Button {
|
||||
setVisibility(View.VISIBLE);
|
||||
|
||||
int textId;
|
||||
if (isInCall()) {
|
||||
if (isInCall) {
|
||||
textId = com.android.internal.R.string.lockscreen_return_to_call;
|
||||
} else {
|
||||
textId = com.android.internal.R.string.lockscreen_emergency_call;
|
||||
@@ -247,26 +137,4 @@ public class EmergencyButton extends Button {
|
||||
setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
public void setCallback(EmergencyButtonCallback callback) {
|
||||
mEmergencyButtonCallback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumes a call in progress.
|
||||
*/
|
||||
private void resumeCall() {
|
||||
getTelecommManager().showInCallScreen(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if there is a call currently in progress.
|
||||
*/
|
||||
private boolean isInCall() {
|
||||
return getTelecommManager().isInCall();
|
||||
}
|
||||
|
||||
private TelecomManager getTelecommManager() {
|
||||
return (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.keyguard;
|
||||
|
||||
import static com.android.systemui.DejankUtils.whitelistIpcs;
|
||||
|
||||
import android.app.ActivityOptions;
|
||||
import android.app.ActivityTaskManager;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
import android.os.PowerManager;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.keyguard.dagger.KeyguardBouncerScope;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
|
||||
import com.android.systemui.util.EmergencyDialerConstants;
|
||||
import com.android.systemui.util.ViewController;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/** View Controller for {@link com.android.keyguard.EmergencyButton}. */
|
||||
@KeyguardBouncerScope
|
||||
public class EmergencyButtonController extends ViewController<EmergencyButton> {
|
||||
static final String LOG_TAG = "EmergencyButton";
|
||||
private final ConfigurationController mConfigurationController;
|
||||
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
private final TelephonyManager mTelephonyManager;
|
||||
private final PowerManager mPowerManager;
|
||||
private final ActivityTaskManager mActivityTaskManager;
|
||||
private final TelecomManager mTelecomManager;
|
||||
private final MetricsLogger mMetricsLogger;
|
||||
|
||||
private EmergencyButtonCallback mEmergencyButtonCallback;
|
||||
|
||||
private final KeyguardUpdateMonitorCallback mInfoCallback =
|
||||
new KeyguardUpdateMonitorCallback() {
|
||||
@Override
|
||||
public void onSimStateChanged(int subId, int slotId, int simState) {
|
||||
updateEmergencyCallButton();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPhoneStateChanged(int phoneState) {
|
||||
updateEmergencyCallButton();
|
||||
}
|
||||
};
|
||||
|
||||
private final ConfigurationListener mConfigurationListener = new ConfigurationListener() {
|
||||
@Override
|
||||
public void onConfigChanged(Configuration newConfig) {
|
||||
updateEmergencyCallButton();
|
||||
}
|
||||
};
|
||||
|
||||
private EmergencyButtonController(@Nullable EmergencyButton view,
|
||||
ConfigurationController configurationController,
|
||||
KeyguardUpdateMonitor keyguardUpdateMonitor, TelephonyManager telephonyManager,
|
||||
PowerManager powerManager, ActivityTaskManager activityTaskManager,
|
||||
@Nullable TelecomManager telecomManager, MetricsLogger metricsLogger) {
|
||||
super(view);
|
||||
mConfigurationController = configurationController;
|
||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
||||
mTelephonyManager = telephonyManager;
|
||||
mPowerManager = powerManager;
|
||||
mActivityTaskManager = activityTaskManager;
|
||||
mTelecomManager = telecomManager;
|
||||
mMetricsLogger = metricsLogger;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInit() {
|
||||
whitelistIpcs(this::updateEmergencyCallButton);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onViewAttached() {
|
||||
mKeyguardUpdateMonitor.registerCallback(mInfoCallback);
|
||||
mConfigurationController.addCallback(mConfigurationListener);
|
||||
mView.setOnClickListener(v -> takeEmergencyCallAction());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onViewDetached() {
|
||||
mKeyguardUpdateMonitor.removeCallback(mInfoCallback);
|
||||
mConfigurationController.removeCallback(mConfigurationListener);
|
||||
}
|
||||
|
||||
private void updateEmergencyCallButton() {
|
||||
if (mView != null) {
|
||||
mView.updateEmergencyCallButton(
|
||||
mTelecomManager != null && mTelecomManager.isInCall(),
|
||||
mTelephonyManager.isVoiceCapable(),
|
||||
mKeyguardUpdateMonitor.isSimPinVoiceSecure());
|
||||
}
|
||||
}
|
||||
|
||||
public void setEmergencyButtonCallback(EmergencyButtonCallback callback) {
|
||||
mEmergencyButtonCallback = callback;
|
||||
}
|
||||
/**
|
||||
* Shows the emergency dialer or returns the user to the existing call.
|
||||
*/
|
||||
public void takeEmergencyCallAction() {
|
||||
mMetricsLogger.action(MetricsEvent.ACTION_EMERGENCY_CALL);
|
||||
if (mPowerManager != null) {
|
||||
mPowerManager.userActivity(SystemClock.uptimeMillis(), true);
|
||||
}
|
||||
mActivityTaskManager.stopSystemLockTaskMode();
|
||||
if (mTelecomManager != null && mTelecomManager.isInCall()) {
|
||||
mTelecomManager.showInCallScreen(false);
|
||||
if (mEmergencyButtonCallback != null) {
|
||||
mEmergencyButtonCallback.onEmergencyButtonClickedWhenInCall();
|
||||
}
|
||||
} else {
|
||||
mKeyguardUpdateMonitor.reportEmergencyCallAction(true /* bypassHandler */);
|
||||
if (mTelecomManager == null) {
|
||||
Log.wtf(LOG_TAG, "TelecomManager was null, cannot launch emergency dialer");
|
||||
return;
|
||||
}
|
||||
Intent emergencyDialIntent =
|
||||
mTelecomManager.createLaunchEmergencyDialerIntent(null /* number*/)
|
||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
|
||||
| Intent.FLAG_ACTIVITY_CLEAR_TOP)
|
||||
.putExtra(EmergencyDialerConstants.EXTRA_ENTRY_TYPE,
|
||||
EmergencyDialerConstants.ENTRY_TYPE_LOCKSCREEN_BUTTON);
|
||||
|
||||
getContext().startActivityAsUser(emergencyDialIntent,
|
||||
ActivityOptions.makeCustomAnimation(getContext(), 0, 0).toBundle(),
|
||||
new UserHandle(KeyguardUpdateMonitor.getCurrentUser()));
|
||||
}
|
||||
}
|
||||
|
||||
/** */
|
||||
public interface EmergencyButtonCallback {
|
||||
/** */
|
||||
void onEmergencyButtonClickedWhenInCall();
|
||||
}
|
||||
|
||||
/** Injectable Factory for creating {@link EmergencyButtonController}. */
|
||||
public static class Factory {
|
||||
private final ConfigurationController mConfigurationController;
|
||||
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
private final TelephonyManager mTelephonyManager;
|
||||
private final PowerManager mPowerManager;
|
||||
private final ActivityTaskManager mActivityTaskManager;
|
||||
@Nullable
|
||||
private final TelecomManager mTelecomManager;
|
||||
private final MetricsLogger mMetricsLogger;
|
||||
|
||||
@Inject
|
||||
public Factory(ConfigurationController configurationController,
|
||||
KeyguardUpdateMonitor keyguardUpdateMonitor, TelephonyManager telephonyManager,
|
||||
PowerManager powerManager, ActivityTaskManager activityTaskManager,
|
||||
@Nullable TelecomManager telecomManager, MetricsLogger metricsLogger) {
|
||||
|
||||
mConfigurationController = configurationController;
|
||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
||||
mTelephonyManager = telephonyManager;
|
||||
mPowerManager = powerManager;
|
||||
mActivityTaskManager = activityTaskManager;
|
||||
mTelecomManager = telecomManager;
|
||||
mMetricsLogger = metricsLogger;
|
||||
}
|
||||
|
||||
/** Construct an {@link com.android.keyguard.EmergencyButtonController}. */
|
||||
public EmergencyButtonController create(EmergencyButton view) {
|
||||
return new EmergencyButtonController(view, mConfigurationController,
|
||||
mKeyguardUpdateMonitor, mTelephonyManager, mPowerManager, mActivityTaskManager,
|
||||
mTelecomManager, mMetricsLogger);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@ import com.android.internal.util.LatencyTracker;
|
||||
import com.android.internal.widget.LockPatternChecker;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.internal.widget.LockscreenCredential;
|
||||
import com.android.keyguard.EmergencyButton.EmergencyButtonCallback;
|
||||
import com.android.keyguard.EmergencyButtonController.EmergencyButtonCallback;
|
||||
import com.android.keyguard.KeyguardAbsKeyInputView.KeyDownListener;
|
||||
import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
|
||||
import com.android.systemui.R;
|
||||
@@ -44,6 +44,7 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey
|
||||
private final LockPatternUtils mLockPatternUtils;
|
||||
private final LatencyTracker mLatencyTracker;
|
||||
private final FalsingCollector mFalsingCollector;
|
||||
private final EmergencyButtonController mEmergencyButtonController;
|
||||
private CountDownTimer mCountdownTimer;
|
||||
protected KeyguardMessageAreaController mMessageAreaController;
|
||||
private boolean mDismissing;
|
||||
@@ -73,12 +74,14 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey
|
||||
LockPatternUtils lockPatternUtils,
|
||||
KeyguardSecurityCallback keyguardSecurityCallback,
|
||||
KeyguardMessageAreaController.Factory messageAreaControllerFactory,
|
||||
LatencyTracker latencyTracker, FalsingCollector falsingCollector) {
|
||||
super(view, securityMode, keyguardSecurityCallback);
|
||||
LatencyTracker latencyTracker, FalsingCollector falsingCollector,
|
||||
EmergencyButtonController emergencyButtonController) {
|
||||
super(view, securityMode, keyguardSecurityCallback, emergencyButtonController);
|
||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
||||
mLockPatternUtils = lockPatternUtils;
|
||||
mLatencyTracker = latencyTracker;
|
||||
mFalsingCollector = falsingCollector;
|
||||
mEmergencyButtonController = emergencyButtonController;
|
||||
KeyguardMessageArea kma = KeyguardMessageArea.findSecurityMessageDisplay(mView);
|
||||
mMessageAreaController = messageAreaControllerFactory.create(kma);
|
||||
}
|
||||
@@ -87,6 +90,7 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey
|
||||
|
||||
@Override
|
||||
public void onInit() {
|
||||
super.onInit();
|
||||
mMessageAreaController.init();
|
||||
}
|
||||
|
||||
@@ -95,10 +99,7 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey
|
||||
super.onViewAttached();
|
||||
mView.setKeyDownListener(mKeyDownListener);
|
||||
mView.setEnableHaptics(mLockPatternUtils.isTactileFeedbackEnabled());
|
||||
EmergencyButton button = mView.findViewById(R.id.emergency_call_button);
|
||||
if (button != null) {
|
||||
button.setCallback(mEmergencyButtonCallback);
|
||||
}
|
||||
mEmergencyButtonController.setEmergencyButtonCallback(mEmergencyButtonCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -36,7 +36,6 @@ import android.view.WindowManager;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.keyguard.dagger.KeyguardStatusViewComponent;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.dagger.qualifiers.UiBackground;
|
||||
import com.android.systemui.navigationbar.NavigationBarController;
|
||||
@@ -46,12 +45,15 @@ import java.util.concurrent.Executor;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.Lazy;
|
||||
|
||||
public class KeyguardDisplayManager {
|
||||
protected static final String TAG = "KeyguardDisplayManager";
|
||||
private static boolean DEBUG = KeyguardConstants.DEBUG;
|
||||
|
||||
private MediaRouter mMediaRouter = null;
|
||||
private final DisplayManager mDisplayService;
|
||||
private final Lazy<NavigationBarController> mNavigationBarControllerLazy;
|
||||
private final KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
|
||||
private final Context mContext;
|
||||
|
||||
@@ -85,9 +87,11 @@ public class KeyguardDisplayManager {
|
||||
|
||||
@Inject
|
||||
public KeyguardDisplayManager(Context context,
|
||||
Lazy<NavigationBarController> navigationBarControllerLazy,
|
||||
KeyguardStatusViewComponent.Factory keyguardStatusViewComponentFactory,
|
||||
@UiBackground Executor uiBgExecutor) {
|
||||
mContext = context;
|
||||
mNavigationBarControllerLazy = navigationBarControllerLazy;
|
||||
mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory;
|
||||
uiBgExecutor.execute(() -> mMediaRouter = mContext.getSystemService(MediaRouter.class));
|
||||
mDisplayService = mContext.getSystemService(DisplayManager.class);
|
||||
@@ -240,7 +244,7 @@ public class KeyguardDisplayManager {
|
||||
// Leave this task to {@link StatusBarKeyguardViewManager}
|
||||
if (displayId == DEFAULT_DISPLAY) return;
|
||||
|
||||
NavigationBarView navBarView = Dependency.get(NavigationBarController.class)
|
||||
NavigationBarView navBarView = mNavigationBarControllerLazy.get()
|
||||
.getNavigationBarView(displayId);
|
||||
// We may not have nav bar on a display.
|
||||
if (navBarView == null) return;
|
||||
|
||||
@@ -42,6 +42,7 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
|
||||
private final SecurityMode mSecurityMode;
|
||||
private final KeyguardSecurityCallback mKeyguardSecurityCallback;
|
||||
private final EmergencyButton mEmergencyButton;
|
||||
private final EmergencyButtonController mEmergencyButtonController;
|
||||
private boolean mPaused;
|
||||
|
||||
|
||||
@@ -69,11 +70,18 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
|
||||
};
|
||||
|
||||
protected KeyguardInputViewController(T view, SecurityMode securityMode,
|
||||
KeyguardSecurityCallback keyguardSecurityCallback) {
|
||||
KeyguardSecurityCallback keyguardSecurityCallback,
|
||||
EmergencyButtonController emergencyButtonController) {
|
||||
super(view);
|
||||
mSecurityMode = securityMode;
|
||||
mKeyguardSecurityCallback = keyguardSecurityCallback;
|
||||
mEmergencyButton = view == null ? null : view.findViewById(R.id.emergency_call_button);
|
||||
mEmergencyButtonController = emergencyButtonController;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInit() {
|
||||
mEmergencyButtonController.init();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -157,6 +165,7 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
|
||||
private final Resources mResources;
|
||||
private final LiftToActivateListener mLiftToActivateListener;
|
||||
private final TelephonyManager mTelephonyManager;
|
||||
private final EmergencyButtonController.Factory mEmergencyButtonControllerFactory;
|
||||
private final FalsingCollector mFalsingCollector;
|
||||
private final boolean mIsNewLayoutEnabled;
|
||||
|
||||
@@ -168,6 +177,7 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
|
||||
InputMethodManager inputMethodManager, @Main DelayableExecutor mainExecutor,
|
||||
@Main Resources resources, LiftToActivateListener liftToActivateListener,
|
||||
TelephonyManager telephonyManager, FalsingCollector falsingCollector,
|
||||
EmergencyButtonController.Factory emergencyButtonControllerFactory,
|
||||
FeatureFlags featureFlags) {
|
||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
||||
mLockPatternUtils = lockPatternUtils;
|
||||
@@ -178,6 +188,7 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
|
||||
mResources = resources;
|
||||
mLiftToActivateListener = liftToActivateListener;
|
||||
mTelephonyManager = telephonyManager;
|
||||
mEmergencyButtonControllerFactory = emergencyButtonControllerFactory;
|
||||
mFalsingCollector = falsingCollector;
|
||||
mIsNewLayoutEnabled = featureFlags.isKeyguardLayoutEnabled();
|
||||
}
|
||||
@@ -185,33 +196,40 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
|
||||
/** Create a new {@link KeyguardInputViewController}. */
|
||||
public KeyguardInputViewController create(KeyguardInputView keyguardInputView,
|
||||
SecurityMode securityMode, KeyguardSecurityCallback keyguardSecurityCallback) {
|
||||
EmergencyButtonController emergencyButtonController =
|
||||
mEmergencyButtonControllerFactory.create(
|
||||
keyguardInputView.findViewById(R.id.emergency_call_button));
|
||||
|
||||
if (keyguardInputView instanceof KeyguardPatternView) {
|
||||
return new KeyguardPatternViewController((KeyguardPatternView) keyguardInputView,
|
||||
mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
|
||||
keyguardSecurityCallback, mLatencyTracker, mFalsingCollector,
|
||||
mMessageAreaControllerFactory);
|
||||
emergencyButtonController, mMessageAreaControllerFactory);
|
||||
} else if (keyguardInputView instanceof KeyguardPasswordView) {
|
||||
return new KeyguardPasswordViewController((KeyguardPasswordView) keyguardInputView,
|
||||
mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
|
||||
keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
|
||||
mInputMethodManager, mMainExecutor, mResources, mFalsingCollector);
|
||||
mInputMethodManager, emergencyButtonController, mMainExecutor, mResources,
|
||||
mFalsingCollector);
|
||||
|
||||
} else if (keyguardInputView instanceof KeyguardPINView) {
|
||||
return new KeyguardPinViewController((KeyguardPINView) keyguardInputView,
|
||||
mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
|
||||
keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
|
||||
mLiftToActivateListener, mFalsingCollector, mIsNewLayoutEnabled);
|
||||
mLiftToActivateListener, emergencyButtonController, mFalsingCollector,
|
||||
mIsNewLayoutEnabled);
|
||||
} else if (keyguardInputView instanceof KeyguardSimPinView) {
|
||||
return new KeyguardSimPinViewController((KeyguardSimPinView) keyguardInputView,
|
||||
mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
|
||||
keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
|
||||
mLiftToActivateListener, mTelephonyManager, mFalsingCollector,
|
||||
mIsNewLayoutEnabled);
|
||||
emergencyButtonController, mIsNewLayoutEnabled);
|
||||
} else if (keyguardInputView instanceof KeyguardSimPukView) {
|
||||
return new KeyguardSimPukViewController((KeyguardSimPukView) keyguardInputView,
|
||||
mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
|
||||
keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
|
||||
mLiftToActivateListener, mTelephonyManager, mFalsingCollector,
|
||||
mIsNewLayoutEnabled);
|
||||
emergencyButtonController, mIsNewLayoutEnabled);
|
||||
}
|
||||
|
||||
throw new RuntimeException("Unable to find controller for " + keyguardInputView);
|
||||
|
||||
@@ -112,11 +112,13 @@ public class KeyguardPasswordViewController
|
||||
KeyguardMessageAreaController.Factory messageAreaControllerFactory,
|
||||
LatencyTracker latencyTracker,
|
||||
InputMethodManager inputMethodManager,
|
||||
EmergencyButtonController emergencyButtonController,
|
||||
@Main DelayableExecutor mainExecutor,
|
||||
@Main Resources resources,
|
||||
FalsingCollector falsingCollector) {
|
||||
super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
|
||||
messageAreaControllerFactory, latencyTracker, falsingCollector);
|
||||
messageAreaControllerFactory, latencyTracker, falsingCollector,
|
||||
emergencyButtonController);
|
||||
mKeyguardSecurityCallback = keyguardSecurityCallback;
|
||||
mInputMethodManager = inputMethodManager;
|
||||
mMainExecutor = mainExecutor;
|
||||
|
||||
@@ -32,7 +32,7 @@ import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.internal.widget.LockPatternView;
|
||||
import com.android.internal.widget.LockPatternView.Cell;
|
||||
import com.android.internal.widget.LockscreenCredential;
|
||||
import com.android.keyguard.EmergencyButton.EmergencyButtonCallback;
|
||||
import com.android.keyguard.EmergencyButtonController.EmergencyButtonCallback;
|
||||
import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.systemui.R;
|
||||
@@ -54,6 +54,7 @@ public class KeyguardPatternViewController
|
||||
private final LockPatternUtils mLockPatternUtils;
|
||||
private final LatencyTracker mLatencyTracker;
|
||||
private final FalsingCollector mFalsingCollector;
|
||||
private final EmergencyButtonController mEmergencyButtonController;
|
||||
private final KeyguardMessageAreaController.Factory mMessageAreaControllerFactory;
|
||||
|
||||
private KeyguardMessageAreaController mMessageAreaController;
|
||||
@@ -189,12 +190,14 @@ public class KeyguardPatternViewController
|
||||
KeyguardSecurityCallback keyguardSecurityCallback,
|
||||
LatencyTracker latencyTracker,
|
||||
FalsingCollector falsingCollector,
|
||||
EmergencyButtonController emergencyButtonController,
|
||||
KeyguardMessageAreaController.Factory messageAreaControllerFactory) {
|
||||
super(view, securityMode, keyguardSecurityCallback);
|
||||
super(view, securityMode, keyguardSecurityCallback, emergencyButtonController);
|
||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
||||
mLockPatternUtils = lockPatternUtils;
|
||||
mLatencyTracker = latencyTracker;
|
||||
mFalsingCollector = falsingCollector;
|
||||
mEmergencyButtonController = emergencyButtonController;
|
||||
mMessageAreaControllerFactory = messageAreaControllerFactory;
|
||||
KeyguardMessageArea kma = KeyguardMessageArea.findSecurityMessageDisplay(mView);
|
||||
mMessageAreaController = mMessageAreaControllerFactory.create(kma);
|
||||
@@ -222,11 +225,7 @@ public class KeyguardPatternViewController
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
EmergencyButton button = mView.findViewById(R.id.emergency_call_button);
|
||||
if (button != null) {
|
||||
button.setCallback(mEmergencyButtonCallback);
|
||||
}
|
||||
mEmergencyButtonController.setEmergencyButtonCallback(mEmergencyButtonCallback);
|
||||
|
||||
View cancelBtn = mView.findViewById(R.id.cancel_button);
|
||||
if (cancelBtn != null) {
|
||||
@@ -242,10 +241,7 @@ public class KeyguardPatternViewController
|
||||
super.onViewDetached();
|
||||
mLockPatternView.setOnPatternListener(null);
|
||||
mLockPatternView.setOnTouchListener(null);
|
||||
EmergencyButton button = mView.findViewById(R.id.emergency_call_button);
|
||||
if (button != null) {
|
||||
button.setCallback(null);
|
||||
}
|
||||
mEmergencyButtonController.setEmergencyButtonCallback(null);
|
||||
View cancelBtn = mView.findViewById(R.id.cancel_button);
|
||||
if (cancelBtn != null) {
|
||||
cancelBtn.setOnClickListener(null);
|
||||
|
||||
@@ -57,9 +57,11 @@ public abstract class KeyguardPinBasedInputViewController<T extends KeyguardPinB
|
||||
KeyguardMessageAreaController.Factory messageAreaControllerFactory,
|
||||
LatencyTracker latencyTracker,
|
||||
LiftToActivateListener liftToActivateListener,
|
||||
EmergencyButtonController emergencyButtonController,
|
||||
FalsingCollector falsingCollector) {
|
||||
super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
|
||||
messageAreaControllerFactory, latencyTracker, falsingCollector);
|
||||
messageAreaControllerFactory, latencyTracker, falsingCollector,
|
||||
emergencyButtonController);
|
||||
mLiftToActivateListener = liftToActivateListener;
|
||||
mFalsingCollector = falsingCollector;
|
||||
mPasswordEntry = mView.findViewById(mView.getPasswordTextViewId());
|
||||
|
||||
@@ -34,10 +34,11 @@ public class KeyguardPinViewController
|
||||
KeyguardSecurityCallback keyguardSecurityCallback,
|
||||
KeyguardMessageAreaController.Factory messageAreaControllerFactory,
|
||||
LatencyTracker latencyTracker, LiftToActivateListener liftToActivateListener,
|
||||
EmergencyButtonController emergencyButtonController,
|
||||
FalsingCollector falsingCollector, boolean isNewLayoutEnabled) {
|
||||
super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
|
||||
messageAreaControllerFactory, latencyTracker, liftToActivateListener,
|
||||
falsingCollector);
|
||||
emergencyButtonController, falsingCollector);
|
||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
||||
view.setIsNewLayoutEnabled(isNewLayoutEnabled);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
|
||||
@@ -49,24 +48,27 @@ public class KeyguardSecurityModel {
|
||||
private final boolean mIsPukScreenAvailable;
|
||||
|
||||
private final LockPatternUtils mLockPatternUtils;
|
||||
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
|
||||
@Inject
|
||||
KeyguardSecurityModel(@Main Resources resources, LockPatternUtils lockPatternUtils) {
|
||||
KeyguardSecurityModel(@Main Resources resources, LockPatternUtils lockPatternUtils,
|
||||
KeyguardUpdateMonitor keyguardUpdateMonitor) {
|
||||
mIsPukScreenAvailable = resources.getBoolean(
|
||||
com.android.internal.R.bool.config_enable_puk_unlock_screen);
|
||||
mLockPatternUtils = lockPatternUtils;
|
||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
||||
}
|
||||
|
||||
public SecurityMode getSecurityMode(int userId) {
|
||||
KeyguardUpdateMonitor monitor = Dependency.get(KeyguardUpdateMonitor.class);
|
||||
|
||||
if (mIsPukScreenAvailable && SubscriptionManager.isValidSubscriptionId(
|
||||
monitor.getNextSubIdForState(TelephonyManager.SIM_STATE_PUK_REQUIRED))) {
|
||||
mKeyguardUpdateMonitor.getNextSubIdForState(
|
||||
TelephonyManager.SIM_STATE_PUK_REQUIRED))) {
|
||||
return SecurityMode.SimPuk;
|
||||
}
|
||||
|
||||
if (SubscriptionManager.isValidSubscriptionId(
|
||||
monitor.getNextSubIdForState(TelephonyManager.SIM_STATE_PIN_REQUIRED))) {
|
||||
mKeyguardUpdateMonitor.getNextSubIdForState(
|
||||
TelephonyManager.SIM_STATE_PIN_REQUIRED))) {
|
||||
return SecurityMode.SimPin;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,15 +44,18 @@ public class KeyguardSecurityViewFlipperController
|
||||
private final List<KeyguardInputViewController<KeyguardInputView>> mChildren =
|
||||
new ArrayList<>();
|
||||
private final LayoutInflater mLayoutInflater;
|
||||
private final EmergencyButtonController.Factory mEmergencyButtonControllerFactory;
|
||||
private final Factory mKeyguardSecurityViewControllerFactory;
|
||||
|
||||
@Inject
|
||||
protected KeyguardSecurityViewFlipperController(KeyguardSecurityViewFlipper view,
|
||||
LayoutInflater layoutInflater,
|
||||
KeyguardInputViewController.Factory keyguardSecurityViewControllerFactory) {
|
||||
KeyguardInputViewController.Factory keyguardSecurityViewControllerFactory,
|
||||
EmergencyButtonController.Factory emergencyButtonControllerFactory) {
|
||||
super(view);
|
||||
mKeyguardSecurityViewControllerFactory = keyguardSecurityViewControllerFactory;
|
||||
mLayoutInflater = layoutInflater;
|
||||
mEmergencyButtonControllerFactory = emergencyButtonControllerFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,7 +114,8 @@ public class KeyguardSecurityViewFlipperController
|
||||
|
||||
if (childController == null) {
|
||||
childController = new NullKeyguardInputViewController(
|
||||
securityMode, keyguardSecurityCallback);
|
||||
securityMode, keyguardSecurityCallback,
|
||||
mEmergencyButtonControllerFactory.create(null));
|
||||
}
|
||||
|
||||
return childController;
|
||||
@@ -140,8 +144,9 @@ public class KeyguardSecurityViewFlipperController
|
||||
private static class NullKeyguardInputViewController
|
||||
extends KeyguardInputViewController<KeyguardInputView> {
|
||||
protected NullKeyguardInputViewController(SecurityMode securityMode,
|
||||
KeyguardSecurityCallback keyguardSecurityCallback) {
|
||||
super(null, securityMode, keyguardSecurityCallback);
|
||||
KeyguardSecurityCallback keyguardSecurityCallback,
|
||||
EmergencyButtonController emergencyButtonController) {
|
||||
super(null, securityMode, keyguardSecurityCallback, emergencyButtonController);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -79,10 +79,10 @@ public class KeyguardSimPinViewController
|
||||
KeyguardMessageAreaController.Factory messageAreaControllerFactory,
|
||||
LatencyTracker latencyTracker, LiftToActivateListener liftToActivateListener,
|
||||
TelephonyManager telephonyManager, FalsingCollector falsingCollector,
|
||||
boolean isNewLayoutEnabled) {
|
||||
EmergencyButtonController emergencyButtonController, boolean isNewLayoutEnabled) {
|
||||
super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
|
||||
messageAreaControllerFactory, latencyTracker, liftToActivateListener,
|
||||
falsingCollector);
|
||||
emergencyButtonController, falsingCollector);
|
||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
||||
mTelephonyManager = telephonyManager;
|
||||
mSimImageView = mView.findViewById(R.id.keyguard_sim);
|
||||
|
||||
@@ -37,7 +37,6 @@ import android.widget.ImageView;
|
||||
import com.android.internal.util.LatencyTracker;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.classifier.FalsingCollector;
|
||||
|
||||
@@ -86,10 +85,10 @@ public class KeyguardSimPukViewController
|
||||
KeyguardMessageAreaController.Factory messageAreaControllerFactory,
|
||||
LatencyTracker latencyTracker, LiftToActivateListener liftToActivateListener,
|
||||
TelephonyManager telephonyManager, FalsingCollector falsingCollector,
|
||||
boolean isNewLayoutEnabled) {
|
||||
EmergencyButtonController emergencyButtonController, boolean isNewLayoutEnabled) {
|
||||
super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
|
||||
messageAreaControllerFactory, latencyTracker, liftToActivateListener,
|
||||
falsingCollector);
|
||||
emergencyButtonController, falsingCollector);
|
||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
||||
mTelephonyManager = telephonyManager;
|
||||
mSimImageView = mView.findViewById(R.id.keyguard_sim);
|
||||
@@ -198,8 +197,7 @@ public class KeyguardSimPukViewController
|
||||
if (count < 2) {
|
||||
msg = rez.getString(R.string.kg_puk_enter_puk_hint);
|
||||
} else {
|
||||
SubscriptionInfo info = Dependency.get(KeyguardUpdateMonitor.class)
|
||||
.getSubscriptionInfoForSubId(mSubId);
|
||||
SubscriptionInfo info = mKeyguardUpdateMonitor.getSubscriptionInfoForSubId(mSubId);
|
||||
CharSequence displayName = info != null ? info.getDisplayName() : "";
|
||||
msg = rez.getString(R.string.kg_puk_enter_puk_hint_multi, displayName);
|
||||
if (info != null) {
|
||||
|
||||
@@ -49,10 +49,8 @@ import androidx.slice.widget.SliceContent;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.graphics.ColorUtils;
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.Interpolators;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.util.wakelock.KeepAwakeAnimationListener;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
@@ -299,8 +297,23 @@ public class KeyguardSliceView extends LinearLayout {
|
||||
void onDensityOrFontScaleChanged() {
|
||||
mIconSize = mContext.getResources().getDimensionPixelSize(R.dimen.widget_icon_size);
|
||||
mIconSizeWithHeader = (int) mContext.getResources().getDimension(R.dimen.header_icon_size);
|
||||
|
||||
for (int i = 0; i < mRow.getChildCount(); i++) {
|
||||
View child = mRow.getChildAt(i);
|
||||
if (child instanceof KeyguardSliceTextView) {
|
||||
((KeyguardSliceTextView) child).onDensityOrFontScaleChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void onOverlayChanged() {
|
||||
for (int i = 0; i < mRow.getChildCount(); i++) {
|
||||
View child = mRow.getChildAt(i);
|
||||
if (child instanceof KeyguardSliceTextView) {
|
||||
((KeyguardSliceTextView) child).onOverlayChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
pw.println("KeyguardSliceView:");
|
||||
pw.println(" mTitle: " + (mTitle == null ? "null" : mTitle.getVisibility() == VISIBLE));
|
||||
@@ -466,8 +479,7 @@ public class KeyguardSliceView extends LinearLayout {
|
||||
* Representation of an item that appears under the clock on main keyguard message.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
static class KeyguardSliceTextView extends TextView implements
|
||||
ConfigurationController.ConfigurationListener {
|
||||
static class KeyguardSliceTextView extends TextView {
|
||||
private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
|
||||
|
||||
@StyleRes
|
||||
@@ -479,24 +491,10 @@ public class KeyguardSliceView extends LinearLayout {
|
||||
setEllipsize(TruncateAt.END);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
Dependency.get(ConfigurationController.class).addCallback(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
Dependency.get(ConfigurationController.class).removeCallback(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDensityOrFontScaleChanged() {
|
||||
updatePadding();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOverlayChanged() {
|
||||
setTextAppearance(sStyleId);
|
||||
}
|
||||
|
||||
@@ -83,6 +83,10 @@ public class KeyguardSliceViewController extends ViewController<KeyguardSliceVie
|
||||
public void onDensityOrFontScaleChanged() {
|
||||
mView.onDensityOrFontScaleChanged();
|
||||
}
|
||||
@Override
|
||||
public void onOverlayChanged() {
|
||||
mView.onOverlayChanged();
|
||||
}
|
||||
};
|
||||
|
||||
Observer<Slice> mObserver = new Observer<Slice>() {
|
||||
|
||||
@@ -34,7 +34,6 @@ import android.widget.TextView;
|
||||
import androidx.core.graphics.ColorUtils;
|
||||
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.R;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
@@ -56,7 +55,6 @@ public class KeyguardStatusView extends GridLayout {
|
||||
private final IActivityManager mIActivityManager;
|
||||
|
||||
private TextView mLogoutView;
|
||||
private boolean mCanShowLogout = true; // by default, try to show the logout button here
|
||||
private KeyguardClockSwitch mClockView;
|
||||
private TextView mOwnerInfo;
|
||||
private boolean mCanShowOwnerInfo = true; // by default, try to show the owner information here
|
||||
@@ -130,11 +128,6 @@ public class KeyguardStatusView extends GridLayout {
|
||||
}
|
||||
}
|
||||
|
||||
void setCanShowLogout(boolean canShowLogout) {
|
||||
mCanShowLogout = canShowLogout;
|
||||
updateLogoutView();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
@@ -159,10 +152,7 @@ public class KeyguardStatusView extends GridLayout {
|
||||
mKeyguardSlice.setContentChangeListener(this::onSliceContentChanged);
|
||||
onSliceContentChanged();
|
||||
|
||||
boolean shouldMarquee = Dependency.get(KeyguardUpdateMonitor.class).isDeviceInteractive();
|
||||
setEnableMarquee(shouldMarquee);
|
||||
updateOwnerInfo();
|
||||
updateLogoutView();
|
||||
updateDark();
|
||||
}
|
||||
|
||||
@@ -209,11 +199,11 @@ public class KeyguardStatusView extends GridLayout {
|
||||
return mOwnerInfo.getVisibility() == VISIBLE ? mOwnerInfo.getHeight() : 0;
|
||||
}
|
||||
|
||||
void updateLogoutView() {
|
||||
void updateLogoutView(boolean shouldShowLogout) {
|
||||
if (mLogoutView == null) {
|
||||
return;
|
||||
}
|
||||
mLogoutView.setVisibility(mCanShowLogout && shouldShowLogout() ? VISIBLE : GONE);
|
||||
mLogoutView.setVisibility(shouldShowLogout ? VISIBLE : GONE);
|
||||
// Logout button will stay in language of user 0 if we don't set that manually.
|
||||
mLogoutView.setText(mContext.getResources().getString(
|
||||
com.android.internal.R.string.global_action_logout));
|
||||
@@ -313,11 +303,6 @@ public class KeyguardStatusView extends GridLayout {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldShowLogout() {
|
||||
return Dependency.get(KeyguardUpdateMonitor.class).isLogoutEnabled()
|
||||
&& KeyguardUpdateMonitor.getCurrentUser() != UserHandle.USER_SYSTEM;
|
||||
}
|
||||
|
||||
private void onLogoutClicked(View view) {
|
||||
int currentUserId = KeyguardUpdateMonitor.getCurrentUser();
|
||||
try {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.keyguard;
|
||||
|
||||
import android.os.UserHandle;
|
||||
import android.util.Slog;
|
||||
import android.view.View;
|
||||
|
||||
@@ -78,6 +79,8 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
|
||||
@Override
|
||||
public void onInit() {
|
||||
mKeyguardClockSwitchController.init();
|
||||
mView.setEnableMarquee(mKeyguardUpdateMonitor.isDeviceInteractive());
|
||||
mView.updateLogoutView(shouldShowLogout());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -245,6 +248,11 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldShowLogout() {
|
||||
return mKeyguardUpdateMonitor.isLogoutEnabled()
|
||||
&& KeyguardUpdateMonitor.getCurrentUser() != UserHandle.USER_SYSTEM;
|
||||
}
|
||||
|
||||
private final ConfigurationController.ConfigurationListener mConfigurationListener =
|
||||
new ConfigurationController.ConfigurationListener() {
|
||||
@Override
|
||||
@@ -267,10 +275,10 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
|
||||
mKeyguardSliceViewController.updateLockScreenMode(mode);
|
||||
if (mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
|
||||
mView.setCanShowOwnerInfo(false);
|
||||
mView.setCanShowLogout(false);
|
||||
mView.updateLogoutView(false);
|
||||
} else {
|
||||
mView.setCanShowOwnerInfo(true);
|
||||
mView.setCanShowLogout(false);
|
||||
mView.updateLogoutView(false);
|
||||
}
|
||||
updateAodIcons();
|
||||
}
|
||||
@@ -296,7 +304,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
|
||||
if (DEBUG) Slog.v(TAG, "refresh statusview showing:" + showing);
|
||||
refreshTime();
|
||||
mView.updateOwnerInfo();
|
||||
mView.updateLogoutView();
|
||||
mView.updateLogoutView(shouldShowLogout());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,12 +322,12 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
|
||||
public void onUserSwitchComplete(int userId) {
|
||||
mKeyguardClockSwitchController.refreshFormat();
|
||||
mView.updateOwnerInfo();
|
||||
mView.updateLogoutView();
|
||||
mView.updateLogoutView(shouldShowLogout());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLogoutEnabledChanged() {
|
||||
mView.updateLogoutView();
|
||||
mView.updateLogoutView(shouldShowLogout());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import static android.content.Intent.ACTION_USER_REMOVED;
|
||||
import static android.content.Intent.ACTION_USER_STOPPED;
|
||||
import static android.content.Intent.ACTION_USER_UNLOCKED;
|
||||
import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
|
||||
import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
|
||||
|
||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
|
||||
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
|
||||
@@ -76,11 +75,11 @@ import android.provider.Settings;
|
||||
import android.service.dreams.DreamService;
|
||||
import android.service.dreams.IDreamManager;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
|
||||
import android.telephony.TelephonyCallback;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
@@ -107,6 +106,7 @@ import com.android.systemui.shared.system.TaskStackChangeListeners;
|
||||
import com.android.systemui.statusbar.FeatureFlags;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.phone.KeyguardBypassController;
|
||||
import com.android.systemui.telephony.TelephonyListenerManager;
|
||||
import com.android.systemui.util.Assert;
|
||||
import com.android.systemui.util.RingerModeTracker;
|
||||
|
||||
@@ -290,6 +290,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
||||
private boolean mDeviceInteractive;
|
||||
private boolean mScreenOn;
|
||||
private SubscriptionManager mSubscriptionManager;
|
||||
private final TelephonyListenerManager mTelephonyListenerManager;
|
||||
private List<SubscriptionInfo> mSubscriptionInfo;
|
||||
private TrustManager mTrustManager;
|
||||
private UserManager mUserManager;
|
||||
@@ -358,7 +359,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
||||
};
|
||||
|
||||
@VisibleForTesting
|
||||
public PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
|
||||
public TelephonyCallback.ActiveDataSubscriptionIdListener mPhoneStateListener =
|
||||
new TelephonyCallback.ActiveDataSubscriptionIdListener() {
|
||||
@Override
|
||||
public void onActiveDataSubscriptionIdChanged(int subId) {
|
||||
mActiveMobileDataSubscription = subId;
|
||||
@@ -1614,9 +1616,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
||||
StatusBarStateController statusBarStateController,
|
||||
LockPatternUtils lockPatternUtils,
|
||||
AuthController authController,
|
||||
TelephonyListenerManager telephonyListenerManager,
|
||||
FeatureFlags featureFlags) {
|
||||
mContext = context;
|
||||
mSubscriptionManager = SubscriptionManager.from(context);
|
||||
mTelephonyListenerManager = telephonyListenerManager;
|
||||
mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
|
||||
mStrongAuthTracker = new StrongAuthTracker(context, this::notifyStrongAuthStateChanged);
|
||||
mBackgroundExecutor = backgroundExecutor;
|
||||
@@ -1865,8 +1869,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
||||
mTelephonyManager =
|
||||
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
if (mTelephonyManager != null) {
|
||||
mTelephonyManager.listen(mPhoneStateListener,
|
||||
LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
|
||||
mTelephonyListenerManager.addActiveDataSubscriptionIdListener(mPhoneStateListener);
|
||||
// Set initial sim states values.
|
||||
for (int slot = 0; slot < mTelephonyManager.getActiveModemCount(); slot++) {
|
||||
int state = mTelephonyManager.getSimState(slot);
|
||||
@@ -3123,7 +3126,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
|
||||
TelephonyManager telephony =
|
||||
(TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
if (telephony != null) {
|
||||
telephony.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
|
||||
mTelephonyListenerManager.removeActiveDataSubscriptionIdListener(mPhoneStateListener);
|
||||
}
|
||||
|
||||
mSubscriptionManager.removeOnSubscriptionsChangedListener(mSubscriptionListener);
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.keyguard.clock;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
/** Dagger Module for clock package. */
|
||||
@Module
|
||||
public abstract class ClockModule {
|
||||
|
||||
/** */
|
||||
@Provides
|
||||
public static List<ClockInfo> provideClockInfoList(ClockManager clockManager) {
|
||||
return clockManager.getClockInfos();
|
||||
}
|
||||
}
|
||||
@@ -28,11 +28,12 @@ import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.systemui.Dependency;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Provider;
|
||||
|
||||
/**
|
||||
* Exposes custom clock face options and provides realistic preview images.
|
||||
@@ -65,15 +66,12 @@ public final class ClockOptionsProvider extends ContentProvider {
|
||||
private static final String CONTENT_SCHEME = "content";
|
||||
private static final String AUTHORITY = "com.android.keyguard.clock";
|
||||
|
||||
private final Supplier<List<ClockInfo>> mClocksSupplier;
|
||||
|
||||
public ClockOptionsProvider() {
|
||||
this(() -> Dependency.get(ClockManager.class).getClockInfos());
|
||||
}
|
||||
@Inject
|
||||
public Provider<List<ClockInfo>> mClockInfosProvider;
|
||||
|
||||
@VisibleForTesting
|
||||
ClockOptionsProvider(Supplier<List<ClockInfo>> clocksSupplier) {
|
||||
mClocksSupplier = clocksSupplier;
|
||||
ClockOptionsProvider(Provider<List<ClockInfo>> clockInfosProvider) {
|
||||
mClockInfosProvider = clockInfosProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,7 +97,7 @@ public final class ClockOptionsProvider extends ContentProvider {
|
||||
}
|
||||
MatrixCursor cursor = new MatrixCursor(new String[] {
|
||||
COLUMN_NAME, COLUMN_TITLE, COLUMN_ID, COLUMN_THUMBNAIL, COLUMN_PREVIEW});
|
||||
List<ClockInfo> clocks = mClocksSupplier.get();
|
||||
List<ClockInfo> clocks = mClockInfosProvider.get();
|
||||
for (int i = 0; i < clocks.size(); i++) {
|
||||
ClockInfo clock = clocks.get(i);
|
||||
cursor.newRow()
|
||||
@@ -139,7 +137,7 @@ public final class ClockOptionsProvider extends ContentProvider {
|
||||
throw new FileNotFoundException("Invalid preview url, missing id");
|
||||
}
|
||||
ClockInfo clock = null;
|
||||
List<ClockInfo> clocks = mClocksSupplier.get();
|
||||
List<ClockInfo> clocks = mClockInfosProvider.get();
|
||||
for (int i = 0; i < clocks.size(); i++) {
|
||||
if (id.equals(clocks.get(i).getId())) {
|
||||
clock = clocks.get(i);
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.keyguard.dagger;
|
||||
|
||||
import com.android.keyguard.KeyguardStatusViewController;
|
||||
import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
|
||||
import com.android.systemui.statusbar.phone.KeyguardStatusBarViewController;
|
||||
|
||||
import dagger.BindsInstance;
|
||||
import dagger.Subcomponent;
|
||||
|
||||
/**
|
||||
* Subcomponent for helping work with KeyguardStatusView and its children.
|
||||
*
|
||||
* TODO: unify this with {@link KeyguardStatusViewComponent}
|
||||
*/
|
||||
@Subcomponent(modules = {KeyguardStatusBarViewModule.class})
|
||||
@KeyguardStatusBarViewScope
|
||||
public interface KeyguardStatusBarViewComponent {
|
||||
/** Simple factory for {@link KeyguardStatusBarViewComponent}. */
|
||||
@Subcomponent.Factory
|
||||
interface Factory {
|
||||
KeyguardStatusBarViewComponent build(@BindsInstance KeyguardStatusBarView view);
|
||||
}
|
||||
|
||||
/** Builds a {@link KeyguardStatusViewController}. */
|
||||
KeyguardStatusBarViewController getKeyguardStatusBarViewController();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.keyguard.dagger;
|
||||
|
||||
import com.android.keyguard.CarrierText;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.phone.KeyguardStatusBarView;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
/** Dagger module for {@link KeyguardStatusBarViewComponent}. */
|
||||
@Module
|
||||
public abstract class KeyguardStatusBarViewModule {
|
||||
@Provides
|
||||
@KeyguardStatusBarViewScope
|
||||
static CarrierText getCarrierText(KeyguardStatusBarView view) {
|
||||
return view.findViewById(R.id.keyguard_carrier_text);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.keyguard.dagger;
|
||||
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.Retention;
|
||||
|
||||
import javax.inject.Scope;
|
||||
|
||||
/**
|
||||
* Scope annotation for singleton items within the StatusBarComponent.
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RUNTIME)
|
||||
@Scope
|
||||
public @interface KeyguardStatusBarViewScope {}
|
||||
@@ -25,6 +25,8 @@ import dagger.Subcomponent;
|
||||
|
||||
/**
|
||||
* Subcomponent for helping work with KeyguardStatusView and its children.
|
||||
*
|
||||
* TODO: unify this with {@link KeyguardStatusBarViewComponent}
|
||||
*/
|
||||
@Subcomponent(modules = {KeyguardStatusViewModule.class})
|
||||
@KeyguardStatusViewScope
|
||||
|
||||
@@ -120,6 +120,7 @@ import com.android.systemui.statusbar.policy.SmartReplyConstants;
|
||||
import com.android.systemui.statusbar.policy.UserInfoController;
|
||||
import com.android.systemui.statusbar.policy.UserSwitcherController;
|
||||
import com.android.systemui.statusbar.policy.ZenModeController;
|
||||
import com.android.systemui.telephony.TelephonyListenerManager;
|
||||
import com.android.systemui.tracing.ProtoTracer;
|
||||
import com.android.systemui.tuner.TunablePadding.TunablePaddingService;
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
@@ -350,6 +351,7 @@ public class Dependency {
|
||||
@Inject Lazy<MediaOutputDialogFactory> mMediaOutputDialogFactory;
|
||||
@Inject Lazy<DeviceConfigProxy> mDeviceConfigProxy;
|
||||
@Inject Lazy<NavigationBarOverlayController> mNavbarButtonsControllerLazy;
|
||||
@Inject Lazy<TelephonyListenerManager> mTelephonyListenerManager;
|
||||
|
||||
@Inject
|
||||
public Dependency() {
|
||||
@@ -545,6 +547,7 @@ public class Dependency {
|
||||
mProviders.put(StatusBar.class, mStatusBar::get);
|
||||
mProviders.put(ProtoTracer.class, mProtoTracer::get);
|
||||
mProviders.put(DeviceConfigProxy.class, mDeviceConfigProxy::get);
|
||||
mProviders.put(TelephonyListenerManager.class, mTelephonyListenerManager::get);
|
||||
|
||||
// TODO(b/118592525): to support multi-display , we start to add something which is
|
||||
// per-display, while others may be global. I think it's time to add
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.dagger;
|
||||
|
||||
import com.android.keyguard.clock.ClockOptionsProvider;
|
||||
import com.android.systemui.BootCompleteCacheImpl;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.InitController;
|
||||
@@ -150,4 +151,9 @@ public interface SysUIComponent {
|
||||
* Member injection into the supplied argument.
|
||||
*/
|
||||
void inject(KeyguardSliceProvider keyguardSliceProvider);
|
||||
|
||||
/**
|
||||
* Member injection into the supplied argument.
|
||||
*/
|
||||
void inject(ClockOptionsProvider clockOptionsProvider);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.content.Context;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.internal.statusbar.IStatusBarService;
|
||||
import com.android.keyguard.clock.ClockModule;
|
||||
import com.android.keyguard.dagger.KeyguardBouncerComponent;
|
||||
import com.android.systemui.BootCompleteCache;
|
||||
import com.android.systemui.BootCompleteCacheImpl;
|
||||
@@ -90,6 +91,7 @@ import dagger.Provides;
|
||||
@Module(includes = {
|
||||
AppOpsModule.class,
|
||||
AssistModule.class,
|
||||
ClockModule.class,
|
||||
ControlsModule.class,
|
||||
DemoModeModule.class,
|
||||
FalsingModule.class,
|
||||
|
||||
@@ -73,8 +73,8 @@ import android.provider.Settings;
|
||||
import android.service.dreams.IDreamManager;
|
||||
import android.sysprop.TelephonyProperties;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.TelephonyCallback;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.transition.AutoTransition;
|
||||
import android.transition.TransitionManager;
|
||||
@@ -138,6 +138,7 @@ import com.android.systemui.statusbar.NotificationShadeDepthController;
|
||||
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
import com.android.systemui.telephony.TelephonyListenerManager;
|
||||
import com.android.systemui.util.EmergencyDialerConstants;
|
||||
import com.android.systemui.util.RingerModeTracker;
|
||||
import com.android.systemui.util.leak.RotationUtils;
|
||||
@@ -303,7 +304,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
AudioManager audioManager, IDreamManager iDreamManager,
|
||||
DevicePolicyManager devicePolicyManager, LockPatternUtils lockPatternUtils,
|
||||
BroadcastDispatcher broadcastDispatcher,
|
||||
ConnectivityManager connectivityManager, TelephonyManager telephonyManager,
|
||||
ConnectivityManager connectivityManager,
|
||||
TelephonyListenerManager telephonyListenerManager,
|
||||
ContentResolver contentResolver, @Nullable Vibrator vibrator, @Main Resources resources,
|
||||
ConfigurationController configurationController, ActivityStarter activityStarter,
|
||||
KeyguardStateController keyguardStateController, UserManager userManager,
|
||||
@@ -361,7 +363,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
|
||||
|
||||
// get notified of phone state changes
|
||||
telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_SERVICE_STATE);
|
||||
telephonyListenerManager.addServiceStateListener(mPhoneStateListener);
|
||||
contentResolver.registerContentObserver(
|
||||
Settings.Global.getUriFor(Settings.Global.AIRPLANE_MODE_ON), true,
|
||||
mAirplaneModeObserver);
|
||||
@@ -2049,7 +2051,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
}
|
||||
};
|
||||
|
||||
PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
|
||||
private final TelephonyCallback.ServiceStateListener mPhoneStateListener =
|
||||
new TelephonyCallback.ServiceStateListener() {
|
||||
@Override
|
||||
public void onServiceStateChanged(ServiceState serviceState) {
|
||||
if (!mHasTelephony) return;
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.android.keyguard.KeyguardDisplayManager;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.KeyguardViewController;
|
||||
import com.android.keyguard.dagger.KeyguardQsUserSwitchComponent;
|
||||
import com.android.keyguard.dagger.KeyguardStatusBarViewComponent;
|
||||
import com.android.keyguard.dagger.KeyguardStatusViewComponent;
|
||||
import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||
@@ -63,8 +64,11 @@ import dagger.Provides;
|
||||
/**
|
||||
* Dagger Module providing {@link StatusBar}.
|
||||
*/
|
||||
@Module(subcomponents = {KeyguardStatusViewComponent.class,
|
||||
KeyguardQsUserSwitchComponent.class, KeyguardUserSwitcherComponent.class},
|
||||
@Module(subcomponents = {
|
||||
KeyguardQsUserSwitchComponent.class,
|
||||
KeyguardStatusBarViewComponent.class,
|
||||
KeyguardStatusViewComponent.class,
|
||||
KeyguardUserSwitcherComponent.class},
|
||||
includes = {FalsingModule.class})
|
||||
public class KeyguardModule {
|
||||
/**
|
||||
|
||||
@@ -34,7 +34,7 @@ import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.keyguard.CarrierTextController;
|
||||
import com.android.keyguard.CarrierTextManager;
|
||||
import com.android.settingslib.AccessibilityContentDescriptions;
|
||||
import com.android.settingslib.mobile.TelephonyIcons;
|
||||
import com.android.systemui.R;
|
||||
@@ -59,7 +59,7 @@ public class QSCarrierGroupController {
|
||||
private final ActivityStarter mActivityStarter;
|
||||
private final Handler mBgHandler;
|
||||
private final NetworkController mNetworkController;
|
||||
private final CarrierTextController mCarrierTextController;
|
||||
private final CarrierTextManager mCarrierTextManager;
|
||||
private final TextView mNoSimTextView;
|
||||
private final H mMainHandler;
|
||||
private final Callback mCallback;
|
||||
@@ -149,7 +149,7 @@ public class QSCarrierGroupController {
|
||||
}
|
||||
};
|
||||
|
||||
private static class Callback implements CarrierTextController.CarrierTextCallback {
|
||||
private static class Callback implements CarrierTextManager.CarrierTextCallback {
|
||||
private H mHandler;
|
||||
|
||||
Callback(H handler) {
|
||||
@@ -157,7 +157,7 @@ public class QSCarrierGroupController {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) {
|
||||
public void updateCarrierInfo(CarrierTextManager.CarrierTextCallbackInfo info) {
|
||||
mHandler.obtainMessage(H.MSG_UPDATE_CARRIER_INFO, info).sendToTarget();
|
||||
}
|
||||
}
|
||||
@@ -165,7 +165,7 @@ public class QSCarrierGroupController {
|
||||
private QSCarrierGroupController(QSCarrierGroup view, ActivityStarter activityStarter,
|
||||
@Background Handler bgHandler, @Main Looper mainLooper,
|
||||
NetworkController networkController,
|
||||
CarrierTextController.Builder carrierTextControllerBuilder, Context context) {
|
||||
CarrierTextManager.Builder carrierTextManagerBuilder, Context context) {
|
||||
if (FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL)) {
|
||||
mProviderModel = true;
|
||||
} else {
|
||||
@@ -174,7 +174,7 @@ public class QSCarrierGroupController {
|
||||
mActivityStarter = activityStarter;
|
||||
mBgHandler = bgHandler;
|
||||
mNetworkController = networkController;
|
||||
mCarrierTextController = carrierTextControllerBuilder
|
||||
mCarrierTextManager = carrierTextManagerBuilder
|
||||
.setShowAirplaneMode(false)
|
||||
.setShowMissingSim(false)
|
||||
.build();
|
||||
@@ -192,7 +192,6 @@ public class QSCarrierGroupController {
|
||||
mMainHandler = new H(mainLooper, this::handleUpdateCarrierInfo, this::handleUpdateState);
|
||||
mCallback = new Callback(mMainHandler);
|
||||
|
||||
|
||||
mCarrierGroups[0] = view.getCarrier1View();
|
||||
mCarrierGroups[1] = view.getCarrier2View();
|
||||
mCarrierGroups[2] = view.getCarrier3View();
|
||||
@@ -243,10 +242,10 @@ public class QSCarrierGroupController {
|
||||
if (mNetworkController.hasVoiceCallingFeature()) {
|
||||
mNetworkController.addCallback(mSignalCallback);
|
||||
}
|
||||
mCarrierTextController.setListening(mCallback);
|
||||
mCarrierTextManager.setListening(mCallback);
|
||||
} else {
|
||||
mNetworkController.removeCallback(mSignalCallback);
|
||||
mCarrierTextController.setListening(null);
|
||||
mCarrierTextManager.setListening(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,7 +272,7 @@ public class QSCarrierGroupController {
|
||||
}
|
||||
|
||||
@MainThread
|
||||
private void handleUpdateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) {
|
||||
private void handleUpdateCarrierInfo(CarrierTextManager.CarrierTextCallbackInfo info) {
|
||||
if (!mMainHandler.getLooper().isCurrentThread()) {
|
||||
mMainHandler.obtainMessage(H.MSG_UPDATE_CARRIER_INFO, info).sendToTarget();
|
||||
return;
|
||||
@@ -327,13 +326,13 @@ public class QSCarrierGroupController {
|
||||
}
|
||||
|
||||
private static class H extends Handler {
|
||||
private Consumer<CarrierTextController.CarrierTextCallbackInfo> mUpdateCarrierInfo;
|
||||
private Consumer<CarrierTextManager.CarrierTextCallbackInfo> mUpdateCarrierInfo;
|
||||
private Runnable mUpdateState;
|
||||
static final int MSG_UPDATE_CARRIER_INFO = 0;
|
||||
static final int MSG_UPDATE_STATE = 1;
|
||||
|
||||
H(Looper looper,
|
||||
Consumer<CarrierTextController.CarrierTextCallbackInfo> updateCarrierInfo,
|
||||
Consumer<CarrierTextManager.CarrierTextCallbackInfo> updateCarrierInfo,
|
||||
Runnable updateState) {
|
||||
super(looper);
|
||||
mUpdateCarrierInfo = updateCarrierInfo;
|
||||
@@ -345,7 +344,7 @@ public class QSCarrierGroupController {
|
||||
switch (msg.what) {
|
||||
case MSG_UPDATE_CARRIER_INFO:
|
||||
mUpdateCarrierInfo.accept(
|
||||
(CarrierTextController.CarrierTextCallbackInfo) msg.obj);
|
||||
(CarrierTextManager.CarrierTextCallbackInfo) msg.obj);
|
||||
break;
|
||||
case MSG_UPDATE_STATE:
|
||||
mUpdateState.run();
|
||||
@@ -362,13 +361,13 @@ public class QSCarrierGroupController {
|
||||
private final Handler mHandler;
|
||||
private final Looper mLooper;
|
||||
private final NetworkController mNetworkController;
|
||||
private final CarrierTextController.Builder mCarrierTextControllerBuilder;
|
||||
private final CarrierTextManager.Builder mCarrierTextControllerBuilder;
|
||||
private final Context mContext;
|
||||
|
||||
@Inject
|
||||
public Builder(ActivityStarter activityStarter, @Background Handler handler,
|
||||
@Main Looper looper, NetworkController networkController,
|
||||
CarrierTextController.Builder carrierTextControllerBuilder, Context context) {
|
||||
CarrierTextManager.Builder carrierTextControllerBuilder, Context context) {
|
||||
mActivityStarter = activityStarter;
|
||||
mHandler = handler;
|
||||
mLooper = looper;
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.phone;
|
||||
|
||||
import com.android.keyguard.CarrierTextController;
|
||||
import com.android.systemui.util.ViewController;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/** View Controller for {@link com.android.systemui.statusbar.phone.KeyguardStatusBarView}. */
|
||||
public class KeyguardStatusBarViewController extends ViewController<KeyguardStatusBarView> {
|
||||
private final CarrierTextController mCarrierTextController;
|
||||
|
||||
@Inject
|
||||
public KeyguardStatusBarViewController(
|
||||
KeyguardStatusBarView view, CarrierTextController carrierTextController) {
|
||||
super(view);
|
||||
mCarrierTextController = carrierTextController;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInit() {
|
||||
super.onInit();
|
||||
mCarrierTextController.init();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onViewAttached() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onViewDetached() {
|
||||
}
|
||||
}
|
||||
@@ -83,6 +83,7 @@ import com.android.keyguard.KeyguardStatusViewController;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||
import com.android.keyguard.dagger.KeyguardQsUserSwitchComponent;
|
||||
import com.android.keyguard.dagger.KeyguardStatusBarViewComponent;
|
||||
import com.android.keyguard.dagger.KeyguardStatusViewComponent;
|
||||
import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
|
||||
import com.android.systemui.DejankUtils;
|
||||
@@ -298,6 +299,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
private final KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
|
||||
private final KeyguardQsUserSwitchComponent.Factory mKeyguardQsUserSwitchComponentFactory;
|
||||
private final KeyguardUserSwitcherComponent.Factory mKeyguardUserSwitcherComponentFactory;
|
||||
private final KeyguardStatusBarViewComponent.Factory mKeyguardStatusBarViewComponentFactory;
|
||||
private final QSDetailDisplayer mQSDetailDisplayer;
|
||||
private final FeatureFlags mFeatureFlags;
|
||||
private final ScrimController mScrimController;
|
||||
@@ -313,6 +315,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
private KeyguardQsUserSwitchController mKeyguardQsUserSwitchController;
|
||||
private KeyguardUserSwitcherController mKeyguardUserSwitcherController;
|
||||
private KeyguardStatusBarView mKeyguardStatusBar;
|
||||
private KeyguardStatusBarViewController mKeyguarStatusBarViewController;
|
||||
private ViewGroup mBigClockContainer;
|
||||
private QS mQs;
|
||||
private FrameLayout mQsFrame;
|
||||
@@ -565,6 +568,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
KeyguardStatusViewComponent.Factory keyguardStatusViewComponentFactory,
|
||||
KeyguardQsUserSwitchComponent.Factory keyguardQsUserSwitchComponentFactory,
|
||||
KeyguardUserSwitcherComponent.Factory keyguardUserSwitcherComponentFactory,
|
||||
KeyguardStatusBarViewComponent.Factory keyguardStatusBarViewComponentFactory,
|
||||
QSDetailDisplayer qsDetailDisplayer,
|
||||
NotificationGroupManagerLegacy groupManager,
|
||||
NotificationIconAreaController notificationIconAreaController,
|
||||
@@ -589,6 +593,7 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
mGroupManager = groupManager;
|
||||
mNotificationIconAreaController = notificationIconAreaController;
|
||||
mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory;
|
||||
mKeyguardStatusBarViewComponentFactory = keyguardStatusBarViewComponentFactory;
|
||||
mFeatureFlags = featureFlags;
|
||||
mKeyguardQsUserSwitchComponentFactory = keyguardQsUserSwitchComponentFactory;
|
||||
mKeyguardUserSwitcherComponentFactory = keyguardUserSwitcherComponentFactory;
|
||||
@@ -693,7 +698,9 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
}
|
||||
|
||||
updateViewControllers(mView.findViewById(R.id.keyguard_status_view),
|
||||
userAvatarView, keyguardUserSwitcherView);
|
||||
userAvatarView,
|
||||
mKeyguardStatusBar,
|
||||
keyguardUserSwitcherView);
|
||||
mNotificationContainerParent = mView.findViewById(R.id.notification_container_parent);
|
||||
NotificationStackScrollLayout stackScrollLayout = mView.findViewById(
|
||||
R.id.notification_stack_scroller);
|
||||
@@ -773,13 +780,21 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
}
|
||||
|
||||
private void updateViewControllers(KeyguardStatusView keyguardStatusView,
|
||||
UserAvatarView userAvatarView, KeyguardUserSwitcherView keyguardUserSwitcherView) {
|
||||
UserAvatarView userAvatarView,
|
||||
KeyguardStatusBarView keyguardStatusBarView,
|
||||
KeyguardUserSwitcherView keyguardUserSwitcherView) {
|
||||
// Re-associate the KeyguardStatusViewController
|
||||
KeyguardStatusViewComponent statusViewComponent =
|
||||
mKeyguardStatusViewComponentFactory.build(keyguardStatusView);
|
||||
mKeyguardStatusViewController = statusViewComponent.getKeyguardStatusViewController();
|
||||
mKeyguardStatusViewController.init();
|
||||
|
||||
KeyguardStatusBarViewComponent statusBarViewComponent =
|
||||
mKeyguardStatusBarViewComponentFactory.build(keyguardStatusBarView);
|
||||
mKeyguarStatusBarViewController =
|
||||
statusBarViewComponent.getKeyguardStatusBarViewController();
|
||||
mKeyguarStatusBarViewController.init();
|
||||
|
||||
// Re-associate the clock container with the keyguard clock switch.
|
||||
KeyguardClockSwitchController keyguardClockSwitchController =
|
||||
statusViewComponent.getKeyguardClockSwitchController();
|
||||
@@ -919,7 +934,8 @@ public class NotificationPanelViewController extends PanelViewController {
|
||||
showKeyguardUserSwitcher /* enabled */);
|
||||
|
||||
mBigClockContainer.removeAllViews();
|
||||
updateViewControllers(keyguardStatusView, userAvatarView, keyguardUserSwitcherView);
|
||||
updateViewControllers(
|
||||
keyguardStatusView, userAvatarView, mKeyguardStatusBar, keyguardUserSwitcherView);
|
||||
|
||||
// Update keyguard bottom area
|
||||
index = mView.indexOfChild(mKeyguardBottomArea);
|
||||
|
||||
@@ -22,7 +22,6 @@ import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_IN
|
||||
import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_INOUT;
|
||||
import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_NONE;
|
||||
import static android.net.wifi.WifiManager.TrafficStateCallback.DATA_ACTIVITY_OUT;
|
||||
import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.content.BroadcastReceiver;
|
||||
@@ -44,11 +43,11 @@ import android.os.Looper;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.CellSignalStrength;
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
|
||||
import android.telephony.TelephonyCallback;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.FeatureFlagUtils;
|
||||
@@ -74,6 +73,7 @@ import com.android.systemui.demomode.DemoMode;
|
||||
import com.android.systemui.demomode.DemoModeController;
|
||||
import com.android.systemui.settings.CurrentUserTracker;
|
||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
|
||||
import com.android.systemui.telephony.TelephonyListenerManager;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
@@ -108,6 +108,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
|
||||
|
||||
private final Context mContext;
|
||||
private final TelephonyManager mPhone;
|
||||
private final TelephonyListenerManager mTelephonyListenerManager;
|
||||
private final WifiManager mWifiManager;
|
||||
private final ConnectivityManager mConnectivityManager;
|
||||
private final SubscriptionManager mSubscriptionManager;
|
||||
@@ -121,7 +122,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
|
||||
private final boolean mProviderModel;
|
||||
private Config mConfig;
|
||||
|
||||
private PhoneStateListener mPhoneStateListener;
|
||||
private TelephonyCallback.ActiveDataSubscriptionIdListener mPhoneStateListener;
|
||||
private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
|
||||
// Subcontrollers.
|
||||
@@ -201,12 +202,14 @@ public class NetworkControllerImpl extends BroadcastReceiver
|
||||
BroadcastDispatcher broadcastDispatcher,
|
||||
ConnectivityManager connectivityManager,
|
||||
TelephonyManager telephonyManager,
|
||||
TelephonyListenerManager telephonyListenerManager,
|
||||
@Nullable WifiManager wifiManager,
|
||||
NetworkScoreManager networkScoreManager,
|
||||
AccessPointControllerImpl accessPointController,
|
||||
DemoModeController demoModeController) {
|
||||
this(context, connectivityManager,
|
||||
telephonyManager,
|
||||
telephonyListenerManager,
|
||||
wifiManager,
|
||||
networkScoreManager,
|
||||
SubscriptionManager.from(context), Config.readConfig(context), bgLooper,
|
||||
@@ -222,7 +225,9 @@ public class NetworkControllerImpl extends BroadcastReceiver
|
||||
|
||||
@VisibleForTesting
|
||||
NetworkControllerImpl(Context context, ConnectivityManager connectivityManager,
|
||||
TelephonyManager telephonyManager, WifiManager wifiManager,
|
||||
TelephonyManager telephonyManager,
|
||||
TelephonyListenerManager telephonyListenerManager,
|
||||
WifiManager wifiManager,
|
||||
NetworkScoreManager networkScoreManager,
|
||||
SubscriptionManager subManager, Config config, Looper bgLooper,
|
||||
CallbackHandler callbackHandler,
|
||||
@@ -233,6 +238,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
|
||||
BroadcastDispatcher broadcastDispatcher,
|
||||
DemoModeController demoModeController) {
|
||||
mContext = context;
|
||||
mTelephonyListenerManager = telephonyListenerManager;
|
||||
mConfig = config;
|
||||
mReceiverHandler = new Handler(bgLooper);
|
||||
mCallbackHandler = callbackHandler;
|
||||
@@ -372,23 +378,20 @@ public class NetworkControllerImpl extends BroadcastReceiver
|
||||
// exclusively for status bar icons.
|
||||
mConnectivityManager.registerDefaultNetworkCallback(callback, mReceiverHandler);
|
||||
// Register the listener on our bg looper
|
||||
mPhoneStateListener = new PhoneStateListener(mReceiverHandler::post) {
|
||||
@Override
|
||||
public void onActiveDataSubscriptionIdChanged(int subId) {
|
||||
// For data switching from A to B, we assume B is validated for up to 2 seconds iff:
|
||||
// 1) A and B are in the same subscription group e.g. CBRS data switch. And
|
||||
// 2) A was validated before the switch.
|
||||
// This is to provide smooth transition for UI without showing cross during data
|
||||
// switch.
|
||||
if (keepCellularValidationBitInSwitch(mActiveMobileDataSubscription, subId)) {
|
||||
if (DEBUG) Log.d(TAG, ": mForceCellularValidated to true.");
|
||||
mForceCellularValidated = true;
|
||||
mReceiverHandler.removeCallbacks(mClearForceValidated);
|
||||
mReceiverHandler.postDelayed(mClearForceValidated, 2000);
|
||||
}
|
||||
mActiveMobileDataSubscription = subId;
|
||||
doUpdateMobileControllers();
|
||||
mPhoneStateListener = subId -> {
|
||||
// For data switching from A to B, we assume B is validated for up to 2 seconds iff:
|
||||
// 1) A and B are in the same subscription group e.g. CBRS data switch. And
|
||||
// 2) A was validated before the switch.
|
||||
// This is to provide smooth transition for UI without showing cross during data
|
||||
// switch.
|
||||
if (keepCellularValidationBitInSwitch(mActiveMobileDataSubscription, subId)) {
|
||||
if (DEBUG) Log.d(TAG, ": mForceCellularValidated to true.");
|
||||
mForceCellularValidated = true;
|
||||
mReceiverHandler.removeCallbacks(mClearForceValidated);
|
||||
mReceiverHandler.postDelayed(mClearForceValidated, 2000);
|
||||
}
|
||||
mActiveMobileDataSubscription = subId;
|
||||
doUpdateMobileControllers();
|
||||
};
|
||||
|
||||
mDemoModeController.addCallback(this);
|
||||
@@ -428,7 +431,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
|
||||
mSubscriptionListener = new SubListener();
|
||||
}
|
||||
mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
|
||||
mPhone.listen(mPhoneStateListener, LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
|
||||
mTelephonyListenerManager.addActiveDataSubscriptionIdListener(mPhoneStateListener);
|
||||
|
||||
// broadcasts
|
||||
IntentFilter filter = new IntentFilter();
|
||||
|
||||
@@ -42,8 +42,7 @@ import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.telephony.TelephonyCallback;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseBooleanArray;
|
||||
@@ -69,6 +68,7 @@ import com.android.systemui.plugins.qs.DetailAdapter;
|
||||
import com.android.systemui.qs.QSUserSwitcherEvent;
|
||||
import com.android.systemui.qs.tiles.UserDetailView;
|
||||
import com.android.systemui.statusbar.phone.SystemUIDialog;
|
||||
import com.android.systemui.telephony.TelephonyListenerManager;
|
||||
import com.android.systemui.user.CreateUserActivity;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
@@ -104,6 +104,7 @@ public class UserSwitcherController implements Dumpable {
|
||||
protected final Handler mHandler;
|
||||
private final ActivityStarter mActivityStarter;
|
||||
private final BroadcastDispatcher mBroadcastDispatcher;
|
||||
private final TelephonyListenerManager mTelephonyListenerManager;
|
||||
private final IActivityTaskManager mActivityTaskManager;
|
||||
|
||||
private ArrayList<UserRecord> mUsers = new ArrayList<>();
|
||||
@@ -126,9 +127,11 @@ public class UserSwitcherController implements Dumpable {
|
||||
public UserSwitcherController(Context context, KeyguardStateController keyguardStateController,
|
||||
@Main Handler handler, ActivityStarter activityStarter,
|
||||
BroadcastDispatcher broadcastDispatcher, UiEventLogger uiEventLogger,
|
||||
TelephonyListenerManager telephonyListenerManager,
|
||||
IActivityTaskManager activityTaskManager) {
|
||||
mContext = context;
|
||||
mBroadcastDispatcher = broadcastDispatcher;
|
||||
mTelephonyListenerManager = telephonyListenerManager;
|
||||
mActivityTaskManager = activityTaskManager;
|
||||
mUiEventLogger = uiEventLogger;
|
||||
mGuestResumeSessionReceiver = new GuestResumeSessionReceiver(mUiEventLogger);
|
||||
@@ -459,18 +462,15 @@ public class UserSwitcherController implements Dumpable {
|
||||
}
|
||||
|
||||
private void listenForCallState() {
|
||||
final TelephonyManager tele =
|
||||
(TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
if (tele != null) {
|
||||
tele.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
|
||||
}
|
||||
mTelephonyListenerManager.addCallStateListener(mPhoneStateListener);
|
||||
}
|
||||
|
||||
private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
|
||||
private final TelephonyCallback.CallStateListener mPhoneStateListener =
|
||||
new TelephonyCallback.CallStateListener() {
|
||||
private int mCallState;
|
||||
|
||||
@Override
|
||||
public void onCallStateChanged(int state, String incomingNumber) {
|
||||
public void onCallStateChanged(int state) {
|
||||
if (mCallState == state) return;
|
||||
if (DEBUG) Log.v(TAG, "Call state changed: " + state);
|
||||
mCallState = state;
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.telephony;
|
||||
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener;
|
||||
import android.telephony.TelephonyCallback.CallStateListener;
|
||||
import android.telephony.TelephonyCallback.ServiceStateListener;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
class TelephonyCallback extends android.telephony.TelephonyCallback
|
||||
implements ActiveDataSubscriptionIdListener, CallStateListener, ServiceStateListener {
|
||||
|
||||
private final List<ActiveDataSubscriptionIdListener> mActiveDataSubscriptionIdListeners =
|
||||
new ArrayList<>();
|
||||
private final List<CallStateListener> mCallStateListeners = new ArrayList<>();
|
||||
private final List<ServiceStateListener> mServiceStateListeners = new ArrayList<>();
|
||||
|
||||
@Inject
|
||||
TelephonyCallback() {
|
||||
}
|
||||
|
||||
boolean hasAnyListeners() {
|
||||
return !mActiveDataSubscriptionIdListeners.isEmpty()
|
||||
|| !mCallStateListeners.isEmpty()
|
||||
|| !mServiceStateListeners.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActiveDataSubscriptionIdChanged(int subId) {
|
||||
mActiveDataSubscriptionIdListeners.forEach(listener -> {
|
||||
listener.onActiveDataSubscriptionIdChanged(subId);
|
||||
});
|
||||
}
|
||||
|
||||
void addActiveDataSubscriptionIdListener(ActiveDataSubscriptionIdListener listener) {
|
||||
mActiveDataSubscriptionIdListeners.add(listener);
|
||||
}
|
||||
|
||||
void removeActiveDataSubscriptionIdListener(ActiveDataSubscriptionIdListener listener) {
|
||||
mActiveDataSubscriptionIdListeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCallStateChanged(int state) {
|
||||
mCallStateListeners.forEach(listener -> {
|
||||
listener.onCallStateChanged(state);
|
||||
});
|
||||
}
|
||||
|
||||
void addCallStateListener(CallStateListener listener) {
|
||||
mCallStateListeners.add(listener);
|
||||
}
|
||||
|
||||
void removeCallStateListener(CallStateListener listener) {
|
||||
mCallStateListeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceStateChanged(@NonNull ServiceState serviceState) {
|
||||
mServiceStateListeners.forEach(listener -> {
|
||||
listener.onServiceStateChanged(serviceState);
|
||||
});
|
||||
}
|
||||
|
||||
void addServiceStateListener(ServiceStateListener listener) {
|
||||
mServiceStateListeners.add(listener);
|
||||
}
|
||||
|
||||
void removeServiceStateListener(ServiceStateListener listener) {
|
||||
mServiceStateListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.telephony;
|
||||
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener;
|
||||
import android.telephony.TelephonyCallback.CallStateListener;
|
||||
import android.telephony.TelephonyCallback.ServiceStateListener;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Wrapper around {@link TelephonyManager#listen(PhoneStateListener, int)}.
|
||||
*
|
||||
* The TelephonyManager complains if too many places in code register a listener. This class
|
||||
* encapsulates SystemUI's usage of this function, reducing it down to a single listener.
|
||||
*
|
||||
* See also
|
||||
* {@link TelephonyManager#registerTelephonyCallback(Executor, android.telephony.TelephonyCallback)}
|
||||
*/
|
||||
@SysUISingleton
|
||||
public class TelephonyListenerManager {
|
||||
private final TelephonyManager mTelephonyManager;
|
||||
private final Executor mExecutor;
|
||||
private final TelephonyCallback mTelephonyCallback;
|
||||
|
||||
private boolean mListening = false;
|
||||
|
||||
@Inject
|
||||
public TelephonyListenerManager(TelephonyManager telephonyManager, @Main Executor executor,
|
||||
TelephonyCallback telephonyCallback) {
|
||||
mTelephonyManager = telephonyManager;
|
||||
mExecutor = executor;
|
||||
mTelephonyCallback = telephonyCallback;
|
||||
}
|
||||
|
||||
/** */
|
||||
public void addActiveDataSubscriptionIdListener(ActiveDataSubscriptionIdListener listener) {
|
||||
mTelephonyCallback.addActiveDataSubscriptionIdListener(listener);
|
||||
updateListening();
|
||||
}
|
||||
|
||||
/** */
|
||||
public void removeActiveDataSubscriptionIdListener(ActiveDataSubscriptionIdListener listener) {
|
||||
mTelephonyCallback.removeActiveDataSubscriptionIdListener(listener);
|
||||
updateListening();
|
||||
}
|
||||
|
||||
/** */
|
||||
public void addCallStateListener(CallStateListener listener) {
|
||||
mTelephonyCallback.addCallStateListener(listener);
|
||||
updateListening();
|
||||
}
|
||||
|
||||
/** */
|
||||
public void removeCallStateListener(CallStateListener listener) {
|
||||
mTelephonyCallback.removeCallStateListener(listener);
|
||||
updateListening();
|
||||
}
|
||||
|
||||
/** */
|
||||
public void addServiceStateListener(ServiceStateListener listener) {
|
||||
mTelephonyCallback.addServiceStateListener(listener);
|
||||
updateListening();
|
||||
}
|
||||
|
||||
/** */
|
||||
public void removeServiceStateListener(ServiceStateListener listener) {
|
||||
mTelephonyCallback.removeServiceStateListener(listener);
|
||||
updateListening();
|
||||
}
|
||||
|
||||
|
||||
private void updateListening() {
|
||||
if (!mListening && mTelephonyCallback.hasAnyListeners()) {
|
||||
mListening = true;
|
||||
mTelephonyManager.registerTelephonyCallback(mExecutor, mTelephonyCallback);
|
||||
} else if (mListening && !mTelephonyCallback.hasAnyListeners()) {
|
||||
mTelephonyManager.unregisterTelephonyCallback(mTelephonyCallback);
|
||||
mListening = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,12 +21,13 @@ import static android.telephony.SubscriptionManager.DATA_ROAMING_DISABLE;
|
||||
import static android.telephony.SubscriptionManager.DATA_ROAMING_ENABLE;
|
||||
import static android.telephony.SubscriptionManager.NAME_SOURCE_CARRIER_ID;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
import static junit.framework.TestCase.assertFalse;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
@@ -40,10 +41,6 @@ import static org.mockito.Mockito.when;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.Looper;
|
||||
import android.os.Process;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
@@ -51,13 +48,14 @@ import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.keyguard.WakefulnessLifecycle;
|
||||
import com.android.systemui.telephony.TelephonyListenerManager;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
import com.android.systemui.util.time.FakeSystemClock;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -73,8 +71,7 @@ import java.util.List;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@TestableLooper.RunWithLooper
|
||||
public class CarrierTextControllerTest extends SysuiTestCase {
|
||||
public class CarrierTextManagerTest extends SysuiTestCase {
|
||||
|
||||
private static final CharSequence SEPARATOR = " \u2014 ";
|
||||
private static final CharSequence INVALID_CARD_TEXT = "Invalid card";
|
||||
@@ -95,7 +92,9 @@ public class CarrierTextControllerTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private WifiManager mWifiManager;
|
||||
@Mock
|
||||
private CarrierTextController.CarrierTextCallback mCarrierTextCallback;
|
||||
private WakefulnessLifecycle mWakefulnessLifecycle;
|
||||
@Mock
|
||||
private CarrierTextManager.CarrierTextCallback mCarrierTextCallback;
|
||||
@Mock
|
||||
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
@Mock
|
||||
@@ -103,24 +102,25 @@ public class CarrierTextControllerTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private TelephonyManager mTelephonyManager;
|
||||
@Mock
|
||||
private TelephonyListenerManager mTelephonyListenerManager;
|
||||
private FakeSystemClock mFakeSystemClock = new FakeSystemClock();
|
||||
private FakeExecutor mMainExecutor = new FakeExecutor(mFakeSystemClock);
|
||||
private FakeExecutor mBgExecutor = new FakeExecutor(mFakeSystemClock);
|
||||
@Mock
|
||||
private SubscriptionManager mSubscriptionManager;
|
||||
private CarrierTextController.CarrierTextCallbackInfo mCarrierTextCallbackInfo;
|
||||
private CarrierTextManager.CarrierTextCallbackInfo mCarrierTextCallbackInfo;
|
||||
|
||||
private CarrierTextController mCarrierTextController;
|
||||
private TestableLooper mTestableLooper;
|
||||
private CarrierTextManager mCarrierTextManager;
|
||||
|
||||
private Void checkMainThread(InvocationOnMock inv) {
|
||||
Looper mainLooper = Dependency.get(Dependency.MAIN_HANDLER).getLooper();
|
||||
if (!mainLooper.isCurrentThread()) {
|
||||
fail("This call should be done from the main thread");
|
||||
}
|
||||
assertThat(mMainExecutor.isExecuting()).isTrue();
|
||||
assertThat(mBgExecutor.isExecuting()).isFalse();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mTestableLooper = TestableLooper.get(this);
|
||||
|
||||
mContext.addMockSystemService(WifiManager.class, mWifiManager);
|
||||
mContext.addMockSystemService(PackageManager.class, mPackageManager);
|
||||
@@ -132,9 +132,6 @@ public class CarrierTextControllerTest extends SysuiTestCase {
|
||||
mContext.getOrCreateTestableResources().addOverride(
|
||||
R.string.airplane_mode, AIRPLANE_MODE_TEXT);
|
||||
mDependency.injectMockDependency(WakefulnessLifecycle.class);
|
||||
mDependency.injectTestDependency(Dependency.MAIN_HANDLER,
|
||||
new Handler(mTestableLooper.getLooper()));
|
||||
mDependency.injectTestDependency(Dependency.BG_LOOPER, mTestableLooper.getLooper());
|
||||
mDependency.injectTestDependency(KeyguardUpdateMonitor.class, mKeyguardUpdateMonitor);
|
||||
|
||||
doAnswer(this::checkMainThread).when(mKeyguardUpdateMonitor)
|
||||
@@ -142,35 +139,30 @@ public class CarrierTextControllerTest extends SysuiTestCase {
|
||||
doAnswer(this::checkMainThread).when(mKeyguardUpdateMonitor)
|
||||
.removeCallback(any(KeyguardUpdateMonitorCallback.class));
|
||||
|
||||
mCarrierTextCallbackInfo = new CarrierTextController.CarrierTextCallbackInfo("",
|
||||
mCarrierTextCallbackInfo = new CarrierTextManager.CarrierTextCallbackInfo("",
|
||||
new CharSequence[]{}, false, new int[]{});
|
||||
when(mTelephonyManager.getSupportedModemCount()).thenReturn(3);
|
||||
when(mTelephonyManager.getActiveModemCount()).thenReturn(3);
|
||||
|
||||
mCarrierTextController = new CarrierTextController(mContext, SEPARATOR, true, true);
|
||||
mCarrierTextManager = new CarrierTextManager.Builder(
|
||||
mContext, mContext.getResources(), mWifiManager,
|
||||
mTelephonyManager, mTelephonyListenerManager, mWakefulnessLifecycle, mMainExecutor,
|
||||
mBgExecutor, mKeyguardUpdateMonitor)
|
||||
.setShowAirplaneMode(true)
|
||||
.setShowMissingSim(true)
|
||||
.build();
|
||||
|
||||
// This should not start listening on any of the real dependencies but will test that
|
||||
// callbacks in mKeyguardUpdateMonitor are done in the mTestableLooper thread
|
||||
mCarrierTextController.setListening(mCarrierTextCallback);
|
||||
mTestableLooper.processAllMessages();
|
||||
mCarrierTextManager.setListening(mCarrierTextCallback);
|
||||
FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testKeyguardUpdateMonitorCalledInMainThread() throws Exception {
|
||||
// This test will run on the main looper (which is not the same as the looper set as MAIN
|
||||
// for CarrierTextCallback. This will fail if calls to mKeyguardUpdateMonitor are not done
|
||||
// through the looper set in the set up
|
||||
HandlerThread thread = new HandlerThread("testThread",
|
||||
Process.THREAD_PRIORITY_BACKGROUND);
|
||||
thread.start();
|
||||
TestableLooper testableLooper = new TestableLooper(thread.getLooper());
|
||||
Handler h = new Handler(testableLooper.getLooper());
|
||||
h.post(() -> {
|
||||
mCarrierTextController.setListening(null);
|
||||
mCarrierTextController.setListening(mCarrierTextCallback);
|
||||
});
|
||||
testableLooper.processAllMessages();
|
||||
mTestableLooper.processAllMessages();
|
||||
thread.quitSafely();
|
||||
mCarrierTextManager.setListening(null);
|
||||
mCarrierTextManager.setListening(mCarrierTextCallback);
|
||||
FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -183,13 +175,13 @@ public class CarrierTextControllerTest extends SysuiTestCase {
|
||||
when(mKeyguardUpdateMonitor.getSimState(0)).thenReturn(TelephonyManager.SIM_STATE_READY);
|
||||
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
|
||||
|
||||
mCarrierTextController.updateCarrierText();
|
||||
mCarrierTextManager.updateCarrierText();
|
||||
|
||||
ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor.forClass(
|
||||
CarrierTextController.CarrierTextCallbackInfo.class);
|
||||
CarrierTextManager.CarrierTextCallbackInfo.class);
|
||||
|
||||
mTestableLooper.processAllMessages();
|
||||
FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
|
||||
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
|
||||
assertEquals(AIRPLANE_MODE_TEXT, captor.getValue().carrierText);
|
||||
}
|
||||
@@ -205,14 +197,14 @@ public class CarrierTextControllerTest extends SysuiTestCase {
|
||||
TelephonyManager.SIM_STATE_CARD_IO_ERROR);
|
||||
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
|
||||
|
||||
mCarrierTextController.mCallback.onSimStateChanged(3, 1,
|
||||
mCarrierTextManager.mCallback.onSimStateChanged(3, 1,
|
||||
TelephonyManager.SIM_STATE_CARD_IO_ERROR);
|
||||
|
||||
ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor.forClass(
|
||||
CarrierTextController.CarrierTextCallbackInfo.class);
|
||||
CarrierTextManager.CarrierTextCallbackInfo.class);
|
||||
|
||||
mTestableLooper.processAllMessages();
|
||||
FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
|
||||
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
|
||||
assertEquals("TEST_CARRIER" + SEPARATOR + INVALID_CARD_TEXT, captor.getValue().carrierText);
|
||||
// There's only one subscription in the list
|
||||
@@ -223,8 +215,8 @@ public class CarrierTextControllerTest extends SysuiTestCase {
|
||||
reset(mCarrierTextCallback);
|
||||
when(mTelephonyManager.getActiveModemCount()).thenReturn(1);
|
||||
// Update carrier text. It should ignore error state of subId 3 in inactive slotId.
|
||||
mCarrierTextController.updateCarrierText();
|
||||
mTestableLooper.processAllMessages();
|
||||
mCarrierTextManager.updateCarrierText();
|
||||
FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
|
||||
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
|
||||
assertEquals("TEST_CARRIER", captor.getValue().carrierText);
|
||||
}
|
||||
@@ -237,9 +229,9 @@ public class CarrierTextControllerTest extends SysuiTestCase {
|
||||
when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
|
||||
TelephonyManager.SIM_STATE_CARD_IO_ERROR);
|
||||
// This should not produce an out of bounds error, even though there are no subscriptions
|
||||
mCarrierTextController.mCallback.onSimStateChanged(0, -3,
|
||||
mCarrierTextManager.mCallback.onSimStateChanged(0, -3,
|
||||
TelephonyManager.SIM_STATE_CARD_IO_ERROR);
|
||||
mCarrierTextController.mCallback.onSimStateChanged(0, 3, TelephonyManager.SIM_STATE_READY);
|
||||
mCarrierTextManager.mCallback.onSimStateChanged(0, 3, TelephonyManager.SIM_STATE_READY);
|
||||
verify(mCarrierTextCallback, never()).updateCarrierInfo(any());
|
||||
}
|
||||
|
||||
@@ -257,23 +249,23 @@ public class CarrierTextControllerTest extends SysuiTestCase {
|
||||
when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
|
||||
TelephonyManager.SIM_STATE_CARD_IO_ERROR);
|
||||
// This should not produce an out of bounds error, even though there are no subscriptions
|
||||
mCarrierTextController.mCallback.onSimStateChanged(0, 1,
|
||||
mCarrierTextManager.mCallback.onSimStateChanged(0, 1,
|
||||
TelephonyManager.SIM_STATE_CARD_IO_ERROR);
|
||||
|
||||
mTestableLooper.processAllMessages();
|
||||
FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
|
||||
verify(mCarrierTextCallback).updateCarrierInfo(
|
||||
any(CarrierTextController.CarrierTextCallbackInfo.class));
|
||||
any(CarrierTextManager.CarrierTextCallbackInfo.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCallback() {
|
||||
reset(mCarrierTextCallback);
|
||||
mCarrierTextController.postToCallback(mCarrierTextCallbackInfo);
|
||||
mTestableLooper.processAllMessages();
|
||||
mCarrierTextManager.postToCallback(mCarrierTextCallbackInfo);
|
||||
FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
|
||||
|
||||
ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor.forClass(
|
||||
CarrierTextController.CarrierTextCallbackInfo.class);
|
||||
CarrierTextManager.CarrierTextCallbackInfo.class);
|
||||
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
|
||||
assertEquals(mCarrierTextCallbackInfo, captor.getValue());
|
||||
}
|
||||
@@ -282,11 +274,11 @@ public class CarrierTextControllerTest extends SysuiTestCase {
|
||||
public void testNullingCallback() {
|
||||
reset(mCarrierTextCallback);
|
||||
|
||||
mCarrierTextController.postToCallback(mCarrierTextCallbackInfo);
|
||||
mCarrierTextController.setListening(null);
|
||||
mCarrierTextManager.postToCallback(mCarrierTextCallbackInfo);
|
||||
mCarrierTextManager.setListening(null);
|
||||
|
||||
// This shouldn't produce NPE
|
||||
mTestableLooper.processAllMessages();
|
||||
FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
|
||||
verify(mCarrierTextCallback).updateCarrierInfo(any());
|
||||
}
|
||||
|
||||
@@ -301,15 +293,15 @@ public class CarrierTextControllerTest extends SysuiTestCase {
|
||||
|
||||
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
|
||||
|
||||
ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor.forClass(
|
||||
CarrierTextController.CarrierTextCallbackInfo.class);
|
||||
CarrierTextManager.CarrierTextCallbackInfo.class);
|
||||
|
||||
mCarrierTextController.updateCarrierText();
|
||||
mTestableLooper.processAllMessages();
|
||||
mCarrierTextManager.updateCarrierText();
|
||||
FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
|
||||
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
|
||||
|
||||
CarrierTextController.CarrierTextCallbackInfo info = captor.getValue();
|
||||
CarrierTextManager.CarrierTextCallbackInfo info = captor.getValue();
|
||||
assertEquals(1, info.listOfCarriers.length);
|
||||
assertEquals(TEST_CARRIER, info.listOfCarriers[0]);
|
||||
assertEquals(1, info.subscriptionIds.length);
|
||||
@@ -326,15 +318,15 @@ public class CarrierTextControllerTest extends SysuiTestCase {
|
||||
|
||||
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
|
||||
|
||||
ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor.forClass(
|
||||
CarrierTextController.CarrierTextCallbackInfo.class);
|
||||
CarrierTextManager.CarrierTextCallbackInfo.class);
|
||||
|
||||
mCarrierTextController.updateCarrierText();
|
||||
mTestableLooper.processAllMessages();
|
||||
mCarrierTextManager.updateCarrierText();
|
||||
FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
|
||||
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
|
||||
|
||||
CarrierTextController.CarrierTextCallbackInfo info = captor.getValue();
|
||||
CarrierTextManager.CarrierTextCallbackInfo info = captor.getValue();
|
||||
assertEquals(1, info.listOfCarriers.length);
|
||||
assertTrue(info.listOfCarriers[0].toString().contains(TEST_CARRIER));
|
||||
assertEquals(1, info.subscriptionIds.length);
|
||||
@@ -346,17 +338,17 @@ public class CarrierTextControllerTest extends SysuiTestCase {
|
||||
List<SubscriptionInfo> list = new ArrayList<>();
|
||||
list.add(TEST_SUBSCRIPTION_NULL);
|
||||
when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
|
||||
TelephonyManager.SIM_STATE_READY);
|
||||
TelephonyManager.SIM_STATE_READY);
|
||||
when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(anyBoolean())).thenReturn(list);
|
||||
|
||||
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
|
||||
|
||||
ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor.forClass(
|
||||
CarrierTextController.CarrierTextCallbackInfo.class);
|
||||
CarrierTextManager.CarrierTextCallbackInfo.class);
|
||||
|
||||
mCarrierTextController.updateCarrierText();
|
||||
mTestableLooper.processAllMessages();
|
||||
mCarrierTextManager.updateCarrierText();
|
||||
FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
|
||||
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
|
||||
|
||||
assertTrue("Carrier text should be empty, instead it's " + captor.getValue().carrierText,
|
||||
@@ -380,12 +372,12 @@ public class CarrierTextControllerTest extends SysuiTestCase {
|
||||
when(ss.getDataRegistrationState()).thenReturn(ServiceState.STATE_IN_SERVICE);
|
||||
mKeyguardUpdateMonitor.mServiceStates.put(TEST_SUBSCRIPTION_NULL.getSubscriptionId(), ss);
|
||||
|
||||
ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor.forClass(
|
||||
CarrierTextController.CarrierTextCallbackInfo.class);
|
||||
CarrierTextManager.CarrierTextCallbackInfo.class);
|
||||
|
||||
mCarrierTextController.updateCarrierText();
|
||||
mTestableLooper.processAllMessages();
|
||||
mCarrierTextManager.updateCarrierText();
|
||||
FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
|
||||
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
|
||||
|
||||
assertFalse("No SIM should be available", captor.getValue().anySimReady);
|
||||
@@ -407,15 +399,15 @@ public class CarrierTextControllerTest extends SysuiTestCase {
|
||||
when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(anyBoolean())).thenReturn(
|
||||
new ArrayList<>());
|
||||
|
||||
ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor.forClass(
|
||||
CarrierTextController.CarrierTextCallbackInfo.class);
|
||||
CarrierTextManager.CarrierTextCallbackInfo.class);
|
||||
|
||||
mCarrierTextController.updateCarrierText();
|
||||
mTestableLooper.processAllMessages();
|
||||
mCarrierTextManager.updateCarrierText();
|
||||
FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
|
||||
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
|
||||
|
||||
CarrierTextController.CarrierTextCallbackInfo info = captor.getValue();
|
||||
CarrierTextManager.CarrierTextCallbackInfo info = captor.getValue();
|
||||
assertEquals(0, info.listOfCarriers.length);
|
||||
assertEquals(0, info.subscriptionIds.length);
|
||||
|
||||
@@ -428,17 +420,17 @@ public class CarrierTextControllerTest extends SysuiTestCase {
|
||||
list.add(TEST_SUBSCRIPTION);
|
||||
list.add(TEST_SUBSCRIPTION);
|
||||
when(mKeyguardUpdateMonitor.getSimState(anyInt())).thenReturn(
|
||||
TelephonyManager.SIM_STATE_READY);
|
||||
TelephonyManager.SIM_STATE_READY);
|
||||
when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(anyBoolean())).thenReturn(list);
|
||||
|
||||
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
|
||||
|
||||
ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor.forClass(
|
||||
CarrierTextController.CarrierTextCallbackInfo.class);
|
||||
CarrierTextManager.CarrierTextCallbackInfo.class);
|
||||
|
||||
mCarrierTextController.updateCarrierText();
|
||||
mTestableLooper.processAllMessages();
|
||||
mCarrierTextManager.updateCarrierText();
|
||||
FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
|
||||
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
|
||||
|
||||
assertEquals(TEST_CARRIER + SEPARATOR + TEST_CARRIER,
|
||||
@@ -458,12 +450,12 @@ public class CarrierTextControllerTest extends SysuiTestCase {
|
||||
|
||||
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
|
||||
|
||||
ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor.forClass(
|
||||
CarrierTextController.CarrierTextCallbackInfo.class);
|
||||
CarrierTextManager.CarrierTextCallbackInfo.class);
|
||||
|
||||
mCarrierTextController.updateCarrierText();
|
||||
mTestableLooper.processAllMessages();
|
||||
mCarrierTextManager.updateCarrierText();
|
||||
FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
|
||||
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
|
||||
|
||||
assertEquals(TEST_CARRIER,
|
||||
@@ -483,12 +475,12 @@ public class CarrierTextControllerTest extends SysuiTestCase {
|
||||
|
||||
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
|
||||
|
||||
ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor.forClass(
|
||||
CarrierTextController.CarrierTextCallbackInfo.class);
|
||||
CarrierTextManager.CarrierTextCallbackInfo.class);
|
||||
|
||||
mCarrierTextController.updateCarrierText();
|
||||
mTestableLooper.processAllMessages();
|
||||
mCarrierTextManager.updateCarrierText();
|
||||
FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
|
||||
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
|
||||
|
||||
assertEquals(TEST_CARRIER,
|
||||
@@ -509,12 +501,12 @@ public class CarrierTextControllerTest extends SysuiTestCase {
|
||||
when(mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(anyBoolean())).thenReturn(list);
|
||||
mKeyguardUpdateMonitor.mServiceStates = new HashMap<>();
|
||||
|
||||
ArgumentCaptor<CarrierTextController.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor<CarrierTextManager.CarrierTextCallbackInfo> captor =
|
||||
ArgumentCaptor.forClass(
|
||||
CarrierTextController.CarrierTextCallbackInfo.class);
|
||||
CarrierTextManager.CarrierTextCallbackInfo.class);
|
||||
|
||||
mCarrierTextController.updateCarrierText();
|
||||
mTestableLooper.processAllMessages();
|
||||
mCarrierTextManager.updateCarrierText();
|
||||
FakeExecutor.exhaustExecutors(mMainExecutor, mBgExecutor);
|
||||
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
|
||||
|
||||
assertEquals(TEST_CARRIER + SEPARATOR + TEST_CARRIER,
|
||||
@@ -72,6 +72,8 @@ public class KeyguardAbsKeyInputViewControllerTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private LatencyTracker mLatencyTracker;
|
||||
private final FalsingCollector mFalsingCollector = new FalsingCollectorFake();
|
||||
@Mock
|
||||
private EmergencyButtonController mEmergencyButtonController;
|
||||
|
||||
private KeyguardAbsKeyInputViewController mKeyguardAbsKeyInputViewController;
|
||||
|
||||
@@ -87,7 +89,8 @@ public class KeyguardAbsKeyInputViewControllerTest extends SysuiTestCase {
|
||||
.thenReturn(mKeyguardMessageArea);
|
||||
mKeyguardAbsKeyInputViewController = new KeyguardAbsKeyInputViewController(mAbsKeyInputView,
|
||||
mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback,
|
||||
mKeyguardMessageAreaControllerFactory, mLatencyTracker, mFalsingCollector) {
|
||||
mKeyguardMessageAreaControllerFactory, mLatencyTracker, mFalsingCollector,
|
||||
mEmergencyButtonController) {
|
||||
@Override
|
||||
void resetState() {
|
||||
}
|
||||
|
||||
@@ -53,12 +53,12 @@ import java.util.concurrent.Executor;
|
||||
@TestableLooper.RunWithLooper
|
||||
public class KeyguardDisplayManagerTest extends SysuiTestCase {
|
||||
|
||||
@Mock
|
||||
private NavigationBarController mNavigationBarController;
|
||||
@Mock
|
||||
private KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory;
|
||||
|
||||
@Mock
|
||||
private DisplayManager mDisplayManager;
|
||||
|
||||
@Mock
|
||||
private KeyguardDisplayManager.KeyguardPresentation mKeyguardPresentation;
|
||||
|
||||
@@ -76,9 +76,8 @@ public class KeyguardDisplayManagerTest extends SysuiTestCase {
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext.addMockSystemService(DisplayManager.class, mDisplayManager);
|
||||
mDependency.injectMockDependency(NavigationBarController.class);
|
||||
mManager = spy(new KeyguardDisplayManager(mContext, mKeyguardStatusViewComponentFactory,
|
||||
mBackgroundExecutor));
|
||||
mManager = spy(new KeyguardDisplayManager(mContext, () -> mNavigationBarController,
|
||||
mKeyguardStatusViewComponentFactory, mBackgroundExecutor));
|
||||
doReturn(mKeyguardPresentation).when(mManager).createPresentation(any());
|
||||
|
||||
mDefaultDisplay = new Display(DisplayManagerGlobal.getInstance(), Display.DEFAULT_DISPLAY,
|
||||
|
||||
@@ -52,6 +52,8 @@ class KeyguardPatternViewControllerTest : SysuiTestCase() {
|
||||
private lateinit var mLatencyTracker: LatencyTracker
|
||||
private var mFalsingCollector: FalsingCollector = FalsingCollectorFake()
|
||||
@Mock
|
||||
private lateinit var mEmergencyButtonController: EmergencyButtonController
|
||||
@Mock
|
||||
private lateinit
|
||||
var mKeyguardMessageAreaControllerFactory: KeyguardMessageAreaController.Factory
|
||||
@Mock
|
||||
@@ -75,7 +77,8 @@ class KeyguardPatternViewControllerTest : SysuiTestCase() {
|
||||
.thenReturn(mKeyguardMessageAreaController)
|
||||
mKeyguardPatternViewController = KeyguardPatternViewController(mKeyguardPatternView,
|
||||
mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback,
|
||||
mLatencyTracker, mFalsingCollector, mKeyguardMessageAreaControllerFactory)
|
||||
mLatencyTracker, mFalsingCollector, mEmergencyButtonController,
|
||||
mKeyguardMessageAreaControllerFactory)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -68,6 +68,8 @@ public class KeyguardPinBasedInputViewControllerTest extends SysuiTestCase {
|
||||
private LatencyTracker mLatencyTracker;
|
||||
@Mock
|
||||
private LiftToActivateListener mLiftToactivateListener;
|
||||
@Mock
|
||||
private EmergencyButtonController mEmergencyButtonController;
|
||||
private FalsingCollector mFalsingCollector = new FalsingCollectorFake();
|
||||
@Mock
|
||||
private SingleTapClassifier mSingleTapClassifier;
|
||||
@@ -97,7 +99,7 @@ public class KeyguardPinBasedInputViewControllerTest extends SysuiTestCase {
|
||||
mKeyguardPinViewController = new KeyguardPinBasedInputViewController(mPinBasedInputView,
|
||||
mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback,
|
||||
mKeyguardMessageAreaControllerFactory, mLatencyTracker, mLiftToactivateListener,
|
||||
mFalsingCollector) {
|
||||
mEmergencyButtonController, mFalsingCollector) {
|
||||
@Override
|
||||
public void onResume(int reason) {
|
||||
super.onResume(reason);
|
||||
|
||||
@@ -94,6 +94,8 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
|
||||
private KeyguardMessageArea mKeyguardMessageArea;
|
||||
@Mock
|
||||
private ConfigurationController mConfigurationController;
|
||||
@Mock
|
||||
private EmergencyButtonController mEmergencyButtonController;
|
||||
|
||||
private KeyguardSecurityContainerController mKeyguardSecurityContainerController;
|
||||
private KeyguardPasswordViewController mKeyguardPasswordViewController;
|
||||
@@ -112,11 +114,11 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase {
|
||||
mKeyguardPasswordViewController = new KeyguardPasswordViewController(
|
||||
(KeyguardPasswordView) mKeyguardPasswordView, mKeyguardUpdateMonitor,
|
||||
SecurityMode.Password, mLockPatternUtils, null,
|
||||
mKeyguardMessageAreaControllerFactory, null, null, null, mock(Resources.class),
|
||||
null);
|
||||
mKeyguardMessageAreaControllerFactory, null, null, mEmergencyButtonController,
|
||||
null, mock(Resources.class), null);
|
||||
|
||||
mKeyguardSecurityContainerController = new KeyguardSecurityContainerController.Factory(
|
||||
mView, mAdminSecondaryLockScreenControllerFactory, mLockPatternUtils,
|
||||
mView, mAdminSecondaryLockScreenControllerFactory, mLockPatternUtils,
|
||||
mKeyguardUpdateMonitor, mKeyguardSecurityModel, mMetricsLogger, mUiEventLogger,
|
||||
mKeyguardStateController, mKeyguardSecurityViewFlipperController,
|
||||
mConfigurationController)
|
||||
|
||||
@@ -59,6 +59,10 @@ public class KeyguardSecurityViewFlipperControllerTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private KeyguardInputViewController.Factory mKeyguardSecurityViewControllerFactory;
|
||||
@Mock
|
||||
private EmergencyButtonController.Factory mEmergencyButtonControllerFactory;
|
||||
@Mock
|
||||
private EmergencyButtonController mEmergencyButtonController;
|
||||
@Mock
|
||||
private KeyguardInputViewController mKeyguardInputViewController;
|
||||
@Mock
|
||||
private KeyguardInputView mInputView;
|
||||
@@ -76,9 +80,12 @@ public class KeyguardSecurityViewFlipperControllerTest extends SysuiTestCase {
|
||||
any(KeyguardSecurityCallback.class)))
|
||||
.thenReturn(mKeyguardInputViewController);
|
||||
when(mView.getWindowInsetsController()).thenReturn(mWindowInsetsController);
|
||||
when(mEmergencyButtonControllerFactory.create(any(EmergencyButton.class)))
|
||||
.thenReturn(mEmergencyButtonController);
|
||||
|
||||
mKeyguardSecurityViewFlipperController = new KeyguardSecurityViewFlipperController(mView,
|
||||
mLayoutInflater, mKeyguardSecurityViewControllerFactory);
|
||||
mLayoutInflater, mKeyguardSecurityViewControllerFactory,
|
||||
mEmergencyButtonControllerFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -88,6 +88,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.FeatureFlags;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
import com.android.systemui.statusbar.phone.KeyguardBypassController;
|
||||
import com.android.systemui.telephony.TelephonyListenerManager;
|
||||
import com.android.systemui.util.RingerModeTracker;
|
||||
|
||||
import org.junit.After;
|
||||
@@ -163,6 +164,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private AuthController mAuthController;
|
||||
@Mock
|
||||
private TelephonyListenerManager mTelephonyListenerManager;
|
||||
@Mock
|
||||
private FeatureFlags mFeatureFlags;
|
||||
@Captor
|
||||
private ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateListenerCaptor;
|
||||
@@ -883,7 +886,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
|
||||
mBroadcastDispatcher, mDumpManager,
|
||||
mRingerModeTracker, mBackgroundExecutor,
|
||||
mStatusBarStateController, mLockPatternUtils,
|
||||
mAuthController, mFeatureFlags);
|
||||
mAuthController, mTelephonyListenerManager, mFeatureFlags);
|
||||
setStrongAuthTracker(KeyguardUpdateMonitorTest.this.mStrongAuthTracker);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,6 @@ import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserManager;
|
||||
import android.service.dreams.IDreamManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.view.IWindowManager;
|
||||
@@ -75,6 +74,7 @@ import com.android.systemui.statusbar.NotificationShadeDepthController;
|
||||
import com.android.systemui.statusbar.NotificationShadeWindowController;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||
import com.android.systemui.telephony.TelephonyListenerManager;
|
||||
import com.android.systemui.util.RingerModeLiveData;
|
||||
import com.android.systemui.util.RingerModeTracker;
|
||||
import com.android.systemui.util.settings.SecureSettings;
|
||||
@@ -106,7 +106,7 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
|
||||
@Mock private LockPatternUtils mLockPatternUtils;
|
||||
@Mock private BroadcastDispatcher mBroadcastDispatcher;
|
||||
@Mock private ConnectivityManager mConnectivityManager;
|
||||
@Mock private TelephonyManager mTelephonyManager;
|
||||
@Mock private TelephonyListenerManager mTelephonyListenerManager;
|
||||
@Mock private ContentResolver mContentResolver;
|
||||
@Mock private Resources mResources;
|
||||
@Mock private ConfigurationController mConfigurationController;
|
||||
@@ -167,7 +167,7 @@ public class GlobalActionsDialogTest extends SysuiTestCase {
|
||||
mLockPatternUtils,
|
||||
mBroadcastDispatcher,
|
||||
mConnectivityManager,
|
||||
mTelephonyManager,
|
||||
mTelephonyListenerManager,
|
||||
mContentResolver,
|
||||
null,
|
||||
mResources,
|
||||
|
||||
@@ -33,7 +33,7 @@ import android.widget.TextView;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.keyguard.CarrierTextController;
|
||||
import com.android.keyguard.CarrierTextManager;
|
||||
import com.android.systemui.plugins.ActivityStarter;
|
||||
import com.android.systemui.statusbar.policy.NetworkController;
|
||||
import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators;
|
||||
@@ -55,7 +55,7 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
|
||||
|
||||
private QSCarrierGroupController mQSCarrierGroupController;
|
||||
private NetworkController.SignalCallback mSignalCallback;
|
||||
private CarrierTextController.CarrierTextCallback mCallback;
|
||||
private CarrierTextManager.CarrierTextCallback mCallback;
|
||||
@Mock
|
||||
private QSCarrierGroup mQSCarrierGroup;
|
||||
@Mock
|
||||
@@ -63,9 +63,9 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
|
||||
@Mock
|
||||
private NetworkController mNetworkController;
|
||||
@Mock
|
||||
private CarrierTextController.Builder mCarrierTextControllerBuilder;
|
||||
private CarrierTextManager.Builder mCarrierTextControllerBuilder;
|
||||
@Mock
|
||||
private CarrierTextController mCarrierTextController;
|
||||
private CarrierTextManager mCarrierTextManager;
|
||||
private TestableLooper mTestableLooper;
|
||||
|
||||
@Before
|
||||
@@ -84,11 +84,11 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
|
||||
.thenReturn(mCarrierTextControllerBuilder);
|
||||
when(mCarrierTextControllerBuilder.setShowMissingSim(anyBoolean()))
|
||||
.thenReturn(mCarrierTextControllerBuilder);
|
||||
when(mCarrierTextControllerBuilder.build()).thenReturn(mCarrierTextController);
|
||||
when(mCarrierTextControllerBuilder.build()).thenReturn(mCarrierTextManager);
|
||||
|
||||
doAnswer(invocation -> mCallback = invocation.getArgument(0))
|
||||
.when(mCarrierTextController)
|
||||
.setListening(any(CarrierTextController.CarrierTextCallback.class));
|
||||
.when(mCarrierTextManager)
|
||||
.setListening(any(CarrierTextManager.CarrierTextCallback.class));
|
||||
|
||||
when(mQSCarrierGroup.getNoSimTextView()).thenReturn(new TextView(mContext));
|
||||
when(mQSCarrierGroup.getCarrier1View()).thenReturn(mock(QSCarrier.class));
|
||||
@@ -114,8 +114,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
|
||||
(Answer<Integer>) invocationOnMock -> invocationOnMock.getArgument(0));
|
||||
|
||||
// listOfCarriers length 1, subscriptionIds length 1, anySims false
|
||||
CarrierTextController.CarrierTextCallbackInfo
|
||||
c1 = new CarrierTextController.CarrierTextCallbackInfo(
|
||||
CarrierTextManager.CarrierTextCallbackInfo
|
||||
c1 = new CarrierTextManager.CarrierTextCallbackInfo(
|
||||
"",
|
||||
new CharSequence[]{""},
|
||||
false,
|
||||
@@ -123,8 +123,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
|
||||
mCallback.updateCarrierInfo(c1);
|
||||
|
||||
// listOfCarriers length 1, subscriptionIds length 1, anySims true
|
||||
CarrierTextController.CarrierTextCallbackInfo
|
||||
c2 = new CarrierTextController.CarrierTextCallbackInfo(
|
||||
CarrierTextManager.CarrierTextCallbackInfo
|
||||
c2 = new CarrierTextManager.CarrierTextCallbackInfo(
|
||||
"",
|
||||
new CharSequence[]{""},
|
||||
true,
|
||||
@@ -132,8 +132,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
|
||||
mCallback.updateCarrierInfo(c2);
|
||||
|
||||
// listOfCarriers length 2, subscriptionIds length 2, anySims false
|
||||
CarrierTextController.CarrierTextCallbackInfo
|
||||
c3 = new CarrierTextController.CarrierTextCallbackInfo(
|
||||
CarrierTextManager.CarrierTextCallbackInfo
|
||||
c3 = new CarrierTextManager.CarrierTextCallbackInfo(
|
||||
"",
|
||||
new CharSequence[]{"", ""},
|
||||
false,
|
||||
@@ -141,8 +141,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
|
||||
mCallback.updateCarrierInfo(c3);
|
||||
|
||||
// listOfCarriers length 2, subscriptionIds length 2, anySims true
|
||||
CarrierTextController.CarrierTextCallbackInfo
|
||||
c4 = new CarrierTextController.CarrierTextCallbackInfo(
|
||||
CarrierTextManager.CarrierTextCallbackInfo
|
||||
c4 = new CarrierTextManager.CarrierTextCallbackInfo(
|
||||
"",
|
||||
new CharSequence[]{"", ""},
|
||||
true,
|
||||
@@ -160,8 +160,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
|
||||
(Answer<Integer>) invocationOnMock -> invocationOnMock.getArgument(0));
|
||||
|
||||
// listOfCarriers length 2, subscriptionIds length 1, anySims false
|
||||
CarrierTextController.CarrierTextCallbackInfo
|
||||
c1 = new CarrierTextController.CarrierTextCallbackInfo(
|
||||
CarrierTextManager.CarrierTextCallbackInfo
|
||||
c1 = new CarrierTextManager.CarrierTextCallbackInfo(
|
||||
"",
|
||||
new CharSequence[]{"", ""},
|
||||
false,
|
||||
@@ -169,8 +169,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
|
||||
mCallback.updateCarrierInfo(c1);
|
||||
|
||||
// listOfCarriers length 2, subscriptionIds length 1, anySims true
|
||||
CarrierTextController.CarrierTextCallbackInfo
|
||||
c2 = new CarrierTextController.CarrierTextCallbackInfo(
|
||||
CarrierTextManager.CarrierTextCallbackInfo
|
||||
c2 = new CarrierTextManager.CarrierTextCallbackInfo(
|
||||
"",
|
||||
new CharSequence[]{"", ""},
|
||||
true,
|
||||
@@ -178,8 +178,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
|
||||
mCallback.updateCarrierInfo(c2);
|
||||
|
||||
// listOfCarriers length 1, subscriptionIds length 2, anySims false
|
||||
CarrierTextController.CarrierTextCallbackInfo
|
||||
c3 = new CarrierTextController.CarrierTextCallbackInfo(
|
||||
CarrierTextManager.CarrierTextCallbackInfo
|
||||
c3 = new CarrierTextManager.CarrierTextCallbackInfo(
|
||||
"",
|
||||
new CharSequence[]{""},
|
||||
false,
|
||||
@@ -187,8 +187,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
|
||||
mCallback.updateCarrierInfo(c3);
|
||||
|
||||
// listOfCarriers length 1, subscriptionIds length 2, anySims true
|
||||
CarrierTextController.CarrierTextCallbackInfo
|
||||
c4 = new CarrierTextController.CarrierTextCallbackInfo(
|
||||
CarrierTextManager.CarrierTextCallbackInfo
|
||||
c4 = new CarrierTextManager.CarrierTextCallbackInfo(
|
||||
"",
|
||||
new CharSequence[]{""},
|
||||
true,
|
||||
@@ -204,8 +204,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
|
||||
when(spiedCarrierGroupController.getSlotIndex(anyInt())).thenReturn(
|
||||
SubscriptionManager.INVALID_SIM_SLOT_INDEX);
|
||||
|
||||
CarrierTextController.CarrierTextCallbackInfo
|
||||
c4 = new CarrierTextController.CarrierTextCallbackInfo(
|
||||
CarrierTextManager.CarrierTextCallbackInfo
|
||||
c4 = new CarrierTextManager.CarrierTextCallbackInfo(
|
||||
"",
|
||||
new CharSequence[]{"", ""},
|
||||
true,
|
||||
@@ -225,8 +225,8 @@ public class QSCarrierGroupControllerTest extends LeakCheckedTest {
|
||||
|
||||
@Test
|
||||
public void testNoEmptyVisibleView_airplaneMode() {
|
||||
CarrierTextController.CarrierTextCallbackInfo
|
||||
info = new CarrierTextController.CarrierTextCallbackInfo(
|
||||
CarrierTextManager.CarrierTextCallbackInfo
|
||||
info = new CarrierTextManager.CarrierTextCallbackInfo(
|
||||
"",
|
||||
new CharSequence[]{""},
|
||||
true,
|
||||
|
||||
@@ -66,6 +66,7 @@ import com.android.keyguard.KeyguardStatusView;
|
||||
import com.android.keyguard.KeyguardStatusViewController;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.dagger.KeyguardQsUserSwitchComponent;
|
||||
import com.android.keyguard.dagger.KeyguardStatusBarViewComponent;
|
||||
import com.android.keyguard.dagger.KeyguardStatusViewComponent;
|
||||
import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
|
||||
import com.android.systemui.R;
|
||||
@@ -206,10 +207,16 @@ public class NotificationPanelViewTest extends SysuiTestCase {
|
||||
@Mock
|
||||
private KeyguardStatusViewComponent mKeyguardStatusViewComponent;
|
||||
@Mock
|
||||
private KeyguardStatusBarViewComponent.Factory mKeyguardStatusBarViewComponentFactory;
|
||||
@Mock
|
||||
private KeyguardStatusBarViewComponent mKeyguardStatusBarViewComponent;
|
||||
@Mock
|
||||
private KeyguardClockSwitchController mKeyguardClockSwitchController;
|
||||
@Mock
|
||||
private KeyguardStatusViewController mKeyguardStatusViewController;
|
||||
@Mock
|
||||
private KeyguardStatusBarViewController mKeyguardStatusBarViewController;
|
||||
@Mock
|
||||
private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
|
||||
@Mock
|
||||
private AuthController mAuthController;
|
||||
@@ -296,6 +303,10 @@ public class NotificationPanelViewTest extends SysuiTestCase {
|
||||
.thenReturn(mKeyguardClockSwitchController);
|
||||
when(mKeyguardStatusViewComponent.getKeyguardStatusViewController())
|
||||
.thenReturn(mKeyguardStatusViewController);
|
||||
when(mKeyguardStatusBarViewComponentFactory.build(any()))
|
||||
.thenReturn(mKeyguardStatusBarViewComponent);
|
||||
when(mKeyguardStatusBarViewComponent.getKeyguardStatusBarViewController())
|
||||
.thenReturn(mKeyguardStatusBarViewController);
|
||||
|
||||
mNotificationPanelViewController = new NotificationPanelViewController(mView,
|
||||
mResources,
|
||||
@@ -314,6 +325,7 @@ public class NotificationPanelViewTest extends SysuiTestCase {
|
||||
mKeyguardStatusViewComponentFactory,
|
||||
mKeyguardQsUserSwitchComponentFactory,
|
||||
mKeyguardUserSwitcherComponentFactory,
|
||||
mKeyguardStatusBarViewComponentFactory,
|
||||
mQSDetailDisplayer,
|
||||
mGroupManager,
|
||||
mNotificationAreaController,
|
||||
|
||||
@@ -76,6 +76,7 @@ import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceP
|
||||
import com.android.systemui.statusbar.policy.NetworkController.IconState;
|
||||
import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators;
|
||||
import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
|
||||
import com.android.systemui.telephony.TelephonyListenerManager;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@@ -113,6 +114,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
|
||||
protected NetworkScoreManager mMockNsm;
|
||||
protected SubscriptionManager mMockSm;
|
||||
protected TelephonyManager mMockTm;
|
||||
protected TelephonyListenerManager mTelephonyListenerManager;
|
||||
protected BroadcastDispatcher mMockBd;
|
||||
protected Config mConfig;
|
||||
protected CallbackHandler mCallbackHandler;
|
||||
@@ -164,6 +166,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
|
||||
mDemoModeController = mock(DemoModeController.class);
|
||||
mMockWm = mock(WifiManager.class);
|
||||
mMockTm = mock(TelephonyManager.class);
|
||||
mTelephonyListenerManager = mock(TelephonyListenerManager.class);
|
||||
mMockSm = mock(SubscriptionManager.class);
|
||||
mMockCm = mock(ConnectivityManager.class);
|
||||
mMockBd = mock(BroadcastDispatcher.class);
|
||||
@@ -213,6 +216,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
|
||||
mNetworkController = new NetworkControllerImpl(mContext,
|
||||
mMockCm,
|
||||
mMockTm,
|
||||
mTelephonyListenerManager,
|
||||
mMockWm,
|
||||
mMockNsm,
|
||||
mMockSm,
|
||||
@@ -285,7 +289,8 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
|
||||
protected NetworkControllerImpl setUpNoMobileData() {
|
||||
when(mMockTm.isDataCapable()).thenReturn(false);
|
||||
NetworkControllerImpl networkControllerNoMobile =
|
||||
new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockNsm, mMockSm,
|
||||
new NetworkControllerImpl(mContext, mMockCm, mMockTm, mTelephonyListenerManager,
|
||||
mMockWm, mMockNsm, mMockSm,
|
||||
mConfig, TestableLooper.get(this).getLooper(), mCallbackHandler,
|
||||
mock(AccessPointControllerImpl.class),
|
||||
mock(DataUsageController.class), mMockSubDefaults,
|
||||
|
||||
@@ -106,7 +106,8 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
|
||||
public void test4gDataIcon() {
|
||||
// Switch to showing 4g icon and re-initialize the NetworkController.
|
||||
mConfig.show4gForLte = true;
|
||||
mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm,
|
||||
mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm,
|
||||
mTelephonyListenerManager, mMockWm,
|
||||
mMockNsm, mMockSm, mConfig, Looper.getMainLooper(), mCallbackHandler,
|
||||
mock(AccessPointControllerImpl.class),
|
||||
mock(DataUsageController.class), mMockSubDefaults,
|
||||
|
||||
@@ -61,8 +61,9 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
|
||||
// Turn off mobile network support.
|
||||
when(mMockTm.isDataCapable()).thenReturn(false);
|
||||
// Create a new NetworkController as this is currently handled in constructor.
|
||||
mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm,
|
||||
mMockNsm, mMockSm, mConfig, Looper.getMainLooper(), mCallbackHandler,
|
||||
mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm,
|
||||
mTelephonyListenerManager, mMockWm, mMockNsm, mMockSm, mConfig,
|
||||
Looper.getMainLooper(), mCallbackHandler,
|
||||
mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
|
||||
mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
|
||||
mDemoModeController);
|
||||
@@ -80,8 +81,9 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
|
||||
when(mMockTm.getServiceState()).thenReturn(mServiceState);
|
||||
when(mMockSm.getCompleteActiveSubscriptionInfoList()).thenReturn(Collections.emptyList());
|
||||
|
||||
mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm,
|
||||
mMockNsm, mMockSm, mConfig, Looper.getMainLooper(), mCallbackHandler,
|
||||
mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm,
|
||||
mTelephonyListenerManager, mMockWm, mMockNsm, mMockSm, mConfig,
|
||||
Looper.getMainLooper(), mCallbackHandler,
|
||||
mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
|
||||
mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
|
||||
mDemoModeController);
|
||||
@@ -147,8 +149,9 @@ public class NetworkControllerSignalTest extends NetworkControllerBaseTest {
|
||||
// Turn off mobile network support.
|
||||
when(mMockTm.isDataCapable()).thenReturn(false);
|
||||
// Create a new NetworkController as this is currently handled in constructor.
|
||||
mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm,
|
||||
mMockNsm, mMockSm, mConfig, Looper.getMainLooper(), mCallbackHandler,
|
||||
mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm,
|
||||
mTelephonyListenerManager, mMockWm, mMockNsm, mMockSm, mConfig,
|
||||
Looper.getMainLooper(), mCallbackHandler,
|
||||
mock(AccessPointControllerImpl.class), mock(DataUsageController.class),
|
||||
mMockSubDefaults, mock(DeviceProvisionedController.class), mMockBd,
|
||||
mDemoModeController);
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.telephony;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener;
|
||||
import android.telephony.TelephonyCallback.CallStateListener;
|
||||
import android.telephony.TelephonyCallback.ServiceStateListener;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class TelephonyCallbackTest extends SysuiTestCase {
|
||||
|
||||
private TelephonyCallback mTelephonyCallback = new TelephonyCallback();
|
||||
|
||||
@Test
|
||||
public void testAddListener_ActiveDataSubscriptionIdListener() {
|
||||
assertThat(mTelephonyCallback.hasAnyListeners()).isFalse();
|
||||
mTelephonyCallback.addActiveDataSubscriptionIdListener(subId -> {});
|
||||
assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
|
||||
mTelephonyCallback.addActiveDataSubscriptionIdListener(subId -> {});
|
||||
assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddListener_CallStateListener() {
|
||||
assertThat(mTelephonyCallback.hasAnyListeners()).isFalse();
|
||||
mTelephonyCallback.addCallStateListener(state -> {});
|
||||
assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
|
||||
mTelephonyCallback.addCallStateListener(state -> {});
|
||||
assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddListener_ServiceStateListener() {
|
||||
assertThat(mTelephonyCallback.hasAnyListeners()).isFalse();
|
||||
mTelephonyCallback.addServiceStateListener(serviceState -> {});
|
||||
assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
|
||||
mTelephonyCallback.addServiceStateListener(serviceState -> {});
|
||||
assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveListener_ActiveDataSubscriptionIdListener() {
|
||||
ActiveDataSubscriptionIdListener listener = subId -> {};
|
||||
mTelephonyCallback.addActiveDataSubscriptionIdListener(listener);
|
||||
mTelephonyCallback.addActiveDataSubscriptionIdListener(listener);
|
||||
assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
|
||||
mTelephonyCallback.removeActiveDataSubscriptionIdListener(listener);
|
||||
assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
|
||||
mTelephonyCallback.removeActiveDataSubscriptionIdListener(listener);
|
||||
assertThat(mTelephonyCallback.hasAnyListeners()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveListener_CallStateListener() {
|
||||
CallStateListener listener = state -> {};
|
||||
mTelephonyCallback.addCallStateListener(listener);
|
||||
mTelephonyCallback.addCallStateListener(listener);
|
||||
assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
|
||||
mTelephonyCallback.removeCallStateListener(listener);
|
||||
assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
|
||||
mTelephonyCallback.removeCallStateListener(listener);
|
||||
assertThat(mTelephonyCallback.hasAnyListeners()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveListener_ServiceStateListener() {
|
||||
ServiceStateListener listener = serviceState -> {};
|
||||
mTelephonyCallback.addServiceStateListener(listener);
|
||||
mTelephonyCallback.addServiceStateListener(listener);
|
||||
assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
|
||||
mTelephonyCallback.removeServiceStateListener(listener);
|
||||
assertThat(mTelephonyCallback.hasAnyListeners()).isTrue();
|
||||
mTelephonyCallback.removeServiceStateListener(listener);
|
||||
assertThat(mTelephonyCallback.hasAnyListeners()).isFalse();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.telephony;
|
||||
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener;
|
||||
import android.telephony.TelephonyCallback.CallStateListener;
|
||||
import android.telephony.TelephonyCallback.ServiceStateListener;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
import com.android.systemui.util.time.FakeSystemClock;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class TelephonyListenerManagerTest extends SysuiTestCase {
|
||||
|
||||
@Mock
|
||||
private TelephonyManager mTelephonyManager;
|
||||
private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
|
||||
@Mock
|
||||
private TelephonyCallback mTelephonyCallback;
|
||||
|
||||
TelephonyListenerManager mTelephonyListenerManager;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mTelephonyListenerManager = new TelephonyListenerManager(
|
||||
mTelephonyManager, mExecutor, mTelephonyCallback);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddListenerRegisters_ActiveDataSubscriptionIdListener() {
|
||||
when(mTelephonyCallback.hasAnyListeners()).thenReturn(true);
|
||||
mTelephonyListenerManager.addActiveDataSubscriptionIdListener(subId -> {});
|
||||
mTelephonyListenerManager.addActiveDataSubscriptionIdListener(subId -> {});
|
||||
mTelephonyListenerManager.addActiveDataSubscriptionIdListener(subId -> {});
|
||||
mTelephonyListenerManager.addActiveDataSubscriptionIdListener(subId -> {});
|
||||
|
||||
verify(mTelephonyManager, times(1))
|
||||
.registerTelephonyCallback(mExecutor, mTelephonyCallback);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddListenerRegisters_CallStateListener() {
|
||||
when(mTelephonyCallback.hasAnyListeners()).thenReturn(true);
|
||||
mTelephonyListenerManager.addCallStateListener(state -> {});
|
||||
mTelephonyListenerManager.addCallStateListener(state -> {});
|
||||
mTelephonyListenerManager.addCallStateListener(state -> {});
|
||||
mTelephonyListenerManager.addCallStateListener(state -> {});
|
||||
|
||||
verify(mTelephonyManager, times(1))
|
||||
.registerTelephonyCallback(mExecutor, mTelephonyCallback);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddListenerRegisters_ServiceStateListener() {
|
||||
when(mTelephonyCallback.hasAnyListeners()).thenReturn(true);
|
||||
mTelephonyListenerManager.addServiceStateListener(serviceState -> {});
|
||||
mTelephonyListenerManager.addServiceStateListener(serviceState -> {});
|
||||
mTelephonyListenerManager.addServiceStateListener(serviceState -> {});
|
||||
mTelephonyListenerManager.addServiceStateListener(serviceState -> {});
|
||||
|
||||
verify(mTelephonyManager, times(1))
|
||||
.registerTelephonyCallback(mExecutor, mTelephonyCallback);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddListenerRegisters_mixed() {
|
||||
when(mTelephonyCallback.hasAnyListeners()).thenReturn(true);
|
||||
mTelephonyListenerManager.addActiveDataSubscriptionIdListener(subId -> {});
|
||||
mTelephonyListenerManager.addCallStateListener(state -> {});
|
||||
mTelephonyListenerManager.addServiceStateListener(serviceState -> {});
|
||||
mTelephonyListenerManager.addActiveDataSubscriptionIdListener(subId -> {});
|
||||
mTelephonyListenerManager.addCallStateListener(state -> {});
|
||||
mTelephonyListenerManager.addServiceStateListener(serviceState -> {});
|
||||
|
||||
verify(mTelephonyManager, times(1))
|
||||
.registerTelephonyCallback(mExecutor, mTelephonyCallback);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveListenerUnregisters_ActiveDataSubscriptionIdListener() {
|
||||
when(mTelephonyCallback.hasAnyListeners()).thenReturn(true);
|
||||
ActiveDataSubscriptionIdListener mListener = subId -> { };
|
||||
|
||||
// Need to add one to actually register
|
||||
mTelephonyListenerManager.addActiveDataSubscriptionIdListener(mListener);
|
||||
verify(mTelephonyManager, times(1))
|
||||
.registerTelephonyCallback(mExecutor, mTelephonyCallback);
|
||||
reset(mTelephonyManager);
|
||||
|
||||
when(mTelephonyCallback.hasAnyListeners()).thenReturn(false);
|
||||
mTelephonyListenerManager.removeActiveDataSubscriptionIdListener(mListener);
|
||||
mTelephonyListenerManager.removeActiveDataSubscriptionIdListener(mListener);
|
||||
mTelephonyListenerManager.removeActiveDataSubscriptionIdListener(mListener);
|
||||
mTelephonyListenerManager.removeActiveDataSubscriptionIdListener(mListener);
|
||||
verify(mTelephonyManager, times(1))
|
||||
.unregisterTelephonyCallback(mTelephonyCallback);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveListenerUnregisters_CallStateListener() {
|
||||
when(mTelephonyCallback.hasAnyListeners()).thenReturn(true);
|
||||
CallStateListener mListener = state -> { };
|
||||
|
||||
// Need to add one to actually register
|
||||
mTelephonyListenerManager.addCallStateListener(mListener);
|
||||
verify(mTelephonyManager, times(1))
|
||||
.registerTelephonyCallback(mExecutor, mTelephonyCallback);
|
||||
reset(mTelephonyManager);
|
||||
|
||||
when(mTelephonyCallback.hasAnyListeners()).thenReturn(false);
|
||||
mTelephonyListenerManager.removeCallStateListener(mListener);
|
||||
mTelephonyListenerManager.removeCallStateListener(mListener);
|
||||
mTelephonyListenerManager.removeCallStateListener(mListener);
|
||||
mTelephonyListenerManager.removeCallStateListener(mListener);
|
||||
verify(mTelephonyManager, times(1))
|
||||
.unregisterTelephonyCallback(mTelephonyCallback);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveListenerUnregisters_ServiceStateListener() {
|
||||
when(mTelephonyCallback.hasAnyListeners()).thenReturn(true);
|
||||
ServiceStateListener mListener = serviceState -> { };
|
||||
|
||||
// Need to add one to actually register
|
||||
mTelephonyListenerManager.addServiceStateListener(mListener);
|
||||
verify(mTelephonyManager, times(1))
|
||||
.registerTelephonyCallback(mExecutor, mTelephonyCallback);
|
||||
reset(mTelephonyManager);
|
||||
|
||||
when(mTelephonyCallback.hasAnyListeners()).thenReturn(false);
|
||||
mTelephonyListenerManager.removeServiceStateListener(mListener);
|
||||
mTelephonyListenerManager.removeServiceStateListener(mListener);
|
||||
mTelephonyListenerManager.removeServiceStateListener(mListener);
|
||||
mTelephonyListenerManager.removeServiceStateListener(mListener);
|
||||
verify(mTelephonyManager, times(1))
|
||||
.unregisterTelephonyCallback(mTelephonyCallback);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveListenerUnregisters_mixed() {
|
||||
when(mTelephonyCallback.hasAnyListeners()).thenReturn(true);
|
||||
ActiveDataSubscriptionIdListener mListenerA = subId -> { };
|
||||
ServiceStateListener mListenerB = serviceState -> { };
|
||||
CallStateListener mListenerC = state -> { };
|
||||
|
||||
// Need to add one to actually register
|
||||
mTelephonyListenerManager.addActiveDataSubscriptionIdListener(mListenerA);
|
||||
verify(mTelephonyManager, times(1))
|
||||
.registerTelephonyCallback(mExecutor, mTelephonyCallback);
|
||||
reset(mTelephonyManager);
|
||||
|
||||
when(mTelephonyCallback.hasAnyListeners()).thenReturn(false);
|
||||
mTelephonyListenerManager.removeActiveDataSubscriptionIdListener(mListenerA);
|
||||
mTelephonyListenerManager.removeServiceStateListener(mListenerB);
|
||||
mTelephonyListenerManager.removeCallStateListener(mListenerC);
|
||||
mTelephonyListenerManager.removeActiveDataSubscriptionIdListener(mListenerA);
|
||||
mTelephonyListenerManager.removeServiceStateListener(mListenerB);
|
||||
mTelephonyListenerManager.removeCallStateListener(mListenerC);
|
||||
verify(mTelephonyManager, times(1))
|
||||
.unregisterTelephonyCallback(mTelephonyCallback);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddListener_noDoubleRegister() {
|
||||
when(mTelephonyCallback.hasAnyListeners()).thenReturn(true);
|
||||
mTelephonyListenerManager.addActiveDataSubscriptionIdListener(subId -> {});
|
||||
verify(mTelephonyManager, times(1))
|
||||
.registerTelephonyCallback(mExecutor, mTelephonyCallback);
|
||||
|
||||
reset(mTelephonyManager);
|
||||
|
||||
// A second call to add doesn't register another listener.
|
||||
mTelephonyListenerManager.addActiveDataSubscriptionIdListener(subId -> {});
|
||||
verify(mTelephonyManager, never()).registerTelephonyCallback(mExecutor, mTelephonyCallback);
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@ public class FakeExecutor implements DelayableExecutor {
|
||||
private final FakeSystemClock mClock;
|
||||
private PriorityQueue<QueuedRunnable> mQueuedRunnables = new PriorityQueue<>();
|
||||
private boolean mIgnoreClockUpdates;
|
||||
private boolean mExecuting;
|
||||
|
||||
/**
|
||||
* Initializes a fake executor.
|
||||
@@ -56,7 +57,9 @@ public class FakeExecutor implements DelayableExecutor {
|
||||
*/
|
||||
public boolean runNextReady() {
|
||||
if (!mQueuedRunnables.isEmpty() && mQueuedRunnables.peek().mWhen <= mClock.uptimeMillis()) {
|
||||
mExecuting = true;
|
||||
mQueuedRunnables.poll().mRunnable.run();
|
||||
mExecuting = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -162,6 +165,10 @@ public class FakeExecutor implements DelayableExecutor {
|
||||
executeDelayed(command, 0);
|
||||
}
|
||||
|
||||
public boolean isExecuting() {
|
||||
return mExecuting;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run all Executors in a loop until they all report they have no ready work to do.
|
||||
*
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.systemui.util.concurrency;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
@@ -319,6 +321,18 @@ public class FakeExecutorTest extends SysuiTestCase {
|
||||
assertEquals(1, runnable.mRunCount);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsExecuting() {
|
||||
FakeSystemClock clock = new FakeSystemClock();
|
||||
FakeExecutor fakeExecutor = new FakeExecutor(clock);
|
||||
|
||||
Runnable runnable = () -> assertThat(fakeExecutor.isExecuting()).isTrue();
|
||||
|
||||
assertThat(fakeExecutor.isExecuting()).isFalse();
|
||||
fakeExecutor.execute(runnable);
|
||||
assertThat(fakeExecutor.isExecuting()).isFalse();
|
||||
}
|
||||
|
||||
private static class RunnableImpl implements Runnable {
|
||||
int mRunCount;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user