From 43cdc3e9a29b77009e9fbb430ac1d42e11e68e4d Mon Sep 17 00:00:00 2001 From: Dave Mankoff Date: Tue, 9 Feb 2021 12:53:03 -0500 Subject: [PATCH 1/6] Add ViewController to CarrierText. Rename CarrierTextController to CarrierTextManager to avoid confusion. Removes several calls to Dependency.get(). This was the primary impetus for this change. Bug: 179775696 Test: atest SystemUITests Change-Id: I6d027169247e8b93fe979e54c04a61bbacb4cca5 --- .../src/com/android/keyguard/CarrierText.java | 65 +- .../keyguard/CarrierTextController.java | 693 +---------------- .../android/keyguard/CarrierTextManager.java | 720 ++++++++++++++++++ .../KeyguardStatusBarViewComponent.java | 42 + .../dagger/KeyguardStatusBarViewModule.java | 34 + .../dagger/KeyguardStatusBarViewScope.java | 32 + .../dagger/KeyguardStatusViewComponent.java | 2 + .../keyguard/dagger/KeyguardModule.java | 8 +- .../qs/carrier/QSCarrierGroupController.java | 29 +- .../KeyguardStatusBarViewController.java | 48 ++ .../NotificationPanelViewController.java | 22 +- ...rTest.java => CarrierTextManagerTest.java} | 136 ++-- .../carrier/QSCarrierGroupControllerTest.java | 54 +- .../phone/NotificationPanelViewTest.java | 12 + 14 files changed, 1072 insertions(+), 825 deletions(-) create mode 100644 packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java create mode 100644 packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java create mode 100644 packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java create mode 100644 packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewScope.java create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java rename packages/SystemUI/tests/src/com/android/keyguard/{CarrierTextControllerTest.java => CarrierTextManagerTest.java} (79%) diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierText.java b/packages/SystemUI/src/com/android/keyguard/CarrierText.java index f6b03c1fa0131..e4f6e131258e3 100644 --- a/packages/SystemUI/src/com/android/keyguard/CarrierText.java +++ b/packages/SystemUI/src/com/android/keyguard/CarrierText.java @@ -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; diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java index b1e14346c3fab..46a6d8b829112 100644 --- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java +++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java @@ -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 { + 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: - * - * - * 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 getSubscriptionInfo() { - return mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(false); - } - - protected void updateCarrierText() { - boolean allSimsMissing = true; - boolean anySimReadyAndInService = false; - CharSequence displayText = null; - List 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 append(List 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); } } diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java new file mode 100644 index 0000000000000..87b01e8671f06 --- /dev/null +++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java @@ -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: + *
    + *
  • If there was a registered callback, and the network is supported, it will register + * listeners. + *
  • If there was not a registered callback, it will try to remove unregistered listeners + * which is a no-op + *
