Merge changes from topic "b179775696-depenency-get-keyguard" into sc-dev

* changes:
  Remove final calls to Dependency.get from keyguard.
  Remove Dependency.get from KeyguardStatusView.
  Add injection to ClockProvider.
  Remove Dependency.get from KeyguardSliceTextView.
  Add Controller for Emergency Button.
  Add ViewController to CarrierText.
This commit is contained in:
TreeHugger Robot
2021-02-16 19:45:15 +00:00
committed by Android (Google) Code Review
40 changed files with 1462 additions and 1070 deletions

View File

@@ -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;

View File

@@ -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,61 @@
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.res.Resources;
import android.net.ConnectivityManager;
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";
public class CarrierTextController extends ViewController<CarrierText> {
private final CarrierTextManager mCarrierTextManager;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
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() {
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 = ConnectivityManager.from(mContext).isNetworkSupported(
ConnectivityManager.TYPE_MOBILE);
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);
}
}

View File

@@ -0,0 +1,720 @@
/*
* 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 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.res.Resources;
import android.net.ConnectivityManager;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
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 java.util.List;
import java.util.Objects;
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 Handler mMainHandler;
private final Handler mBgHandler;
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 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 PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
@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,
ConnectivityManager connectivityManager, TelephonyManager telephonyManager,
WakefulnessLifecycle wakefulnessLifecycle, @Main Handler mainHandler,
@Background Handler bgHandler, KeyguardUpdateMonitor keyguardUpdateMonitor) {
mContext = context;
mIsEmergencyCallCapable = telephonyManager.isVoiceCapable();
mShowAirplaneMode = showAirplaneMode;
mShowMissingSim = showMissingSim;
mWifiManager = wifiManager;
mTelephonyManager = telephonyManager;
mSeparator = separator;
mWakefulnessLifecycle = wakefulnessLifecycle;
mSimSlotsNumber = getTelephonyManager().getSupportedModemCount();
mSimErrorState = new boolean[mSimSlotsNumber];
mMainHandler = mainHandler;
mBgHandler = bgHandler;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mBgHandler.post(() -> {
boolean supported = connectivityManager.isNetworkSupported(
ConnectivityManager.TYPE_MOBILE);
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) {
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 != 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) {
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;
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 ConnectivityManager mConnectivityManager;
private final TelephonyManager mTelephonyManager;
private final WakefulnessLifecycle mWakefulnessLifecycle;
private final Handler mMainHandler;
private final Handler mBgHandler;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private boolean mShowAirplaneMode;
private boolean mShowMissingSim;
@Inject
public Builder(Context context, @Main Resources resources,
@Nullable WifiManager wifiManager, ConnectivityManager connectivityManager,
TelephonyManager telephonyManager, WakefulnessLifecycle wakefulnessLifecycle,
@Main Handler mainHandler, @Background Handler bgHandler,
KeyguardUpdateMonitor keyguardUpdateMonitor) {
mContext = context;
mSeparator = resources.getString(
com.android.internal.R.string.kg_text_message_separator);
mWifiManager = wifiManager;
mConnectivityManager = connectivityManager;
mTelephonyManager = telephonyManager;
mWakefulnessLifecycle = wakefulnessLifecycle;
mMainHandler = mainHandler;
mBgHandler = bgHandler;
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,
mConnectivityManager, mTelephonyManager, mWakefulnessLifecycle, mMainHandler,
mBgHandler, 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() {};
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
@@ -41,6 +41,7 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final LockPatternUtils mLockPatternUtils;
private final LatencyTracker mLatencyTracker;
private final EmergencyButtonController mEmergencyButtonController;
private CountDownTimer mCountdownTimer;
protected KeyguardMessageAreaController mMessageAreaController;
private boolean mDismissing;
@@ -70,11 +71,12 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey
LockPatternUtils lockPatternUtils,
KeyguardSecurityCallback keyguardSecurityCallback,
KeyguardMessageAreaController.Factory messageAreaControllerFactory,
LatencyTracker latencyTracker) {
super(view, securityMode, keyguardSecurityCallback);
LatencyTracker latencyTracker, EmergencyButtonController emergencyButtonController) {
super(view, securityMode, keyguardSecurityCallback, emergencyButtonController);
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mLockPatternUtils = lockPatternUtils;
mLatencyTracker = latencyTracker;
mEmergencyButtonController = emergencyButtonController;
KeyguardMessageArea kma = KeyguardMessageArea.findSecurityMessageDisplay(mView);
mMessageAreaController = messageAreaControllerFactory.create(kma);
}
@@ -83,6 +85,7 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey
@Override
public void onInit() {
super.onInit();
mMessageAreaController.init();
}
@@ -91,10 +94,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

View File

@@ -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;

View File

@@ -41,6 +41,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;
@@ -68,11 +69,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
@@ -154,8 +162,9 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
private final InputMethodManager mInputMethodManager;
private final DelayableExecutor mMainExecutor;
private final Resources mResources;
private LiftToActivateListener mLiftToActivateListener;
private TelephonyManager mTelephonyManager;
private final LiftToActivateListener mLiftToActivateListener;
private final TelephonyManager mTelephonyManager;
private final EmergencyButtonController.Factory mEmergencyButtonControllerFactory;
private final FalsingCollector mFalsingCollector;
@Inject
@@ -165,7 +174,9 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
KeyguardMessageAreaController.Factory messageAreaControllerFactory,
InputMethodManager inputMethodManager, @Main DelayableExecutor mainExecutor,
@Main Resources resources, LiftToActivateListener liftToActivateListener,
TelephonyManager telephonyManager, FalsingCollector falsingCollector) {
TelephonyManager telephonyManager,
EmergencyButtonController.Factory emergencyButtonControllerFactory,
FalsingCollector falsingCollector) {
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mLockPatternUtils = lockPatternUtils;
mLatencyTracker = latencyTracker;
@@ -175,36 +186,47 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
mResources = resources;
mLiftToActivateListener = liftToActivateListener;
mTelephonyManager = telephonyManager;
mEmergencyButtonControllerFactory = emergencyButtonControllerFactory;
mFalsingCollector = falsingCollector;
}
/** 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, mMessageAreaControllerFactory);
keyguardSecurityCallback, mLatencyTracker,
emergencyButtonController,
mMessageAreaControllerFactory);
} else if (keyguardInputView instanceof KeyguardPasswordView) {
return new KeyguardPasswordViewController((KeyguardPasswordView) keyguardInputView,
mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
mInputMethodManager, mMainExecutor, mResources);
mInputMethodManager, emergencyButtonController, mMainExecutor, mResources);
} else if (keyguardInputView instanceof KeyguardPINView) {
return new KeyguardPinViewController((KeyguardPINView) keyguardInputView,
mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
mLiftToActivateListener, mFalsingCollector);
mLiftToActivateListener, emergencyButtonController, mFalsingCollector);
} else if (keyguardInputView instanceof KeyguardSimPinView) {
return new KeyguardSimPinViewController((KeyguardSimPinView) keyguardInputView,
mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
mLiftToActivateListener, mTelephonyManager, mFalsingCollector);
mLiftToActivateListener, mTelephonyManager,
emergencyButtonController,
mFalsingCollector);
} else if (keyguardInputView instanceof KeyguardSimPukView) {
return new KeyguardSimPukViewController((KeyguardSimPukView) keyguardInputView,
mKeyguardUpdateMonitor, securityMode, mLockPatternUtils,
keyguardSecurityCallback, mMessageAreaControllerFactory, mLatencyTracker,
mLiftToActivateListener, mTelephonyManager, mFalsingCollector);
mLiftToActivateListener, mTelephonyManager,
emergencyButtonController,
mFalsingCollector);
}
throw new RuntimeException("Unable to find controller for " + keyguardInputView);

View File

@@ -111,10 +111,11 @@ public class KeyguardPasswordViewController
KeyguardMessageAreaController.Factory messageAreaControllerFactory,
LatencyTracker latencyTracker,
InputMethodManager inputMethodManager,
EmergencyButtonController emergencyButtonController,
@Main DelayableExecutor mainExecutor,
@Main Resources resources) {
super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
messageAreaControllerFactory, latencyTracker);
messageAreaControllerFactory, latencyTracker, emergencyButtonController);
mKeyguardSecurityCallback = keyguardSecurityCallback;
mInputMethodManager = inputMethodManager;
mMainExecutor = mainExecutor;

View File

@@ -31,7 +31,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;
@@ -50,6 +50,7 @@ public class KeyguardPatternViewController
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final LockPatternUtils mLockPatternUtils;
private final LatencyTracker mLatencyTracker;
private final EmergencyButtonController mEmergencyButtonController;
private final KeyguardMessageAreaController.Factory mMessageAreaControllerFactory;
private KeyguardMessageAreaController mMessageAreaController;
@@ -179,11 +180,13 @@ public class KeyguardPatternViewController
LockPatternUtils lockPatternUtils,
KeyguardSecurityCallback keyguardSecurityCallback,
LatencyTracker latencyTracker,
EmergencyButtonController emergencyButtonController,
KeyguardMessageAreaController.Factory messageAreaControllerFactory) {
super(view, securityMode, keyguardSecurityCallback);
super(view, securityMode, keyguardSecurityCallback, emergencyButtonController);
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mLockPatternUtils = lockPatternUtils;
mLatencyTracker = latencyTracker;
mEmergencyButtonController = emergencyButtonController;
mMessageAreaControllerFactory = messageAreaControllerFactory;
KeyguardMessageArea kma = KeyguardMessageArea.findSecurityMessageDisplay(mView);
mMessageAreaController = mMessageAreaControllerFactory.create(kma);
@@ -205,11 +208,7 @@ public class KeyguardPatternViewController
KeyguardUpdateMonitor.getCurrentUser()));
// vibrate mode will be the same for the life of this screen
mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
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) {
@@ -224,10 +223,7 @@ public class KeyguardPatternViewController
protected void onViewDetached() {
super.onViewDetached();
mLockPatternView.setOnPatternListener(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);

View File

@@ -71,9 +71,10 @@ 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);
messageAreaControllerFactory, latencyTracker, emergencyButtonController);
mLiftToActivateListener = liftToActivateListener;
mFalsingCollector = falsingCollector;
mPasswordEntry = mView.findViewById(mView.getPasswordTextViewId());

View File

@@ -34,10 +34,11 @@ public class KeyguardPinViewController
KeyguardSecurityCallback keyguardSecurityCallback,
KeyguardMessageAreaController.Factory messageAreaControllerFactory,
LatencyTracker latencyTracker, LiftToActivateListener liftToActivateListener,
EmergencyButtonController emergencyButtonController,
FalsingCollector falsingCollector) {
super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
messageAreaControllerFactory, latencyTracker, liftToActivateListener,
falsingCollector);
emergencyButtonController, falsingCollector);
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -78,10 +78,11 @@ public class KeyguardSimPinViewController
KeyguardSecurityCallback keyguardSecurityCallback,
KeyguardMessageAreaController.Factory messageAreaControllerFactory,
LatencyTracker latencyTracker, LiftToActivateListener liftToActivateListener,
TelephonyManager telephonyManager, FalsingCollector falsingCollector) {
TelephonyManager telephonyManager, EmergencyButtonController emergencyButtonController,
FalsingCollector falsingCollector) {
super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
messageAreaControllerFactory, latencyTracker, liftToActivateListener,
falsingCollector);
emergencyButtonController, falsingCollector);
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mTelephonyManager = telephonyManager;
mSimImageView = mView.findViewById(R.id.keyguard_sim);

View File

@@ -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;
@@ -85,10 +84,11 @@ public class KeyguardSimPukViewController
KeyguardSecurityCallback keyguardSecurityCallback,
KeyguardMessageAreaController.Factory messageAreaControllerFactory,
LatencyTracker latencyTracker, LiftToActivateListener liftToActivateListener,
TelephonyManager telephonyManager, FalsingCollector falsingCollector) {
TelephonyManager telephonyManager, EmergencyButtonController emergencyButtonController,
FalsingCollector falsingCollector) {
super(view, keyguardUpdateMonitor, securityMode, lockPatternUtils, keyguardSecurityCallback,
messageAreaControllerFactory, latencyTracker, liftToActivateListener,
falsingCollector);
emergencyButtonController, falsingCollector);
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mTelephonyManager = telephonyManager;
mSimImageView = mView.findViewById(R.id.keyguard_sim);
@@ -196,8 +196,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) {

View File

@@ -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;
@@ -317,6 +315,22 @@ public class KeyguardSliceView extends LinearLayout {
R.dimen.widget_label_font_size);
mRowWithHeaderTextSize = mContext.getResources().getDimensionPixelSize(
R.dimen.header_row_font_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) {
@@ -479,8 +493,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
@@ -492,24 +505,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);
}

View File

@@ -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>() {

View File

@@ -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 {

View File

@@ -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
@@ -271,12 +279,12 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
mKeyguardSliceViewController.updateTopMargin(
mKeyguardClockSwitchController.getClockTextTopPadding());
mView.setCanShowOwnerInfo(false);
mView.setCanShowLogout(false);
mView.updateLogoutView(false);
} else {
// reset margin
mKeyguardSliceViewController.updateTopMargin(0);
mView.setCanShowOwnerInfo(true);
mView.setCanShowLogout(false);
mView.updateLogoutView(false);
}
updateAodIcons();
}
@@ -302,7 +310,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
if (DEBUG) Slog.v(TAG, "refresh statusview showing:" + showing);
refreshTime();
mView.updateOwnerInfo();
mView.updateLogoutView();
mView.updateLogoutView(shouldShowLogout());
}
}
@@ -320,12 +328,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());
}
};
}

View File

@@ -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();
}
}

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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);
}
}

View File

@@ -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 {}

View File

@@ -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

View File

@@ -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;
@@ -146,4 +147,9 @@ public interface SysUIComponent {
* Member injection into the supplied argument.
*/
void inject(KeyguardSliceProvider keyguardSliceProvider);
/**
* Member injection into the supplied argument.
*/
void inject(ClockOptionsProvider clockOptionsProvider);
}