+ * + * 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 getSubscriptionInfo() { + return mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(false); + } + + protected void updateCarrierText() { + boolean allSimsMissing = true; + boolean anySimReadyAndInService = false; + CharSequence displayText = null; + List 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 append(List 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() {}; + } +} diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java new file mode 100644 index 0000000000000..49a617eeb6c09 --- /dev/null +++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewComponent.java @@ -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(); +} diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java new file mode 100644 index 0000000000000..a6725234e4af1 --- /dev/null +++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewModule.java @@ -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); + } +} diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewScope.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewScope.java new file mode 100644 index 0000000000000..ba0642f57a887 --- /dev/null +++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusBarViewScope.java @@ -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 {} diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewComponent.java b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewComponent.java index 1b6476ce74df7..d342377da49b3 100644 --- a/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewComponent.java +++ b/packages/SystemUI/src/com/android/keyguard/dagger/KeyguardStatusViewComponent.java @@ -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 diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java index de2e7c476e185..a747edd0580a7 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/dagger/KeyguardModule.java @@ -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 { /** diff --git a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java index a567f512b204b..aa6bbbda04fbe 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/carrier/QSCarrierGroupController.java @@ -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 mUpdateCarrierInfo; + private Consumer mUpdateCarrierInfo; private Runnable mUpdateState; static final int MSG_UPDATE_CARRIER_INFO = 0; static final int MSG_UPDATE_STATE = 1; H(Looper looper, - Consumer updateCarrierInfo, + Consumer 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; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java new file mode 100644 index 0000000000000..377fb92ac6bad --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java @@ -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 { + 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() { + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index 738ac4d18c621..2ece2ee6a0f38 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -78,6 +78,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; @@ -320,6 +321,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; @@ -336,6 +338,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; @@ -588,6 +591,7 @@ public class NotificationPanelViewController extends PanelViewController { KeyguardStatusViewComponent.Factory keyguardStatusViewComponentFactory, KeyguardQsUserSwitchComponent.Factory keyguardQsUserSwitchComponentFactory, KeyguardUserSwitcherComponent.Factory keyguardUserSwitcherComponentFactory, + KeyguardStatusBarViewComponent.Factory keyguardStatusBarViewComponentFactory, QSDetailDisplayer qsDetailDisplayer, NotificationGroupManagerLegacy groupManager, NotificationIconAreaController notificationIconAreaController, @@ -614,6 +618,7 @@ public class NotificationPanelViewController extends PanelViewController { mGroupManager = groupManager; mNotificationIconAreaController = notificationIconAreaController; mKeyguardStatusViewComponentFactory = keyguardStatusViewComponentFactory; + mKeyguardStatusBarViewComponentFactory = keyguardStatusBarViewComponentFactory; mFeatureFlags = featureFlags; mKeyguardQsUserSwitchComponentFactory = keyguardQsUserSwitchComponentFactory; mKeyguardUserSwitcherComponentFactory = keyguardUserSwitcherComponentFactory; @@ -717,7 +722,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); @@ -791,13 +798,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(); @@ -935,7 +950,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); diff --git a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java similarity index 79% rename from packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java rename to packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java index aa4122fd190a6..d3f9d641ca9fd 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/CarrierTextManagerTest.java @@ -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 captor = + ArgumentCaptor 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 captor = + ArgumentCaptor 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 captor = + ArgumentCaptor 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 captor = + ArgumentCaptor 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 captor = + ArgumentCaptor 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 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 captor = + ArgumentCaptor 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 captor = + ArgumentCaptor 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 captor = + ArgumentCaptor 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 captor = + ArgumentCaptor 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 captor = + ArgumentCaptor 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 captor = + ArgumentCaptor 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 captor = + ArgumentCaptor captor = ArgumentCaptor.forClass( - CarrierTextController.CarrierTextCallbackInfo.class); + CarrierTextManager.CarrierTextCallbackInfo.class); - mCarrierTextController.updateCarrierText(); + mCarrierTextManager.updateCarrierText(); mTestableLooper.processAllMessages(); verify(mCarrierTextCallback).updateCarrierInfo(captor.capture()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java index 1ec1da44c0b54..e855834dcad4f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/carrier/QSCarrierGroupControllerTest.java @@ -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) 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) 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, diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java index 3f5a6992fcef0..38aa633279a00 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java @@ -59,6 +59,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; @@ -204,10 +205,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; @@ -295,6 +302,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, @@ -313,6 +324,7 @@ public class NotificationPanelViewTest extends SysuiTestCase { mKeyguardStatusViewComponentFactory, mKeyguardQsUserSwitchComponentFactory, mKeyguardUserSwitcherComponentFactory, + mKeyguardStatusBarViewComponentFactory, mQSDetailDisplayer, mGroupManager, mNotificationAreaController, From f8cb6b24581a41e976d0eb0229a78c778e583e0b Mon Sep 17 00:00:00 2001 From: Dave Mankoff Date: Tue, 9 Feb 2021 15:37:19 -0500 Subject: [PATCH 2/6] Add Controller for Emergency Button. This removes all the calls to Dependency.get from EmergencyButton. Bug: 179775696 Test: atest SystemUITests && manual Change-Id: I4d9a4a21fe8a8a0306b110a2fbaaa3ea91507d05 --- .../com/android/keyguard/EmergencyButton.java | 140 +------------ .../keyguard/EmergencyButtonController.java | 196 ++++++++++++++++++ .../KeyguardAbsKeyInputViewController.java | 14 +- .../keyguard/KeyguardInputViewController.java | 40 +++- .../KeyguardPasswordViewController.java | 3 +- .../KeyguardPatternViewController.java | 18 +- .../KeyguardPinBasedInputViewController.java | 3 +- .../keyguard/KeyguardPinViewController.java | 3 +- ...KeyguardSecurityViewFlipperController.java | 13 +- .../KeyguardSimPinViewController.java | 5 +- .../KeyguardSimPukViewController.java | 5 +- ...KeyguardAbsKeyInputViewControllerTest.java | 5 +- .../KeyguardPatternViewControllerTest.kt | 5 +- ...yguardPinBasedInputViewControllerTest.java | 4 +- ...uardSecurityViewFlipperControllerTest.java | 9 +- 15 files changed, 285 insertions(+), 178 deletions(-) create mode 100644 packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java index 707ee298a55a9..c4b02f62f2914 100644 --- a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java +++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java @@ -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); - } } diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java new file mode 100644 index 0000000000000..4275189cfe267 --- /dev/null +++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java @@ -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 { + 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); + } + } +} diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java index 5760565aaab16..7a05a17c80105 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java @@ -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 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 }; 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 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 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 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); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java index 0f1c3c8a20b76..2e45545925804 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordViewController.java @@ -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; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java index 2aaf748e2415e..55e348cc06b18 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java @@ -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); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java index f2479488db0f8..1b5aa453ac97a 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputViewController.java @@ -71,9 +71,10 @@ public abstract class KeyguardPinBasedInputViewController> 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 { protected NullKeyguardInputViewController(SecurityMode securityMode, - KeyguardSecurityCallback keyguardSecurityCallback) { - super(null, securityMode, keyguardSecurityCallback); + KeyguardSecurityCallback keyguardSecurityCallback, + EmergencyButtonController emergencyButtonController) { + super(null, securityMode, keyguardSecurityCallback, emergencyButtonController); } @Override diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java index b218141346074..a5a3a80b8d42e 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java @@ -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); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java index 890a17c1cf921..58bec70babd8a 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java @@ -85,10 +85,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); diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java index c2ade81a9877a..d67fe6dfb0b2a 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardAbsKeyInputViewControllerTest.java @@ -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() { } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt index c69ec1a254c30..6d0c64088abc1 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt @@ -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 diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java index 31cc7bb7c958e..8d1e1a4a44633 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewControllerTest.java @@ -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); diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java index 3b7f4b8398537..9296d3d5ec820 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityViewFlipperControllerTest.java @@ -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 From dfc947e84fc7b951221a9b04fa976d7cfeeb4201 Mon Sep 17 00:00:00 2001 From: Dave Mankoff Date: Tue, 9 Feb 2021 15:46:58 -0500 Subject: [PATCH 3/6] Remove Dependency.get from KeyguardSliceTextView. Moved the related code into the containing class's controller. Bug: 179775696 Test: atest SystemUITests Change-Id: I4c76d99f988233dd4fd51b7a6ff7606c77e73087 --- .../android/keyguard/KeyguardSliceView.java | 35 +++++++++---------- .../keyguard/KeyguardSliceViewController.java | 4 +++ 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java index fb97a30f93fbf..1fbf71de47ca4 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java @@ -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); } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java index 1b0a7faeddab7..8038ce4c7b691 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceViewController.java @@ -83,6 +83,10 @@ public class KeyguardSliceViewController extends ViewController mObserver = new Observer() { From 000e4071584a3b43eadb3be4403448dd66097cdc Mon Sep 17 00:00:00 2001 From: Dave Mankoff Date: Tue, 9 Feb 2021 16:36:37 -0500 Subject: [PATCH 4/6] Add injection to ClockProvider. Removes Dependency.get from ClockProvider. Bug: 179775696 Test: atest SystemUITests Change-Id: I730593fcf5cf8d8d969990eccfc0297efd1eb56b --- .../android/keyguard/clock/ClockModule.java | 33 +++++++++++++++++++ .../keyguard/clock/ClockOptionsProvider.java | 20 +++++------ .../systemui/dagger/SysUIComponent.java | 6 ++++ .../systemui/dagger/SystemUIModule.java | 2 ++ 4 files changed, 50 insertions(+), 11 deletions(-) create mode 100644 packages/SystemUI/src/com/android/keyguard/clock/ClockModule.java diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockModule.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockModule.java new file mode 100644 index 0000000000000..c4be1ba535039 --- /dev/null +++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockModule.java @@ -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 provideClockInfoList(ClockManager clockManager) { + return clockManager.getClockInfos(); + } +} diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockOptionsProvider.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockOptionsProvider.java index 5ef35be8df51a..b6413cb61deb6 100644 --- a/packages/SystemUI/src/com/android/keyguard/clock/ClockOptionsProvider.java +++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockOptionsProvider.java @@ -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> mClocksSupplier; - - public ClockOptionsProvider() { - this(() -> Dependency.get(ClockManager.class).getClockInfos()); - } + @Inject + public Provider> mClockInfosProvider; @VisibleForTesting - ClockOptionsProvider(Supplier> clocksSupplier) { - mClocksSupplier = clocksSupplier; + ClockOptionsProvider(Provider> 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 clocks = mClocksSupplier.get(); + List 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 clocks = mClocksSupplier.get(); + List clocks = mClockInfosProvider.get(); for (int i = 0; i < clocks.size(); i++) { if (id.equals(clocks.get(i).getId())) { clock = clocks.get(i); diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java index ffb8446f3e21a..91c2dcfd92028 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java @@ -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); } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java index b0067cd15c1ba..b67db03a743ca 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java @@ -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, From b8b5aa4ed2e7499cb6e1b84d9d68202b65d033b5 Mon Sep 17 00:00:00 2001 From: Dave Mankoff Date: Tue, 9 Feb 2021 16:58:40 -0500 Subject: [PATCH 5/6] Remove Dependency.get from KeyguardStatusView. Bug: 179775696 Test: atest SystemUITests && manual Change-Id: Ifbb93e624d839d7506b45da2cabb4fcf8b0b75ff --- .../android/keyguard/KeyguardStatusView.java | 19 ++----------------- .../KeyguardStatusViewController.java | 18 +++++++++++++----- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java index fea152abe36ae..5db4f9e61140d 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java @@ -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 { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java index 6fb6760be653b..bfe7f8c7ebd88 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java @@ -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 Date: Tue, 9 Feb 2021 17:03:06 -0500 Subject: [PATCH 6/6] Remove final calls to Dependency.get from keyguard. Fixes: 179775696 Test: atest SystemUITests && manual Change-Id: I23721545632093850182416ae8a6213662b04e6b --- .../android/keyguard/KeyguardDisplayManager.java | 8 ++++++-- .../android/keyguard/KeyguardSecurityModel.java | 14 ++++++++------ .../keyguard/KeyguardSimPukViewController.java | 4 +--- .../keyguard/KeyguardDisplayManagerTest.java | 9 ++++----- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java index 276036c400e10..76a7473e25e83 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java @@ -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 mNavigationBarControllerLazy; private final KeyguardStatusViewComponent.Factory mKeyguardStatusViewComponentFactory; private final Context mContext; @@ -85,9 +87,11 @@ public class KeyguardDisplayManager { @Inject public KeyguardDisplayManager(Context context, + Lazy 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; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java index c77c86711abf0..bacd29f661ae2 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java @@ -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; } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java index 58bec70babd8a..b584bf75831e3 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java @@ -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; @@ -197,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) { diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java index 826be2ba0d832..4beec574cd2a5 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardDisplayManagerTest.java @@ -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,