View File

@@ -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,

View File

@@ -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 {
/**

View File

@@ -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;
@@ -58,7 +58,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;
@@ -153,7 +153,7 @@ public class QSCarrierGroupController {
}
};
private static class Callback implements CarrierTextController.CarrierTextCallback {
private static class Callback implements CarrierTextManager.CarrierTextCallback {
private H mHandler;
Callback(H handler) {
@@ -161,7 +161,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();
}
}
@@ -169,7 +169,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 {
@@ -178,7 +178,7 @@ public class QSCarrierGroupController {
mActivityStarter = activityStarter;
mBgHandler = bgHandler;
mNetworkController = networkController;
mCarrierTextController = carrierTextControllerBuilder
mCarrierTextManager = carrierTextManagerBuilder
.setShowAirplaneMode(false)
.setShowMissingSim(false)
.build();
@@ -196,7 +196,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();
@@ -247,10 +246,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);
}
}
@@ -277,7 +276,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;
@@ -331,13 +330,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;
@@ -349,7 +348,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();
@@ -366,13 +365,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;

View File

@@ -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() {
}
}

View File

@@ -84,6 +84,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;
@@ -326,6 +327,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;
@@ -342,6 +344,7 @@ public class NotificationPanelViewController extends PanelViewController {
private boolean mKeyguardUserSwitcherIsShowing;
private KeyguardUserSwitcherController mKeyguardUserSwitcherController;
private KeyguardStatusBarView mKeyguardStatusBar;
private KeyguardStatusBarViewController mKeyguarStatusBarViewController;
private ViewGroup mBigClockContainer;
private QS mQs;
private FrameLayout mQsFrame;
@@ -594,6 +597,7 @@ public class NotificationPanelViewController extends PanelViewController {
KeyguardStatusViewComponent.Factory keyguardStatusViewComponentFactory,
KeyguardQsUserSwitchComponent.Factory keyguardQsUserSwitchComponentFactory,
KeyguardUserSwitcherComponent.Factory keyguardUserSwitcherComponentFactory,
KeyguardStatusBarViewComponent.Factory keyguardStatusBarViewComponentFactory,
QSDetailDisplayer qsDetailDisplayer,
NotificationGroupManagerLegacy groupManager,
NotificationIconAreaController notificationIconAreaController,
@@ -620,6 +624,7 @@ public class NotificationPanelViewController extends PanelViewController {
mGroupManager = groupManager;
mNotificationIconAreaController = notificationIconAreaController;
mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory;
mKeyguardStatusBarViewComponentFactory = keyguardStatusBarViewComponentFactory;
mFeatureFlags = featureFlags;
mKeyguardQsUserSwitchComponentFactory = keyguardQsUserSwitchComponentFactory;
mKeyguardUserSwitcherComponentFactory = keyguardUserSwitcherComponentFactory;
@@ -723,7 +728,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);
@@ -801,13 +808,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();
@@ -955,7 +970,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);

View File

@@ -54,7 +54,6 @@ 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;
@@ -74,7 +73,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 +94,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
@@ -104,13 +105,14 @@ public class CarrierTextControllerTest extends SysuiTestCase {
private TelephonyManager mTelephonyManager;
@Mock
private SubscriptionManager mSubscriptionManager;
private CarrierTextController.CarrierTextCallbackInfo mCarrierTextCallbackInfo;
private CarrierTextManager.CarrierTextCallbackInfo mCarrierTextCallbackInfo;
private CarrierTextController mCarrierTextController;
private CarrierTextManager mCarrierTextManager;
private TestableLooper mTestableLooper;
private Handler mMainHandler;
private Void checkMainThread(InvocationOnMock inv) {
Looper mainLooper = Dependency.get(Dependency.MAIN_HANDLER).getLooper();
Looper mainLooper = mMainHandler.getLooper();
if (!mainLooper.isCurrentThread()) {
fail("This call should be done from the main thread");
}
@@ -122,35 +124,33 @@ public class CarrierTextControllerTest extends SysuiTestCase {
MockitoAnnotations.initMocks(this);
mTestableLooper = TestableLooper.get(this);
mContext.addMockSystemService(WifiManager.class, mWifiManager);
mContext.addMockSystemService(ConnectivityManager.class, mConnectivityManager);
mMainHandler = new Handler(mTestableLooper.getLooper());
when(mConnectivityManager.isNetworkSupported(anyInt())).thenReturn(true);
mContext.addMockSystemService(TelephonyManager.class, mTelephonyManager);
mContext.addMockSystemService(SubscriptionManager.class, mSubscriptionManager);
mContext.getOrCreateTestableResources().addOverride(
R.string.keyguard_sim_error_message_short, INVALID_CARD_TEXT);
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)
.registerCallback(any(KeyguardUpdateMonitorCallback.class));
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, mConnectivityManager,
mTelephonyManager, mWakefulnessLifecycle, new Handler(mTestableLooper.getLooper()),
mMainHandler, 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);
mCarrierTextManager.setListening(mCarrierTextCallback);
mTestableLooper.processAllMessages();
}
@@ -165,8 +165,8 @@ public class CarrierTextControllerTest extends SysuiTestCase {
TestableLooper testableLooper = new TestableLooper(thread.getLooper());
Handler h = new Handler(testableLooper.getLooper());
h.post(() -> {
mCarrierTextController.setListening(null);
mCarrierTextController.setListening(mCarrierTextCallback);
mCarrierTextManager.setListening(null);
mCarrierTextManager.setListening(mCarrierTextCallback);
});
testableLooper.processAllMessages();
mTestableLooper.processAllMessages();
@@ -183,11 +183,11 @@ 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();
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
@@ -205,12 +205,12 @@ 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();
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
@@ -223,7 +223,7 @@ 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();
mCarrierTextManager.updateCarrierText();
mTestableLooper.processAllMessages();
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
assertEquals("TEST_CARRIER", captor.getValue().carrierText);
@@ -237,9 +237,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 +257,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();
verify(mCarrierTextCallback).updateCarrierInfo(
any(CarrierTextController.CarrierTextCallbackInfo.class));
any(CarrierTextManager.CarrierTextCallbackInfo.class));
}
@Test
public void testCallback() {
reset(mCarrierTextCallback);
mCarrierTextController.postToCallback(mCarrierTextCallbackInfo);
mCarrierTextManager.postToCallback(mCarrierTextCallbackInfo);
mTestableLooper.processAllMessages();
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,8 +282,8 @@ 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();
@@ -301,15 +301,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();
mCarrierTextManager.updateCarrierText();
mTestableLooper.processAllMessages();
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 +326,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();
mCarrierTextManager.updateCarrierText();
mTestableLooper.processAllMessages();
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,16 +346,16 @@ 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();
mCarrierTextManager.updateCarrierText();
mTestableLooper.processAllMessages();
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
@@ -380,11 +380,11 @@ 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();
mCarrierTextManager.updateCarrierText();
mTestableLooper.processAllMessages();
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
@@ -407,15 +407,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();
mCarrierTextManager.updateCarrierText();
mTestableLooper.processAllMessages();
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,16 +428,16 @@ 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();
mCarrierTextManager.updateCarrierText();
mTestableLooper.processAllMessages();
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
@@ -458,11 +458,11 @@ 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();
mCarrierTextManager.updateCarrierText();
mTestableLooper.processAllMessages();
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
@@ -483,11 +483,11 @@ 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();
mCarrierTextManager.updateCarrierText();
mTestableLooper.processAllMessages();
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());
@@ -509,11 +509,11 @@ 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();
mCarrierTextManager.updateCarrierText();
mTestableLooper.processAllMessages();
verify(mCarrierTextCallback).updateCarrierInfo(captor.capture());

View File

@@ -69,6 +69,8 @@ public class KeyguardAbsKeyInputViewControllerTest extends SysuiTestCase {
private KeyguardMessageAreaController mKeyguardMessageAreaController;
@Mock
private LatencyTracker mLatencyTracker;
@Mock
private EmergencyButtonController mEmergencyButtonController;
private KeyguardAbsKeyInputViewController mKeyguardAbsKeyInputViewController;
@@ -84,7 +86,8 @@ public class KeyguardAbsKeyInputViewControllerTest extends SysuiTestCase {
.thenReturn(mKeyguardMessageArea);
mKeyguardAbsKeyInputViewController = new KeyguardAbsKeyInputViewController(mAbsKeyInputView,
mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback,
mKeyguardMessageAreaControllerFactory, mLatencyTracker) {
mKeyguardMessageAreaControllerFactory, mLatencyTracker,
mEmergencyButtonController) {
@Override
void resetState() {
}

View File

@@ -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,

View File

@@ -49,6 +49,8 @@ class KeyguardPatternViewControllerTest : SysuiTestCase() {
@Mock
private lateinit var mLatencyTracker: LatencyTracker
@Mock
private lateinit var mEmergencyButtonController: EmergencyButtonController
@Mock
private lateinit
var mKeyguardMessageAreaControllerFactory: KeyguardMessageAreaController.Factory
@Mock
@@ -72,7 +74,8 @@ class KeyguardPatternViewControllerTest : SysuiTestCase() {
.thenReturn(mKeyguardMessageAreaController)
mKeyguardPatternViewController = KeyguardPatternViewController(mKeyguardPatternView,
mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback,
mLatencyTracker, mKeyguardMessageAreaControllerFactory)
mLatencyTracker, mEmergencyButtonController,
mKeyguardMessageAreaControllerFactory)
}
@Test

View File

@@ -67,6 +67,8 @@ public class KeyguardPinBasedInputViewControllerTest extends SysuiTestCase {
private LatencyTracker mLatencyTracker;
@Mock
private LiftToActivateListener mLiftToactivateListener;
@Mock
private EmergencyButtonController mEmergencyButtonController;
private FalsingCollector mFalsingCollector = new FalsingCollectorFake();
@Mock
private View mDeleteButton;
@@ -92,7 +94,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);

View File

@@ -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

View File

@@ -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.utils.leaks.LeakCheckedTest;
@@ -54,7 +54,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
@@ -62,9 +62,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
@@ -83,11 +83,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));
@@ -113,8 +113,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,
@@ -122,8 +122,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,
@@ -131,8 +131,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,
@@ -140,8 +140,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,
@@ -159,8 +159,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,
@@ -168,8 +168,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,
@@ -177,8 +177,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,
@@ -186,8 +186,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,
@@ -203,8 +203,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,
@@ -223,8 +223,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,

View File

@@ -61,6 +61,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;
@@ -297,6 +304,10 @@ public class NotificationPanelViewTest extends SysuiTestCase {
new ViewGroup.LayoutParams(600, 400));
when(mNotificationStackScrollLayoutController.getLayoutParams()).thenReturn(
new ViewGroup.LayoutParams(600, 400));
when(mKeyguardStatusBarViewComponentFactory.build(any()))
.thenReturn(mKeyguardStatusBarViewComponent);
when(mKeyguardStatusBarViewComponent.getKeyguardStatusBarViewController())
.thenReturn(mKeyguardStatusBarViewController);
mNotificationPanelViewController = new NotificationPanelViewController(mView,
mResources,
@@ -315,6 +326,7 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mKeyguardStatusViewComponentFactory,
mKeyguardQsUserSwitchComponentFactory,
mKeyguardUserSwitcherComponentFactory,
mKeyguardStatusBarViewComponentFactory,
mQSDetailDisplayer,
mGroupManager,
mNotificationAreaController,