diff options
Diffstat (limited to 'packages/SystemUI/src')
50 files changed, 1902 insertions, 146 deletions
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java index 997c5275a2fa..85645adf72e2 100644 --- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java +++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java @@ -16,6 +16,8 @@ package com.android.keyguard; +import android.telephony.TelephonyManager; + import com.android.systemui.util.ViewController; import javax.inject.Inject; diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java index 907943a9203d..f90f93797ee8 100644 --- a/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java +++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextManager.java @@ -37,6 +37,8 @@ import com.android.systemui.R; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.keyguard.WakefulnessLifecycle; +import com.android.systemui.statusbar.policy.FiveGServiceClient; +import com.android.systemui.statusbar.policy.FiveGServiceClient.FiveGServiceState; import com.android.systemui.telephony.TelephonyListenerManager; import java.util.List; @@ -88,6 +90,7 @@ public class CarrierTextManager { if (callback != null) callback.startedGoingToSleep(); } }; + private FiveGServiceClient mFiveGServiceClient; @VisibleForTesting protected final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() { @@ -299,11 +302,15 @@ public class CarrierTextManager { protected void updateCarrierText() { boolean allSimsMissing = true; boolean anySimReadyAndInService = false; + boolean missingSimsWithSubs = false; + boolean showCustomizeName = getContext().getResources().getBoolean( + com.android.systemui.R.bool.config_show_customize_carrier_name); CharSequence displayText = null; List<SubscriptionInfo> subs = getSubscriptionInfo(); final int numSubs = subs.size(); final int[] subsIds = new int[numSubs]; + if (DEBUG) Log.d(TAG, "updateCarrierText(): " + 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]; @@ -320,6 +327,9 @@ public class CarrierTextManager { subOrderBySlot[subs.get(i).getSimSlotIndex()] = i; int simState = mKeyguardUpdateMonitor.getSimState(subId); CharSequence carrierName = subs.get(i).getCarrierName(); + if ( showCustomizeName ) { + carrierName = getCustomizeCarrierName(carrierName, subs.get(i)); + } CharSequence carrierTextForSimState = getCarrierTextForSimState(simState, carrierName); if (DEBUG) { Log.d(TAG, "Handling (subId=" + subId + "): " + simState + " " + carrierName); @@ -732,4 +742,119 @@ public class CarrierTextManager { */ default void finishedWakingUp() {}; } + + private String getCustomizeCarrierName(CharSequence originCarrierName, + SubscriptionInfo sub) { + StringBuilder newCarrierName = new StringBuilder(); + int networkType = getNetworkType(sub.getSubscriptionId()); + String networkClass = networkTypeToString(networkType); + + String fiveGNetworkClass = get5GNetworkClass(sub, networkType); + if ( fiveGNetworkClass != null ) { + networkClass = fiveGNetworkClass; + } + + if (!TextUtils.isEmpty(originCarrierName)) { + String[] names = originCarrierName.toString().split(mSeparator.toString(), 2); + for (int j = 0; j < names.length; j++) { + names[j] = getLocalString( + names[j], com.android.systemui.R.array.origin_carrier_names, + com.android.systemui.R.array.locale_carrier_names); + if (!TextUtils.isEmpty(names[j])) { + if (!TextUtils.isEmpty(networkClass)) { + names[j] = new StringBuilder().append(names[j]).append(" ") + .append(networkClass).toString(); + } + if (j > 0 && names[j].equals(names[j - 1])) { + continue; + } + if (j > 0) { + newCarrierName.append(mSeparator); + } + newCarrierName.append(names[j]); + } + } + } + return newCarrierName.toString(); + } + + /** + * parse the string to current language. + * + * @param originalString original string + * @param originNamesId the id of the original string array. + * @param localNamesId the id of the local string keys. + * @return local language string + */ + private String getLocalString(String originalString, + int originNamesId, int localNamesId) { + String[] origNames = getContext().getResources().getStringArray(originNamesId); + String[] localNames = getContext().getResources().getStringArray(localNamesId); + for (int i = 0; i < origNames.length; i++) { + if (origNames[i].equalsIgnoreCase(originalString)) { + return localNames[i]; + } + } + return originalString; + } + + private int getNetworkType(int subId) { + int networkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; + ServiceState ss = mKeyguardUpdateMonitor.mServiceStates.get(subId); + if (ss != null && (ss.getDataRegState() == ServiceState.STATE_IN_SERVICE + || ss.getVoiceRegState() == ServiceState.STATE_IN_SERVICE)) { + networkType = ss.getDataNetworkType(); + if (networkType == TelephonyManager.NETWORK_TYPE_UNKNOWN) { + networkType = ss.getVoiceNetworkType(); + } + } + return networkType; + } + + private String networkTypeToString(int networkType) { + int classId = com.android.systemui.R.string.config_rat_unknown; + long mask = TelephonyManager.getBitMaskForNetworkType(networkType); + if ((mask & TelephonyManager.NETWORK_CLASS_BITMASK_2G) != 0) { + classId = com.android.systemui.R.string.config_rat_2g; + } else if ((mask & TelephonyManager.NETWORK_CLASS_BITMASK_3G) != 0) { + classId = com.android.systemui.R.string.config_rat_3g; + } else if ((mask & TelephonyManager.NETWORK_CLASS_BITMASK_4G) != 0) { + classId = com.android.systemui.R.string.config_rat_4g; + } + return getContext().getResources().getString(classId); + } + + + private String get5GNetworkClass(SubscriptionInfo sub, int networkType) { + if ( networkType == TelephonyManager.NETWORK_TYPE_NR ) { + return mContext.getResources().getString(R.string.data_connection_5g); + } + + int slotIndex = sub.getSimSlotIndex(); + int subId = sub.getSubscriptionId(); + + if ( mFiveGServiceClient == null ) { + mFiveGServiceClient = FiveGServiceClient.getInstance(mContext); + mFiveGServiceClient.registerCallback(mCallback); + } + FiveGServiceState fiveGServiceState = + mFiveGServiceClient.getCurrentServiceState(slotIndex); + if ( fiveGServiceState.isNrIconTypeValid() && isDataRegisteredOnLte(subId)) { + return mContext.getResources().getString(R.string.data_connection_5g); + } + + return null; + } + + private boolean isDataRegisteredOnLte(int subId) { + TelephonyManager telephonyManager = (TelephonyManager) + mContext.getSystemService(Context.TELEPHONY_SERVICE); + int dataType = telephonyManager.getDataNetworkType(subId); + if ( dataType == TelephonyManager.NETWORK_TYPE_LTE || + dataType == TelephonyManager.NETWORK_TYPE_LTE_CA) { + return true; + }else{ + return false; + } + } } diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java index c4b02f62f291..ef76e9304c1c 100644 --- a/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java +++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButton.java @@ -17,6 +17,7 @@ package com.android.keyguard; import android.content.Context; +import com.android.systemui.Dependency; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; @@ -26,6 +27,9 @@ import android.widget.Button; import com.android.internal.util.EmergencyAffordanceManager; import com.android.internal.widget.LockPatternUtils; import com.android.settingslib.Utils; +import com.android.systemui.R; + +import java.util.List; /** * This class implements a smart emergency button that updates itself based @@ -107,7 +111,8 @@ public class EmergencyButton extends Button { return super.performLongClick(); } - void updateEmergencyCallButton(boolean isInCall, boolean isVoiceCapable, boolean simLocked) { + public void updateEmergencyCallButton(boolean isInCall, boolean isVoiceCapable, + boolean simLocked, boolean isEmergencyCapable) { boolean visible = false; if (isVoiceCapable) { // Emergency calling requires voice capability. @@ -118,8 +123,13 @@ public class EmergencyButton extends Button { // Some countries can't handle emergency calls while SIM is locked. visible = mEnableEmergencyCallWhileSimLocked; } else { - // Only show if there is a secure screen (pin/pattern/SIM pin/SIM puk); - visible = mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser()); + // Show if there is a secure screen (pin/pattern/SIM pin/SIM puk) or config set + visible = mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser()) || + mContext.getResources().getBoolean(R.bool.config_showEmergencyButton); + } + + if (mContext.getResources().getBoolean(R.bool.kg_hide_emgcy_btn_when_oos)) { + visible = visible && isEmergencyCapable; } } } @@ -137,4 +147,5 @@ public class EmergencyButton extends Button { setVisibility(View.GONE); } } + } diff --git a/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java b/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java index e7215b8ebe49..1d6dce9b1af8 100644 --- a/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java +++ b/packages/SystemUI/src/com/android/keyguard/EmergencyButtonController.java @@ -26,6 +26,9 @@ import android.os.PowerManager; import android.os.SystemClock; import android.os.UserHandle; import android.telecom.TelecomManager; +import android.telephony.CellInfo; +import android.telephony.ServiceState; +import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.util.Log; @@ -34,12 +37,14 @@ 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.R; import com.android.systemui.statusbar.phone.ShadeController; 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 java.util.List; import javax.inject.Inject; /** View Controller for {@link com.android.keyguard.EmergencyButton}. */ @@ -56,17 +61,28 @@ public class EmergencyButtonController extends ViewController<EmergencyButton> { private final MetricsLogger mMetricsLogger; private EmergencyButtonCallback mEmergencyButtonCallback; + private boolean mIsCellAvailable; + private ServiceState mServiceState; private final KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() { @Override public void onSimStateChanged(int subId, int slotId, int simState) { updateEmergencyCallButton(); + requestCellInfoUpdate(); } @Override public void onPhoneStateChanged(int phoneState) { updateEmergencyCallButton(); + requestCellInfoUpdate(); + } + + @Override + public void onServiceStateChanged(int subId, ServiceState state) { + mServiceState = state; + updateEmergencyCallButton(); + requestCellInfoUpdate(); } }; @@ -117,7 +133,8 @@ public class EmergencyButtonController extends ViewController<EmergencyButton> { mView.updateEmergencyCallButton( mTelecomManager != null && mTelecomManager.isInCall(), mTelephonyManager.isVoiceCapable(), - mKeyguardUpdateMonitor.isSimPinVoiceSecure()); + mKeyguardUpdateMonitor.isSimPinVoiceSecure(), + isEmergencyCapable()); } } @@ -159,6 +176,40 @@ public class EmergencyButtonController extends ViewController<EmergencyButton> { } } + private void requestCellInfoUpdate(){ + if(!getContext().getResources().getBoolean(R.bool.kg_hide_emgcy_btn_when_oos)) { + return; + } + TelephonyManager tmWithoutSim = mTelephonyManager + .createForSubscriptionId(SubscriptionManager.INVALID_SUBSCRIPTION_ID); + try { + tmWithoutSim.requestCellInfoUpdate(getContext().getMainExecutor(), + new TelephonyManager.CellInfoCallback() { + @Override + public void onCellInfo(List<CellInfo> cellInfo) { + if (KeyguardConstants.DEBUG_SIM_STATES) { + Log.d(LOG_TAG, "requestCellInfoUpdate.onCellInfo cellInfoList.size=" + + (cellInfo == null ? 0 : cellInfo.size())); + } + if (cellInfo == null || cellInfo.isEmpty()) { + mIsCellAvailable = false; + } else { + mIsCellAvailable = true; + } + updateEmergencyCallButton(); + } + }); + } catch (Exception exception) { + Log.e(LOG_TAG, "Fail to call TelephonyManager.requestCellInfoUpdate ", exception); + } + } + + private boolean isEmergencyCapable() { + return (!mKeyguardUpdateMonitor.isOOS() + || mIsCellAvailable + || (mServiceState !=null && mServiceState.isEmergencyOnly())); + } + /** */ public interface EmergencyButtonCallback { /** */ diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java index cc6df45c598f..ff5f66485676 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java @@ -66,6 +66,7 @@ public abstract class KeyguardAbsKeyInputView extends KeyguardInputView { return R.string.kg_wrong_password; } + protected abstract void resetPasswordText(boolean animate, boolean announce); protected abstract LockscreenCredential getEnteredCredential(); protected abstract void setPasswordEntryEnabled(boolean enabled); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java index 1c4559eb0364..6bb88646e918 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputViewController.java @@ -169,6 +169,7 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey void onPasswordChecked(int userId, boolean matched, int timeoutMs, boolean isValidPassword) { boolean dismissKeyguard = KeyguardUpdateMonitor.getCurrentUser() == userId; if (matched) { + mLockPatternUtils.sanitizePassword(); getKeyguardSecurityCallback().reportUnlockAttempt(userId, true, 0); if (dismissKeyguard) { mDismissing = true; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardConstants.java b/packages/SystemUI/src/com/android/keyguard/KeyguardConstants.java index b2658c9f9bdb..b2658c9f9bdb 100644..100755 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardConstants.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardConstants.java diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java index 94e07b713915..3ff7c637b365 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternViewController.java @@ -164,6 +164,7 @@ public class KeyguardPatternViewController boolean isValidPattern) { boolean dismissKeyguard = KeyguardUpdateMonitor.getCurrentUser() == userId; if (matched) { + mLockPatternUtils.sanitizePassword(); getKeyguardSecurityCallback().reportUnlockAttempt(userId, true, 0); if (dismissKeyguard) { mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java index 69328cd5d344..12935c342a2d 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java @@ -23,6 +23,7 @@ import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import com.android.internal.widget.LockPatternUtils; +import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; @@ -66,9 +67,8 @@ public class KeyguardSecurityModel { return SecurityMode.SimPuk; } - if (SubscriptionManager.isValidSubscriptionId( - mKeyguardUpdateMonitor.getNextSubIdForState( - TelephonyManager.SIM_STATE_PIN_REQUIRED))) { + int subId = mKeyguardUpdateMonitor.getUnlockedSubIdForState(TelephonyManager.SIM_STATE_PIN_REQUIRED); + if (SubscriptionManager.isValidSubscriptionId((subId))){ return SecurityMode.SimPin; } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java index c0f9ce794628..bd26320fd5e5 100644..100755 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinView.java @@ -29,6 +29,7 @@ import com.android.systemui.R; public class KeyguardSimPinView extends KeyguardPinBasedInputView { public static final String TAG = "KeyguardSimPinView"; + public KeyguardSimPinView(Context context) { this(context, null); } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java index e04bfdc3868d..fadb19f7ce0c 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPinViewController.java @@ -58,18 +58,24 @@ public class KeyguardSimPinViewController private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; private AlertDialog mRemainingAttemptsDialog; private ImageView mSimImageView; + private int mSlotId; KeyguardUpdateMonitorCallback mUpdateMonitorCallback = new KeyguardUpdateMonitorCallback() { @Override public void onSimStateChanged(int subId, int slotId, int simState) { - if (DEBUG) Log.v(TAG, "onSimStateChanged(subId=" + subId + ",state=" + simState + ")"); - if (simState == TelephonyManager.SIM_STATE_READY) { + if (DEBUG) Log.v(TAG, "onSimStateChanged(subId=" + subId + ",slotId=" + slotId + + ",simState=" + simState + ")"); + + if ((simState == TelephonyManager.SIM_STATE_READY) + || (simState == TelephonyManager.SIM_STATE_LOADED)) { mRemainingAttempts = -1; resetState(); } else { resetState(); } } + + }; protected KeyguardSimPinViewController(KeyguardSimPinView view, @@ -96,7 +102,7 @@ public class KeyguardSimPinViewController @Override void resetState() { super.resetState(); - if (DEBUG) Log.v(TAG, "Resetting state"); + if (DEBUG) Log.v(TAG, "Resetting state mShowDefaultMessage="+mShowDefaultMessage); handleSubInfoChangeIfNeeded(); mMessageAreaController.setMessage(""); if (mShowDefaultMessage) { @@ -115,7 +121,6 @@ public class KeyguardSimPinViewController public void onResume(int reason) { super.onResume(reason); mKeyguardUpdateMonitor.registerCallback(mUpdateMonitorCallback); - mView.resetState(); } @Override @@ -128,6 +133,8 @@ public class KeyguardSimPinViewController mSimUnlockProgressDialog.dismiss(); mSimUnlockProgressDialog = null; } + + mMessageAreaController.setMessage(""); } @Override @@ -235,10 +242,18 @@ public class KeyguardSimPinViewController displayMessage = mView.getResources().getString( R.string.kg_password_wrong_pin_code_pukked); } else if (attemptsRemaining > 0) { - msgId = isDefault ? R.plurals.kg_password_default_pin_message : - R.plurals.kg_password_wrong_pin_code; - displayMessage = mView.getResources() - .getQuantityString(msgId, attemptsRemaining, attemptsRemaining); + int count = TelephonyManager.getDefault().getSimCount(); + if ( count > 1 ) { + msgId = isDefault ? R.plurals.kg_password_default_pin_message_multi_sim : + R.plurals.kg_password_wrong_pin_code_multi_sim; + displayMessage = mView.getContext().getResources() + .getQuantityString(msgId, attemptsRemaining, mSlotId, attemptsRemaining); + }else { + msgId = isDefault ? R.plurals.kg_password_default_pin_message : + R.plurals.kg_password_wrong_pin_code; + displayMessage = mView.getContext().getResources() + .getQuantityString(msgId, attemptsRemaining, attemptsRemaining); + } } else { msgId = isDefault ? R.string.kg_sim_pin_instructions : R.string.kg_password_pin_failed; displayMessage = mView.getResources().getString(msgId); @@ -260,6 +275,7 @@ public class KeyguardSimPinViewController return; } + mSlotId = SubscriptionManager.getSlotIndex(mSubId) + 1; // Sending empty PIN here to query the number of remaining PIN attempts new CheckSimPin("", mSubId) { void onSimCheckResponse(final PinResult result) { @@ -336,11 +352,17 @@ public class KeyguardSimPinViewController private void handleSubInfoChangeIfNeeded() { int subId = mKeyguardUpdateMonitor - .getNextSubIdForState(TelephonyManager.SIM_STATE_PIN_REQUIRED); - if (subId != mSubId && SubscriptionManager.isValidSubscriptionId(subId)) { - mSubId = subId; + .getUnlockedSubIdForState(TelephonyManager.SIM_STATE_PIN_REQUIRED); + if (SubscriptionManager.isValidSubscriptionId(subId)) { + if (DEBUG) Log.v(TAG, "handleSubInfoChangeIfNeeded mSubId="+mSubId+" subId="+ subId); mShowDefaultMessage = true; - mRemainingAttempts = -1; + if(subId != mSubId){ + mSubId = subId; + mRemainingAttempts = -1; + } + }else{ + //false by default and keep false except in PIN lock state + mShowDefaultMessage = false; } } } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java index 0d72c93e9041..a1adcd32c6db 100644..100755 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukView.java @@ -17,11 +17,15 @@ package com.android.keyguard; import android.content.Context; +import android.telephony.SubscriptionInfo; import android.util.AttributeSet; import android.util.Log; +import com.android.systemui.Dependency; import com.android.systemui.R; +import java.util.HashMap; +import java.util.Map; /** * Displays a PIN pad for entering a PUK (Pin Unlock Kode) provided by a carrier. @@ -29,6 +33,7 @@ import com.android.systemui.R; public class KeyguardSimPukView extends KeyguardPinBasedInputView { private static final boolean DEBUG = KeyguardConstants.DEBUG; public static final String TAG = "KeyguardSimPukView"; + private Map<String, String> mWrongPukCodeMessageMap = new HashMap<>(4); public KeyguardSimPukView(Context context) { this(context, null); @@ -36,6 +41,35 @@ public class KeyguardSimPukView extends KeyguardPinBasedInputView { public KeyguardSimPukView(Context context, AttributeSet attrs) { super(context, attrs); + updateWrongPukMessageMap(context); + } + + void updateWrongPukMessageMap(Context context) { + String[] customizationConfigs = context.getResources(). + getStringArray(R.array.kg_wrong_puk_code_message_list); + if ( customizationConfigs.length == 0 ){ + Log.d(TAG, "There is no customization PUK prompt"); + return; + } + for(String config : customizationConfigs ) { + String[] kv = config.trim().split(":"); + if ( kv.length != 2) { + Log.e(TAG, "invalid key value config " + config); + continue; + } + mWrongPukCodeMessageMap.put(kv[0], kv[1]); + } + } + + private String getMessageTextForWrongPukCode(int subId) { + String message = null; + SubscriptionInfo info = Dependency.get(KeyguardUpdateMonitor.class) + .getSubscriptionInfoForSubId(subId); + if ( info != null ) { + String mccMNC = info.getMccString()+info.getMncString(); + message = mWrongPukCodeMessageMap.get(mccMNC); + } + return message; } @Override @@ -45,11 +79,16 @@ public class KeyguardSimPukView extends KeyguardPinBasedInputView { } String getPukPasswordErrorMessage( - int attemptsRemaining, boolean isDefault, boolean isEsimLocked) { + int attemptsRemaining, boolean isDefault, boolean isEsimLocked, int subId) { String displayMessage; if (attemptsRemaining == 0) { - displayMessage = getContext().getString(R.string.kg_password_wrong_puk_code_dead); + String message = getMessageTextForWrongPukCode(subId); + if ( message == null ) { + displayMessage = getContext().getString(R.string.kg_password_wrong_puk_code_dead); + }else { + displayMessage = message; + } } else if (attemptsRemaining > 0) { int msgId = isDefault ? R.plurals.kg_password_default_puk_message : R.plurals.kg_password_wrong_puk_code; diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java index 07309224608e..ff680a56efe7 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSimPukViewController.java @@ -178,7 +178,7 @@ public class KeyguardSimPukViewController if (mRemainingAttempts >= 0) { mMessageAreaController.setMessage(mView.getPukPasswordErrorMessage( mRemainingAttempts, true, - KeyguardEsimArea.isEsimLocked(mView.getContext(), mSubId))); + KeyguardEsimArea.isEsimLocked(mView.getContext(), mSubId), mSubId)); return; } @@ -221,7 +221,7 @@ public class KeyguardSimPukViewController mMessageAreaController.setMessage( mView.getPukPasswordErrorMessage( result.getAttemptsRemaining(), true, - KeyguardEsimArea.isEsimLocked(mView.getContext(), mSubId))); + KeyguardEsimArea.isEsimLocked(mView.getContext(), mSubId), mSubId)); } } } @@ -281,7 +281,7 @@ public class KeyguardSimPukViewController // show message mMessageAreaController.setMessage(mView.getPukPasswordErrorMessage( result.getAttemptsRemaining(), false, - KeyguardEsimArea.isEsimLocked(mView.getContext(), mSubId))); + KeyguardEsimArea.isEsimLocked(mView.getContext(), mSubId), mSubId)); if (result.getAttemptsRemaining() <= 2) { // this is getting critical - show dialog getPukRemainingAttemptsDialog( @@ -292,7 +292,7 @@ public class KeyguardSimPukViewController mView.getPukPasswordErrorMessage( result.getAttemptsRemaining(), false, KeyguardEsimArea.isEsimLocked( - mView.getContext(), mSubId))); + mView.getContext(), mSubId), mSubId)); } } else { mMessageAreaController.setMessage(mView.getResources().getString( @@ -341,13 +341,15 @@ public class KeyguardSimPukViewController mSubId = subId; mShowDefaultMessage = true; mRemainingAttempts = -1; + }else{ + mShowDefaultMessage = false; } } private Dialog getPukRemainingAttemptsDialog(int remaining) { String msg = mView.getPukPasswordErrorMessage(remaining, false, - KeyguardEsimArea.isEsimLocked(mView.getContext(), mSubId)); + KeyguardEsimArea.isEsimLocked(mView.getContext(), mSubId), mSubId); if (mRemainingAttemptsDialog == null) { AlertDialog.Builder builder = new AlertDialog.Builder(mView.getContext()); builder.setMessage(msg); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 42f0fccd61b0..b54d11d1f811 100644..100755 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -111,6 +111,7 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController; import com.android.systemui.telephony.TelephonyListenerManager; import com.android.systemui.util.Assert; import com.android.systemui.util.RingerModeTracker; +import com.android.systemui.keyguard.KeyguardViewMediator; import com.google.android.collect.Lists; @@ -119,12 +120,9 @@ import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; import java.util.TimeZone; import java.util.concurrent.Executor; import java.util.function.Consumer; @@ -487,41 +485,21 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */); // Hack level over 9000: Because the subscription id is not yet valid when we see the - // first update in handleSimStateChange, we need to force refresh all SIM states + // first update in handleSimStateChange, we need to force refresh all all SIM states // so the subscription id for them is consistent. ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>(); - Set<Integer> activeSubIds = new HashSet<>(); for (int i = 0; i < subscriptionInfos.size(); i++) { SubscriptionInfo info = subscriptionInfos.get(i); - activeSubIds.add(info.getSubscriptionId()); boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex()); if (changed) { changedSubscriptions.add(info); } } - - // It is possible for active subscriptions to become invalid (-1), and these will not be - // present in the subscriptionInfo list - Iterator<Map.Entry<Integer, SimData>> iter = mSimDatas.entrySet().iterator(); - while (iter.hasNext()) { - Map.Entry<Integer, SimData> simData = iter.next(); - if (!activeSubIds.contains(simData.getKey())) { - Log.i(TAG, "Previously active sub id " + simData.getKey() + " is now invalid, " - + "will remove"); - iter.remove(); - - SimData data = simData.getValue(); - for (int j = 0; j < mCallbacks.size(); j++) { - KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get(); - if (cb != null) { - cb.onSimStateChanged(data.subId, data.slotId, data.simState); - } - } - } - } - for (int i = 0; i < changedSubscriptions.size(); i++) { - SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId()); + SimData data = mSimDatas.get(changedSubscriptions.get(i).getSimSlotIndex()); + if (data == null) { + continue; + } for (int j = 0; j < mCallbacks.size(); j++) { KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get(); if (cb != null) { @@ -1625,11 +1603,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab state = TelephonyManager.SIM_STATE_NETWORK_LOCKED; } else if (Intent.SIM_STATE_CARD_IO_ERROR.equals(stateExtra)) { state = TelephonyManager.SIM_STATE_CARD_IO_ERROR; - } else if (Intent.SIM_STATE_LOADED.equals(stateExtra) - || Intent.SIM_STATE_IMSI.equals(stateExtra)) { + } else if (Intent.SIM_STATE_IMSI.equals(stateExtra)) { // This is required because telephony doesn't return to "READY" after // these state transitions. See bug 7197471. state = TelephonyManager.SIM_STATE_READY; + } else if (Intent.SIM_STATE_LOADED.equals(stateExtra)) { + state = TelephonyManager.SIM_STATE_LOADED; } else { state = TelephonyManager.SIM_STATE_UNKNOWN; } @@ -2873,11 +2852,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } } - SimData data = mSimDatas.get(subId); + SimData data = mSimDatas.get(slotId); final boolean changed; if (data == null) { data = new SimData(state, slotId, subId); - mSimDatas.put(subId, data); + mSimDatas.put(slotId, data); changed = true; // no data yet; force update } else { changed = (data.simState != state || data.subId != subId || data.slotId != slotId); @@ -2907,6 +2886,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab if (!SubscriptionManager.isValidSubscriptionId(subId)) { Log.w(TAG, "invalid subId in handleServiceStateChange()"); + for (int j = 0; j < mCallbacks.size(); j++) { + KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get(); + if (cb != null) { + cb.onServiceStateChanged(subId, serviceState); + } + } return; } else { updateTelephonyCapable(true); @@ -2914,7 +2899,17 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab mServiceStates.put(subId, serviceState); - callbacksRefreshCarrierInfo(); + // The upstream method (callbacksRefreshCarrierInfo) does not subId or + // serviceState as input. Thus onServiceStateChanged cannot be called + // from that new method. For now, re-use the same logic as before here + // instead of a call to callbacksRefreshCarrierInfo. + for (int j = 0; j < mCallbacks.size(); j++) { + KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get(); + if (cb != null) { + cb.onRefreshCarrierInfo(); + cb.onServiceStateChanged(subId, serviceState); + } + } } public boolean isKeyguardVisible() { @@ -3248,18 +3243,20 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } public int getSimState(int subId) { - if (mSimDatas.containsKey(subId)) { - return mSimDatas.get(subId).simState; + int slotId = SubscriptionManager.getSlotIndex(subId); + if (mSimDatas.containsKey(slotId)) { + return mSimDatas.get(slotId).simState; } else { return TelephonyManager.SIM_STATE_UNKNOWN; } } private int getSlotId(int subId) { - if (!mSimDatas.containsKey(subId)) { - refreshSimState(subId, SubscriptionManager.getSlotIndex(subId)); + int slotId = SubscriptionManager.getSlotIndex(subId); + if (!mSimDatas.containsKey(slotId)) { + refreshSimState(subId, slotId); } - return mSimDatas.get(subId).slotId; + return mSimDatas.get(slotId).slotId; } private final TaskStackChangeListener @@ -3288,15 +3285,16 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); int state = (tele != null) ? tele.getSimState(slotId) : TelephonyManager.SIM_STATE_UNKNOWN; - SimData data = mSimDatas.get(subId); + SimData data = mSimDatas.get(slotId); final boolean changed; if (data == null) { data = new SimData(state, slotId, subId); - mSimDatas.put(subId, data); + mSimDatas.put(slotId, data); changed = true; // no data yet; force update } else { - changed = data.simState != state; + changed = (data.simState != state) || (data.slotId != slotId); data.simState = state; + data.slotId = slotId; } return changed; } @@ -3394,6 +3392,28 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab return resultId; } + + /** + * Find the Unlocked SubscriptionId for a SIM in the given state, + * @param state + * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found + */ + public int getUnlockedSubIdForState(int state) { + List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */); + int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; + for (int i = 0; i < list.size(); i++) { + final SubscriptionInfo info = list.get(i); + final int id = info.getSubscriptionId(); + int slotId = SubscriptionManager.getSlotIndex(id); + if (state == getSimState(id) && (KeyguardViewMediator.getUnlockTrackSimState(slotId) + != TelephonyManager.SIM_STATE_READY)) { + resultId = id; + break; + } + } + return resultId; + } + public SubscriptionInfo getSubscriptionInfoForSubId(int subId) { List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */); for (int i = 0; i < list.size(); i++) { @@ -3464,6 +3484,34 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab mHandler.removeCallbacksAndMessages(null); } + public boolean isOOS() { + boolean ret = true; + int phoneCount = mTelephonyManager.getActiveModemCount(); + for (int phoneId = 0; phoneId < phoneCount; phoneId++) { + int[] subId = mSubscriptionManager.getSubscriptionIds(phoneId); + if (subId != null && subId.length >= 1) { + if (DEBUG) Log.d(TAG, "slot id:" + phoneId + " subId:" + subId[0]); + ServiceState state = mServiceStates.get(subId[0]); + if (state != null) { + if (state.isEmergencyOnly()) { + ret = false; + } else if ((state.getVoiceRegState() != ServiceState.STATE_OUT_OF_SERVICE) + && (state.getVoiceRegState() != ServiceState.STATE_POWER_OFF)) { + ret = false; + } + if (DEBUG) { + Log.d(TAG, "is emergency: " + state.isEmergencyOnly() + + "voice state: " + state.getVoiceRegState()); + } + } else { + if (DEBUG) Log.d(TAG, "state is NULL"); + } + } + } + + return ret; + } + @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("KeyguardUpdateMonitor state:"); diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java index 8170a81a09e6..c742f62f81ba 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java @@ -20,6 +20,7 @@ import android.graphics.Bitmap; import android.hardware.biometrics.BiometricSourceType; import android.media.AudioManager; import android.os.SystemClock; +import android.telephony.ServiceState; import android.telephony.TelephonyManager; import android.view.WindowManagerPolicyConstants; @@ -151,6 +152,13 @@ public class KeyguardUpdateMonitorCallback { public void onSimStateChanged(int subId, int slotId, int simState) { } /** + * Called when the sevice state changes. + * @param subId + * @param serviceState + */ + public void onServiceStateChanged(int subId, ServiceState state) { } + + /** * Called when the user's info changed. */ public void onUserInfoChanged(int userId) { } diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index e566ccb49e3b..759adc22862a 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -118,6 +118,10 @@ public class ScreenDecorations extends SystemUI implements Tunable { SystemProperties.getBoolean("debug.disable_screen_decorations", false); private static final boolean DEBUG_SCREENSHOT_ROUNDED_CORNERS = SystemProperties.getBoolean("debug.screenshot_rounded_corners", false); + + private static int mDisableRoundedCorner = + SystemProperties.getInt("vendor.display.disable_rounded_corner", 0); + private static final boolean VERBOSE = false; private static final boolean DEBUG_COLOR = DEBUG_SCREENSHOT_ROUNDED_CORNERS; @@ -712,8 +716,11 @@ public class ScreenDecorations extends SystemUI implements Tunable { // upgrading all of the configs to contain (width, height) pairs. Instead assume that a // device configured using the single integer config value is okay with drawing the corners // as a square - final int newRoundedDefault = RoundedCorners.getRoundedCornerRadius( + int newRoundedDefault = RoundedCorners.getRoundedCornerRadius( mContext.getResources(), mDisplayUniqueId); + if (mDisableRoundedCorner == 1) { + newRoundedDefault = 0; + } final int newRoundedDefaultTop = RoundedCorners.getRoundedCornerTopRadius( mContext.getResources(), mDisplayUniqueId); final int newRoundedDefaultBottom = RoundedCorners.getRoundedCornerBottomRadius( @@ -926,6 +933,10 @@ public class ScreenDecorations extends SystemUI implements Tunable { } static boolean shouldDrawCutout(Context context) { + if (mDisableRoundedCorner == 1) { + return false; + } + return DisplayCutout.getFillBuiltInDisplayCutout( context.getResources(), context.getDisplay().getUniqueId()); } diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/DisplayUtils.java b/packages/SystemUI/src/com/android/systemui/assist/ui/DisplayUtils.java index 33e6ca49ddd5..e228c3b42ebd 100644 --- a/packages/SystemUI/src/com/android/systemui/assist/ui/DisplayUtils.java +++ b/packages/SystemUI/src/com/android/systemui/assist/ui/DisplayUtils.java @@ -20,6 +20,7 @@ import android.content.Context; import android.util.DisplayMetrics; import android.view.Display; import android.view.Surface; +import android.os.SystemProperties; /** * Utility class for determining screen and corner dimensions. @@ -117,6 +118,11 @@ public class DisplayUtils { private static int getCornerRadiusDefault(Context context) { int radius = 0; + int disableRoundedCorner = SystemProperties.getInt("vendor.display.disable_rounded_corner", + 0); + if (disableRoundedCorner == 1) { + return radius; + } int resourceId = context.getResources().getIdentifier("config_rounded_mask_size", "dimen", "com.android.systemui"); diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java index 250c16c81eac..f81706d35748 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java @@ -220,12 +220,14 @@ public class UdfpsController implements DozeReceiver { } void onAcquiredGood() { + Log.d(TAG, "onAcquiredGood"); if (mEnrollHelper != null) { mEnrollHelper.animateIfLastStep(); } } void onEnrollmentHelp() { + Log.d(TAG, "onEnrollmentHelp"); if (mEnrollHelper != null) { mEnrollHelper.onEnrollmentHelp(); } diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java index d5c763d3b6e2..6687beaabbab 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsEnrollHelper.java @@ -135,9 +135,11 @@ public class UdfpsEnrollHelper { } void onEnrollmentProgress(int remaining) { - if (mTotalSteps == -1) { - mTotalSteps = remaining; - } + Log.d(TAG, "onEnrollmentProgress: remaining = " + remaining + + ", mRemainingSteps = " + mRemainingSteps + + ", mTotalSteps = " + mTotalSteps + + ", mLocationsEnrolled = " + mLocationsEnrolled + + ", mCenterTouchCount = " + mCenterTouchCount); if (remaining != mRemainingSteps) { mLocationsEnrolled++; @@ -221,6 +223,7 @@ public class UdfpsEnrollHelper { } void animateIfLastStep() { + Log.d(TAG, "animateIfLastStep: mRemainingSteps = " + mRemainingSteps); if (mListener == null) { Log.e(TAG, "animateIfLastStep, null listener"); return; diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java index 6d31ef0e7701..30e5aed2f8d8 100644 --- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java +++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.java @@ -241,18 +241,20 @@ public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIllumin if (mGhbmView != null && surface == null) { Log.e(TAG, "doIlluminate | surface must be non-null for GHBM"); } - mHbmProvider.enableHbm(mHbmType, surface, () -> { - if (mGhbmView != null) { - mGhbmView.drawIlluminationDot(mSensorRect); - } - if (onIlluminatedRunnable != null) { - // No framework API can reliably tell when a frame reaches the panel. A timeout - // is the safest solution. - postDelayed(onIlluminatedRunnable, mOnIlluminatedDelayMs); - } else { - Log.w(TAG, "doIlluminate | onIlluminatedRunnable is null"); - } - }); + if (mHbmProvider != null) { + mHbmProvider.enableHbm(mHbmType, surface, () -> { + if (mGhbmView != null) { + mGhbmView.drawIlluminationDot(mSensorRect); + } + if (onIlluminatedRunnable != null) { + // No framework API can reliably tell when a frame reaches the panel. A timeout + // is the safest solution. + postDelayed(onIlluminatedRunnable, mOnIlluminatedDelayMs); + } else { + Log.w(TAG, "doIlluminate | onIlluminatedRunnable is null"); + } + }); + } } @Override @@ -265,6 +267,8 @@ public class UdfpsView extends FrameLayout implements DozeReceiver, UdfpsIllumin mGhbmView.setGhbmIlluminationListener(null); mGhbmView.setVisibility(View.INVISIBLE); } - mHbmProvider.disableHbm(null /* onHbmDisabled */); + if (mHbmProvider != null) { + mHbmProvider.disableHbm(null /* onHbmDisabled */); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index b7916f9f09e1..f30e2832c1aa 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -99,6 +99,7 @@ import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.KeyguardViewController; import com.android.keyguard.ViewMediatorCallback; +import com.android.systemui.Dependency; import com.android.systemui.Dumpable; import com.android.systemui.SystemUI; import com.android.systemui.animation.Interpolators; @@ -331,6 +332,8 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, * Index is the slotId - in case of multiple SIM cards. */ private final SparseIntArray mLastSimStates = new SparseIntArray(); + private static SparseIntArray mUnlockTrackSimStates = new SparseIntArray(); + private static final int STATE_INVALID = -1; /** * Indicates if a SIM card had the SIM PIN enabled during the initialization, before @@ -406,12 +409,6 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, private boolean mPendingLock; /** - * When starting to go away, flag a need to show the PIN lock so the keyguard can be brought - * back. - */ - private boolean mPendingPinLock = false; - - /** * Whether a power button gesture (such as double tap for camera) has been detected. This is * delivered directly from {@link KeyguardService}, immediately upon the gesture being detected. * This is used in {@link #onStartedWakingUp} to decide whether to execute the pending lock, or @@ -484,19 +481,6 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() { @Override - public void onKeyguardVisibilityChanged(boolean showing) { - synchronized (KeyguardViewMediator.this) { - if (!showing && mPendingPinLock) { - Log.i(TAG, "PIN lock requested, starting keyguard"); - - // Bring the keyguard back in order to show the PIN lock - mPendingPinLock = false; - doKeyguardLocked(null); - } - } - } - - @Override public void onUserSwitching(int userId) { if (DEBUG) Log.d(TAG, String.format("onUserSwitching %d", userId)); // Note that the mLockPatternUtils user has already been updated from setCurrentUser. @@ -576,6 +560,29 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, lastSimStateWasLocked = (lastState == TelephonyManager.SIM_STATE_PIN_REQUIRED || lastState == TelephonyManager.SIM_STATE_PUK_REQUIRED); mLastSimStates.append(slotId, simState); + + int trackState = mUnlockTrackSimStates.get(slotId, STATE_INVALID); + //update the mUnlockTrackSimStates + if(simState == TelephonyManager.SIM_STATE_READY){ + if(trackState == TelephonyManager.SIM_STATE_LOADED){ + if (DEBUG) Log.e(TAG, "skip the redundant SIM_STATE_READY state"); + return; + }else{ + mUnlockTrackSimStates.put(slotId, simState); + } + }else{ + if(simState != TelephonyManager.SIM_STATE_PIN_REQUIRED) { + mUnlockTrackSimStates.put(slotId, simState); + } + } + + //check the SIM_STATE_PIN_REQUIRED + if(trackState == TelephonyManager.SIM_STATE_READY){ + if(simState == TelephonyManager.SIM_STATE_PIN_REQUIRED) { + if (DEBUG) Log.e(TAG, "skip the unnecessary SIM_STATE_PIN_REQUIRED state"); + return; + } + } } switch (simState) { @@ -616,7 +623,6 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, + "showing; need to show keyguard so user can enter sim pin"); doKeyguardLocked(null); } else { - mPendingPinLock = true; resetStateLocked(); } } @@ -758,9 +764,6 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, @Override public void onBouncerVisiblityChanged(boolean shown) { synchronized (KeyguardViewMediator.this) { - if (shown) { - mPendingPinLock = false; - } adjustStatusBarLocked(shown, false); } } @@ -1446,6 +1449,9 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, Trace.endSection(); } + public static int getUnlockTrackSimState(int slotId) { + return mUnlockTrackSimStates.get(slotId); + } public boolean isHiding() { return mHiding; } @@ -1470,7 +1476,8 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, if (mOccluded != isOccluded) { mOccluded = isOccluded; mUpdateMonitor.setKeyguardOccluded(isOccluded); - mKeyguardViewControllerLazy.get().setOccluded(isOccluded, animate + mKeyguardViewControllerLazy.get().setOccluded(isOccluded, + (Dependency.get(KeyguardUpdateMonitor.class).isSimPinSecure()?false:animate) && mDeviceInteractive); adjustStatusBarLocked(); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java index 22cd6f86b165..79193564e21f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/AirplaneModeTile.java @@ -49,6 +49,8 @@ import com.android.systemui.qs.QSHost; import com.android.systemui.qs.logging.QSLogger; import com.android.systemui.qs.tileimpl.QSTileImpl; +import com.qti.extphone.ExtTelephonyManager; + import javax.inject.Inject; import dagger.Lazy; @@ -102,6 +104,10 @@ public class AirplaneModeTile extends QSTileImpl<BooleanState> { mActivityStarter.postStartActivityDismissingKeyguard( new Intent(TelephonyManager.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS), 0); return; + } else if(!airplaneModeEnabled && TelephonyProperties.in_scbm().orElse(false)) { + mActivityStarter.postStartActivityDismissingKeyguard( + new Intent(ExtTelephonyManager.ACTION_SHOW_NOTICE_SCM_BLOCK_OTHERS), 0); + return; } setEnabled(!airplaneModeEnabled); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java index b83dc52240b3..2cacf3cf9df0 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java @@ -25,6 +25,7 @@ import android.content.Intent; import android.media.MediaRouter.RouteInfo; import android.os.Handler; import android.os.Looper; +import android.os.SystemProperties; import android.provider.Settings; import android.service.quicksettings.Tile; import android.util.Log; @@ -81,6 +82,7 @@ public class CastTile extends QSTileImpl<BooleanState> { private Dialog mDialog; private boolean mWifiConnected; private boolean mHotspotConnected; + private static final String WFD_ENABLE = "persist.debug.wfd.enable"; @Inject public CastTile( @@ -298,14 +300,20 @@ public class CastTile extends QSTileImpl<BooleanState> { @Override public void setWifiIndicators(@NonNull WifiIndicators indicators) { // statusIcon.visible has the connected status information - boolean enabledAndConnected = indicators.enabled - && (indicators.qsIcon == null ? false : indicators.qsIcon.visible); - if (enabledAndConnected != mWifiConnected) { - mWifiConnected = enabledAndConnected; - // Hotspot is not connected, so changes here should update - if (!mHotspotConnected) { + if(SystemProperties.getBoolean(WFD_ENABLE, false)) { + if(indicators.enabled != mWifiConnected) { + mWifiConnected = indicators.enabled; refreshState(); } + } else { + boolean enabledAndConnected = indicators.enabled && indicators.qsIcon.visible; + if (enabledAndConnected != mWifiConnected) { + mWifiConnected = enabledAndConnected; + // Hotspot is not connected, so changes here should update + if (!mHotspotConnected) { + refreshState(); + } + } } } }; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java index e5601f29af0b..1dde8d1480ba 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java @@ -300,6 +300,7 @@ public class CellularTile extends QSTileImpl<SignalState> { @Override public void setMobileDataEnabled(boolean enabled) { mDetailAdapter.setMobileDataEnabled(enabled); + refreshState(mInfo); } } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java index 87edc2cf8bac..db1df77a5803 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/HotspotTile.java @@ -16,7 +16,10 @@ package com.android.systemui.qs.tiles; +import android.content.Context; import android.content.Intent; +import android.net.wifi.ScanResult; +import android.net.wifi.WifiManager; import android.os.Handler; import android.os.Looper; import android.os.UserManager; @@ -49,12 +52,16 @@ import javax.inject.Inject; public class HotspotTile extends QSTileImpl<BooleanState> { private final Icon mEnabledStatic = ResourceIcon.get(R.drawable.ic_hotspot); + private final Icon mWifi4EnabledStatic = ResourceIcon.get(R.drawable.ic_wifi_4_hotspot); + private final Icon mWifi5EnabledStatic = ResourceIcon.get(R.drawable.ic_wifi_5_hotspot); + private final Icon mWifi6EnabledStatic = ResourceIcon.get(R.drawable.ic_wifi_6_hotspot); private final HotspotController mHotspotController; private final DataSaverController mDataSaverController; private final HotspotAndDataSaverCallbacks mCallbacks = new HotspotAndDataSaverCallbacks(); private boolean mListening; + private WifiManager mWifiManager; @Inject public HotspotTile( @@ -75,6 +82,7 @@ public class HotspotTile extends QSTileImpl<BooleanState> { mDataSaverController = dataSaverController; mHotspotController.observe(this, mCallbacks); mDataSaverController.observe(this, mCallbacks); + mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE); } @Override @@ -154,6 +162,15 @@ public class HotspotTile extends QSTileImpl<BooleanState> { if (state.isTransient) { state.icon = ResourceIcon.get( com.android.internal.R.drawable.ic_hotspot_transient_animation); + } else if (state.value) { + int standard = mWifiManager.getSoftApWifiStandard(); + if (standard == ScanResult.WIFI_STANDARD_11AX) { + state.icon = mWifi6EnabledStatic; + } else if (standard == ScanResult.WIFI_STANDARD_11AC) { + state.icon = mWifi5EnabledStatic; + } else if (standard == ScanResult.WIFI_STANDARD_11N) { + state.icon = mWifi4EnabledStatic; + } } state.expandedAccessibilityClassName = Switch.class.getName(); state.contentDescription = state.label; diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java index ef4d1ac14a2c..1e84b40d1544 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialog.java @@ -379,7 +379,8 @@ public class InternetDialog extends SystemUIDialog implements } if (!mInternetDialogController.hasActiveSubId() - && (!mWifiManager.isWifiEnabled() || !isCarrierNetworkActive)) { + && (!mWifiManager.isWifiEnabled() || !isCarrierNetworkActive) + || mInternetDialogController.isInCallOnNonDds()) { mMobileNetworkLayout.setVisibility(View.GONE); } else { mMobileNetworkLayout.setVisibility(View.VISIBLE); @@ -687,6 +688,11 @@ public class InternetDialog extends SystemUIDialog implements } @Override + public void onNonDdsCallStateChanged() { + mHandler.post(() -> updateDialog(true /* shouldUpdateMobileNetwork */)); + } + + @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (mAlertDialog != null && !mAlertDialog.isShowing()) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java index 0d064af9c17d..57e70b009d6a 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogController.java @@ -91,6 +91,7 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.HashMap; import java.util.Set; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicReference; @@ -156,6 +157,10 @@ public class InternetDialogController implements AccessPointController.AccessPoi private LocationController mLocationController; private DialogLaunchAnimator mDialogLaunchAnimator; private boolean mHasWifiEntries; + private int mActiveDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; + private int mVoiceCallState = TelephonyManager.CALL_STATE_IDLE; + private HashMap<TelephonyManager, NonDdsTelephonyCallback> mNonDdsCallbacks = + new HashMap<>(); @VisibleForTesting static final float TOAST_PARAMS_HORIZONTAL_WEIGHT = 1.0f; @@ -256,6 +261,7 @@ public class InternetDialogController implements AccessPointController.AccessPoi mSubscriptionManager.addOnSubscriptionsChangedListener(mExecutor, mOnSubscriptionsChangedListener); mDefaultDataSubId = getDefaultDataSubscriptionId(); + mActiveDataSubId = mDefaultDataSubId; if (DEBUG) { Log.d(TAG, "Init, SubId: " + mDefaultDataSubId); } @@ -263,6 +269,19 @@ public class InternetDialogController implements AccessPointController.AccessPoi mTelephonyManager = mTelephonyManager.createForSubscriptionId(mDefaultDataSubId); mInternetTelephonyCallback = new InternetTelephonyCallback(); mTelephonyManager.registerTelephonyCallback(mExecutor, mInternetTelephonyCallback); + final List<SubscriptionInfo> subscriptions = + mSubscriptionManager.getActiveSubscriptionInfoList(); + if (subscriptions != null) { + NonDdsTelephonyCallback nonDdscallback = new NonDdsTelephonyCallback(); + for (SubscriptionInfo info : subscriptions) { + if (mDefaultDataSubId != info.getSubscriptionId()) { + TelephonyManager tm = + mTelephonyManager.createForSubscriptionId(info.getSubscriptionId()); + tm.registerTelephonyCallback(mExecutor, nonDdscallback); + mNonDdsCallbacks.put(tm, nonDdscallback); + } + } + } // Listen the connectivity changes mConnectivityManager.registerDefaultNetworkCallback(mConnectivityManagerNetworkCallback); mCanConfigWifi = canConfigWifi; @@ -281,6 +300,11 @@ public class InternetDialogController implements AccessPointController.AccessPoi mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateCallback); mConnectivityManager.unregisterNetworkCallback(mConnectivityManagerNetworkCallback); mConnectedWifiInternetMonitor.unregisterCallback(); + for (Map.Entry<TelephonyManager, NonDdsTelephonyCallback> entry + : mNonDdsCallbacks.entrySet()) { + entry.getKey().unregisterTelephonyCallback(entry.getValue()); + } + mNonDdsCallbacks.clear(); } @VisibleForTesting @@ -784,6 +808,11 @@ public class InternetDialogController implements AccessPointController.AccessPoi return !mKeyguardStateController.isUnlocked(); } + public boolean isInCallOnNonDds() { + return mDefaultDataSubId != mActiveDataSubId + && mVoiceCallState != TelephonyManager.CALL_STATE_IDLE; + } + boolean activeNetworkIsCellular() { if (mConnectivityManager == null) { if (DEBUG) { @@ -914,7 +943,8 @@ public class InternetDialogController implements AccessPointController.AccessPoi TelephonyCallback.DisplayInfoListener, TelephonyCallback.ServiceStateListener, TelephonyCallback.SignalStrengthsListener, - TelephonyCallback.UserMobileDataStateListener { + TelephonyCallback.UserMobileDataStateListener, + TelephonyCallback.ActiveDataSubscriptionIdListener { @Override public void onServiceStateChanged(@NonNull ServiceState serviceState) { @@ -941,6 +971,12 @@ public class InternetDialogController implements AccessPointController.AccessPoi public void onUserMobileDataStateChanged(boolean enabled) { mCallback.onUserMobileDataStateChanged(enabled); } + + @Override + public void onActiveDataSubscriptionIdChanged(int subId) { + mActiveDataSubId = subId; + mCallback.onNonDdsCallStateChanged(); + } } private class InternetOnSubscriptionChangedListener @@ -977,6 +1013,15 @@ public class InternetDialogController implements AccessPointController.AccessPoi } } + private class NonDdsTelephonyCallback extends TelephonyCallback implements + TelephonyCallback.CallStateListener { + @Override + public void onCallStateChanged(int state) { + mVoiceCallState = state; + mCallback.onNonDdsCallStateChanged(); + } + } + /** * Helper class for monitoring the Internet access of the connected WifiEntry. */ @@ -1102,6 +1147,8 @@ public class InternetDialogController implements AccessPointController.AccessPoi void onAccessPointsChanged(@Nullable List<WifiEntry> wifiEntries, @Nullable WifiEntry connectedEntry, boolean hasMoreWifiEntries); + + void onNonDdsCallStateChanged(); } void makeOverlayToast(int stringId) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java index 68dcdd9ff49f..13cfddd2b0bb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java @@ -26,6 +26,7 @@ import android.content.Context; import android.content.res.ColorStateList; import android.graphics.Rect; import android.util.AttributeSet; +import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; @@ -60,6 +61,7 @@ public class StatusBarMobileView extends FrameLayout implements DarkReceiver, private DualToneHandler mDualToneHandler; private boolean mForceHidden; private boolean mProviderModel; + private ImageView mVolte; /** * Designated constructor @@ -121,6 +123,7 @@ public class StatusBarMobileView extends FrameLayout implements DarkReceiver, mIn = findViewById(R.id.mobile_in); mOut = findViewById(R.id.mobile_out); mInoutContainer = findViewById(R.id.inout_container); + mVolte = findViewById(R.id.mobile_volte); mMobileDrawable = new SignalDrawable(getContext()); mMobile.setImageDrawable(mMobileDrawable); @@ -164,7 +167,12 @@ public class StatusBarMobileView extends FrameLayout implements DarkReceiver, } else { mMobileGroup.setVisibility(View.VISIBLE); } - mMobileDrawable.setLevel(mState.strengthId); + if (mState.strengthId >= 0) { + mMobile.setVisibility(View.VISIBLE); + mMobileDrawable.setLevel(mState.strengthId); + }else { + mMobile.setVisibility(View.GONE); + } if (mState.typeId > 0) { mMobileType.setContentDescription(mState.typeContentDescription); mMobileType.setImageResource(mState.typeId); @@ -179,6 +187,12 @@ public class StatusBarMobileView extends FrameLayout implements DarkReceiver, mOut.setVisibility(mState.activityOut ? View.VISIBLE : View.GONE); mInoutContainer.setVisibility((mState.activityIn || mState.activityOut) ? View.VISIBLE : View.GONE); + if (mState.volteId > 0 ) { + mVolte.setImageResource(mState.volteId); + mVolte.setVisibility(View.VISIBLE); + }else { + mVolte.setVisibility(View.GONE); + } } private boolean updateState(MobileIconState state) { @@ -186,12 +200,15 @@ public class StatusBarMobileView extends FrameLayout implements DarkReceiver, setContentDescription(state.contentDescription); int newVisibility = state.visible && !mForceHidden ? View.VISIBLE : View.GONE; - if (newVisibility != mMobileGroup.getVisibility()) { + if (newVisibility != mMobileGroup.getVisibility() && STATE_ICON == mVisibleState) { mMobileGroup.setVisibility(newVisibility); needsLayout = true; } - if (mState.strengthId != state.strengthId) { + if (state.strengthId >= 0) { mMobileDrawable.setLevel(state.strengthId); + mMobile.setVisibility(View.VISIBLE); + }else { + mMobile.setVisibility(View.GONE); } if (mState.typeId != state.typeId) { needsLayout |= state.typeId == 0 || mState.typeId == 0; @@ -212,6 +229,15 @@ public class StatusBarMobileView extends FrameLayout implements DarkReceiver, mInoutContainer.setVisibility((state.activityIn || state.activityOut) ? View.VISIBLE : View.GONE); + if (mState.volteId != state.volteId) { + if (state.volteId != 0) { + mVolte.setImageResource(state.volteId); + mVolte.setVisibility(View.VISIBLE); + } else { + mVolte.setVisibility(View.GONE); + } + } + needsLayout |= state.roaming != mState.roaming || state.activityIn != mState.activityIn || state.activityOut != mState.activityOut @@ -230,6 +256,7 @@ public class StatusBarMobileView extends FrameLayout implements DarkReceiver, mIn.setImageTintList(color); mOut.setImageTintList(color); mMobileType.setImageTintList(color); + mVolte.setImageTintList(color); mMobileRoaming.setImageTintList(color); mDotView.setDecorColor(tint); mDotView.setIconColor(tint, false); @@ -251,6 +278,7 @@ public class StatusBarMobileView extends FrameLayout implements DarkReceiver, mIn.setImageTintList(list); mOut.setImageTintList(list); mMobileType.setImageTintList(list); + mVolte.setImageTintList(list); mMobileRoaming.setImageTintList(list); mDotView.setDecorColor(color); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java index 9ae7ea2bdded..6d6a5fb29594 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalController.java @@ -18,9 +18,14 @@ package com.android.systemui.statusbar.connectivity; import static com.android.settingslib.mobile.MobileMappings.getDefaultIcons; import static com.android.settingslib.mobile.MobileMappings.getIconKey; import static com.android.settingslib.mobile.MobileMappings.mapIconSets; +import static com.android.settingslib.mobile.MobileMappings.toDisplayIconKey; +import static com.android.settingslib.mobile.MobileMappings.toIconKey; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; +import android.content.res.Resources; import android.database.ContentObserver; import android.net.NetworkCapabilities; import android.os.Handler; @@ -29,10 +34,15 @@ import android.provider.Settings.Global; import android.telephony.AccessNetworkConstants; import android.telephony.CellSignalStrength; import android.telephony.CellSignalStrengthCdma; +import android.telephony.CellSignalStrengthNr; +import android.telephony.ims.ImsMmTelManager; +import android.telephony.ims.ImsReasonInfo; +import android.telephony.ims.feature.MmTelFeature; import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; +import android.telephony.TelephonyDisplayInfo; import android.telephony.TelephonyManager; import android.telephony.ims.ImsException; import android.telephony.ims.ImsMmTelManager; @@ -43,7 +53,12 @@ import android.text.Html; import android.text.TextUtils; import android.util.Log; +import com.android.ims.ImsManager; +import com.android.ims.FeatureConnector; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.telephony.PhoneConstants; +import com.android.internal.telephony.PhoneConstants.DataState; +import com.android.internal.telephony.TelephonyIntents; import com.android.settingslib.AccessibilityContentDescriptions; import com.android.settingslib.SignalIcon.MobileIconGroup; import com.android.settingslib.graph.SignalDrawable; @@ -54,6 +69,9 @@ import com.android.settingslib.mobile.MobileStatusTracker.SubscriptionDefaults; import com.android.settingslib.mobile.TelephonyIcons; import com.android.settingslib.net.SignalStrengthUtil; import com.android.systemui.R; +import com.android.systemui.statusbar.policy.FiveGServiceClient; +import com.android.systemui.statusbar.policy.FiveGServiceClient.FiveGServiceState; +import com.android.systemui.statusbar.policy.FiveGServiceClient.IFiveGStateListener; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.util.CarrierConfigTracker; @@ -87,6 +105,7 @@ public class MobileSignalController extends SignalController<MobileState, Mobile final SubscriptionInfo mSubscriptionInfo; private Map<String, MobileIconGroup> mNetworkToIconLookup; + private DataState mMMSDataState = DataState.DISCONNECTED; private int mLastLevel; private MobileIconGroup mDefaultIcons; private Config mConfig; @@ -103,6 +122,19 @@ public class MobileSignalController extends SignalController<MobileState, Mobile // Where to copy the next state into. private int mMobileStatusHistoryIndex; + private int mCallState = TelephonyManager.CALL_STATE_IDLE; + + /****************************SideCar****************************/ + @VisibleForTesting + FiveGStateListener mFiveGStateListener; + @VisibleForTesting + FiveGServiceState mFiveGState; + private FiveGServiceClient mClient; + /**********************************************************/ + + private ImsManager mImsManager; + private FeatureConnector<ImsManager> mFeatureConnector; + private final MobileStatusTracker.Callback mMobileCallback = new MobileStatusTracker.Callback() { private String mLastStatus; @@ -202,6 +234,8 @@ public class MobileSignalController extends SignalController<MobileState, Mobile mPhone = phone; mDefaults = defaults; mSubscriptionInfo = info; + mFiveGStateListener = new FiveGStateListener(); + mFiveGState = new FiveGServiceState(); mNetworkNameSeparator = getTextIfExists( R.string.status_bar_network_name_separator).toString(); mNetworkNameDefault = getTextIfExists( @@ -217,6 +251,26 @@ public class MobileSignalController extends SignalController<MobileState, Mobile mLastState.networkNameData = mCurrentState.networkNameData = networkName; mLastState.enabled = mCurrentState.enabled = hasMobileData; mLastState.iconGroup = mCurrentState.iconGroup = mDefaultIcons; + + int phoneId = mSubscriptionInfo.getSimSlotIndex(); + mFeatureConnector = ImsManager.getConnector( + mContext, phoneId, "?", + new FeatureConnector.Listener<ImsManager> () { + @Override + public void connectionReady(ImsManager manager) throws com.android.ims.ImsException { + Log.d(mTag, "ImsManager: connection ready."); + mImsManager = manager; + setListeners(); + } + + @Override + public void connectionUnavailable(int reason) { + Log.d(mTag, "ImsManager: connection unavailable."); + removeListeners(); + } + }, mContext.getMainExecutor()); + + mObserver = new ContentObserver(new Handler(receiverLooper)) { @Override public void onChange(boolean selfChange) { @@ -272,6 +326,14 @@ public class MobileSignalController extends SignalController<MobileState, Mobile mContext.getContentResolver().registerContentObserver(Global.getUriFor( Global.MOBILE_DATA + mSubscriptionInfo.getSubscriptionId()), true, mObserver); + mContext.getContentResolver().registerContentObserver(Global.getUriFor(Global.DATA_ROAMING), + true, mObserver); + mContext.getContentResolver().registerContentObserver(Global.getUriFor( + Global.DATA_ROAMING + mSubscriptionInfo.getSubscriptionId()), + true, mObserver); + mContext.registerReceiver(mVolteSwitchObserver, + new IntentFilter("org.codeaurora.intent.action.ACTION_ENHANCE_4G_SWITCH")); + mFeatureConnector.connect(); if (mProviderModelBehavior) { mReceiverHandler.post(mTryRegisterIms); } @@ -307,6 +369,8 @@ public class MobileSignalController extends SignalController<MobileState, Mobile mMobileStatusTracker.setListening(false); mContext.getContentResolver().unregisterContentObserver(mObserver); mImsMmTelManager.unregisterImsRegistrationCallback(mRegistrationCallback); + mContext.unregisterReceiver(mVolteSwitchObserver); + mFeatureConnector.disconnect(); } private void updateInflateSignalStrength() { @@ -330,12 +394,16 @@ public class MobileSignalController extends SignalController<MobileState, Mobile if (mInflateSignalStrengths) { level++; } + boolean dataDisabled = mCurrentState.userSetup && (mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED || (mCurrentState.iconGroup == TelephonyIcons.NOT_DEFAULT_DATA && mCurrentState.defaultDataOff)); boolean noInternet = mCurrentState.inetCondition == 0; boolean cutOut = dataDisabled || noInternet; + if (mConfig.hideNoInternetState) { + cutOut = false; + } return SignalDrawable.getState(level, getNumLevels(), cutOut); } else if (mCurrentState.enabled) { return SignalDrawable.getEmptyState(getNumLevels()); @@ -349,6 +417,70 @@ public class MobileSignalController extends SignalController<MobileState, Mobile return getCurrentIconId(); } + private boolean isVolteSwitchOn() { + return mImsManager != null && mImsManager.isEnhanced4gLteModeSettingEnabledByUser(); + } + + private int getVolteResId() { + int resId = 0; + int voiceNetTye = mCurrentState.getVoiceNetworkType(); + if ( (mCurrentState.voiceCapable || mCurrentState.videoCapable) + && mCurrentState.imsRegistered ) { + resId = R.drawable.ic_volte; + }else if ( (mCurrentState.telephonyDisplayInfo.getNetworkType() == TelephonyManager.NETWORK_TYPE_LTE + || mCurrentState.telephonyDisplayInfo.getNetworkType() == TelephonyManager.NETWORK_TYPE_LTE_CA) + && voiceNetTye == TelephonyManager.NETWORK_TYPE_UNKNOWN) { + resId = R.drawable.ic_volte_no_voice; + } + return resId; + } + + private void setListeners() { + if (mImsManager == null) { + Log.e(mTag, "setListeners mImsManager is null"); + return; + } + + try { + mImsManager.addCapabilitiesCallback(mCapabilityCallback, mContext.getMainExecutor()); + mImsManager.addRegistrationCallback(mImsRegistrationCallback, mContext.getMainExecutor()); + Log.d(mTag, "addCapabilitiesCallback " + mCapabilityCallback + " into " + mImsManager); + Log.d(mTag, "addRegistrationCallback " + mImsRegistrationCallback + + " into " + mImsManager); + } catch (com.android.ims.ImsException e) { + Log.d(mTag, "unable to addCapabilitiesCallback callback."); + } + queryImsState(); + } + + private void queryImsState() { + TelephonyManager tm = mPhone.createForSubscriptionId(mSubscriptionInfo.getSubscriptionId()); + mCurrentState.voiceCapable = tm.isVolteAvailable(); + mCurrentState.videoCapable = tm.isVideoTelephonyAvailable(); + mCurrentState.imsRegistered = mPhone.isImsRegistered(mSubscriptionInfo.getSubscriptionId()); + if (DEBUG) { + Log.d(mTag, "queryImsState tm=" + tm + " phone=" + mPhone + + " voiceCapable=" + mCurrentState.voiceCapable + + " videoCapable=" + mCurrentState.videoCapable + + " imsResitered=" + mCurrentState.imsRegistered); + } + notifyListenersIfNecessary(); + } + + private void removeListeners() { + if (mImsManager == null) { + Log.e(mTag, "removeListeners mImsManager is null"); + return; + } + + mImsManager.removeCapabilitiesCallback(mCapabilityCallback); + mImsManager.removeRegistrationListener(mImsRegistrationCallback); + Log.d(mTag, "removeCapabilitiesCallback " + mCapabilityCallback + + " from " + mImsManager); + Log.d(mTag, "removeRegistrationCallback " + mImsRegistrationCallback + + " from " + mImsManager); + } + @Override public void notifyListeners(SignalCallback callback) { // If the device is on carrier merged WiFi, we should let WifiSignalController to control @@ -373,6 +505,7 @@ public class MobileSignalController extends SignalController<MobileState, Mobile final QsInfo qsInfo = getQsInfo(contentDescription, icons.dataType); final SbInfo sbInfo = getSbInfo(contentDescription, icons.dataType); + int volteIcon = mConfig.showVolteIcon && isVolteSwitchOn() ? getVolteResId() : 0; MobileDataIndicators mobileDataIndicators = new MobileDataIndicators( sbInfo.icon, qsInfo.icon, @@ -380,6 +513,7 @@ public class MobileSignalController extends SignalController<MobileState, Mobile qsInfo.ratTypeIcon, mCurrentState.hasActivityIn(), mCurrentState.hasActivityOut(), + volteIcon, dataContentDescription, dataContentDescriptionHtml, qsInfo.description, @@ -426,12 +560,12 @@ public class MobileSignalController extends SignalController<MobileState, Mobile boolean showDataIconStatusBar = (mCurrentState.dataConnected || dataDisabled) && (mCurrentState.dataSim && mCurrentState.isDefault); typeIcon = - (showDataIconStatusBar || mConfig.alwaysShowDataRatIcon) ? dataTypeIcon : 0; + (showDataIconStatusBar || mConfig.alwaysShowDataRatIcon + || mConfig.alwaysShowNetworkTypeIcon) ? dataTypeIcon : 0; showDataIconStatusBar |= mCurrentState.roaming; statusIcon = new IconState( showDataIconStatusBar && !mCurrentState.airplaneMode, getCurrentIconId(), contentDescription); - showTriangle = showDataIconStatusBar && !mCurrentState.airplaneMode; } else { statusIcon = new IconState( @@ -439,12 +573,27 @@ public class MobileSignalController extends SignalController<MobileState, Mobile getCurrentIconId(), contentDescription); boolean showDataIconInStatusBar = - (mCurrentState.dataConnected && mCurrentState.isDefault) || dataDisabled; + (mCurrentState.dataConnected && mCurrentState.isDefault + || mConfig.alwaysShowNetworkTypeIcon) || dataDisabled; typeIcon = (showDataIconInStatusBar || mConfig.alwaysShowDataRatIcon) ? dataTypeIcon : 0; showTriangle = mCurrentState.enabled && !mCurrentState.airplaneMode; } + if ( mConfig.enableRatIconEnhancement ) { + typeIcon = getEnhancementDataRatIcon(); + }else if ( mConfig.enableDdsRatIconEnhancement ) { + typeIcon = getEnhancementDdsRatIcon(); + } + + MobileIconGroup vowifiIconGroup = getVowifiIconGroup(); + if (mConfig.showVowifiIcon && vowifiIconGroup != null) { + typeIcon = vowifiIconGroup.dataType; + statusIcon = new IconState(true, + ((mCurrentState.enabled && !mCurrentState.airplaneMode) ? statusIcon.icon : -1), + statusIcon.contentDescription); + } + return new SbInfo(showTriangle, typeIcon, statusIcon); } @@ -490,6 +639,16 @@ public class MobileSignalController extends SignalController<MobileState, Mobile } else if (action.equals(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) { updateDataSim(); notifyListenersIfNecessary(); + }else if (action.equals(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) { + String apnType = intent.getStringExtra(PhoneConstants.DATA_APN_TYPE_KEY); + String state = intent.getStringExtra(PhoneConstants.STATE_KEY); + if ("mms".equals(apnType)) { + if (DEBUG) { + Log.d(mTag, "handleBroadcast MMS connection state=" + state); + } + mMMSDataState = DataState.valueOf(state); + updateTelephony(); + } } } @@ -729,6 +888,27 @@ public class MobileSignalController extends SignalController<MobileState, Mobile mCurrentState.connected = mCurrentState.isInService(); if (mCurrentState.connected) { mCurrentState.level = getSignalLevel(mCurrentState.signalStrength); + if (mConfig.showRsrpSignalLevelforLTE) { + if (DEBUG) { + Log.d(mTag, "updateTelephony CS:" + mCurrentState.getVoiceNetworkType() + + "/" + TelephonyManager.getNetworkTypeName( + mCurrentState.getVoiceNetworkType()) + + ", PS:" + mCurrentState.getDataNetworkType() + + "/"+ TelephonyManager.getNetworkTypeName( + mCurrentState.getDataNetworkType())); + } + int dataType = mCurrentState.getDataNetworkType(); + if (dataType == TelephonyManager.NETWORK_TYPE_LTE || + dataType == TelephonyManager.NETWORK_TYPE_LTE_CA) { + mCurrentState.level = getAlternateLteLevel(mCurrentState.signalStrength); + } else if (dataType == TelephonyManager.NETWORK_TYPE_UNKNOWN) { + int voiceType = mCurrentState.getVoiceNetworkType(); + if (voiceType == TelephonyManager.NETWORK_TYPE_LTE || + voiceType == TelephonyManager.NETWORK_TYPE_LTE_CA) { + mCurrentState.level = getAlternateLteLevel(mCurrentState.signalStrength); + } + } + } } String iconKey = getIconKey(mCurrentState.telephonyDisplayInfo); @@ -737,7 +917,17 @@ public class MobileSignalController extends SignalController<MobileState, Mobile } else { mCurrentState.iconGroup = mDefaultIcons; } - mCurrentState.dataConnected = mCurrentState.isDataConnected(); + + //Modem has centralized logic to display 5G icon based on carrier requirements + //For 5G icon display, only query NrIconType reported by modem + if ( mFiveGState.isNrIconTypeValid() ) { + mCurrentState.iconGroup = mFiveGState.getIconGroup(); + }else { + mCurrentState.iconGroup = getNetworkTypeIconGroup(); + } + + mCurrentState.dataConnected = (mCurrentState.isDataConnected() + || mMMSDataState == DataState.CONNECTED); mCurrentState.roaming = isRoaming(); if (isCarrierNetworkChangeActive()) { @@ -765,6 +955,19 @@ public class MobileSignalController extends SignalController<MobileState, Mobile mCurrentState.networkNameData = mCurrentState.getOperatorAlphaShort(); } + + if ( mConfig.alwaysShowNetworkTypeIcon ) { + if(!mCurrentState.connected) { + mCurrentState.iconGroup = TelephonyIcons.UNKNOWN; + }else if (mFiveGState.isNrIconTypeValid()) { + mCurrentState.iconGroup = mFiveGState.getIconGroup(); + }else { + mCurrentState.iconGroup = getNetworkTypeIconGroup(); + } + } + mCurrentState.mobileDataEnabled = mPhone.isDataEnabled(); + mCurrentState.roamingDataEnabled = mPhone.isDataRoamingEnabled(); + notifyListenersIfNecessary(); } @@ -789,6 +992,76 @@ public class MobileSignalController extends SignalController<MobileState, Mobile return !mPhone.isDataConnectionAllowed(); } + private boolean isDataNetworkTypeAvailable() { + boolean isAvailable = true; + if ( mCurrentState.telephonyDisplayInfo.getNetworkType() == TelephonyManager.NETWORK_TYPE_UNKNOWN ) { + isAvailable = false; + }else { + int dataType = getDataNetworkType(); + int voiceType = getVoiceNetworkType(); + if ((dataType == TelephonyManager.NETWORK_TYPE_EVDO_A + || dataType == TelephonyManager.NETWORK_TYPE_EVDO_B + || dataType == TelephonyManager.NETWORK_TYPE_EHRPD + || dataType == TelephonyManager.NETWORK_TYPE_LTE + || dataType == TelephonyManager.NETWORK_TYPE_LTE_CA) + && (voiceType == TelephonyManager.NETWORK_TYPE_GSM + || voiceType == TelephonyManager.NETWORK_TYPE_1xRTT + || voiceType == TelephonyManager.NETWORK_TYPE_CDMA) + && ( !isCallIdle() )) { + isAvailable = false; + } + } + + return isAvailable; + } + + private boolean isCallIdle() { + return mCallState == TelephonyManager.CALL_STATE_IDLE; + } + + private int getVoiceNetworkType() { + // TODO(b/214591923) + //return mServiceState != null ? + // mServiceState.getVoiceNetworkType() : TelephonyManager.NETWORK_TYPE_UNKNOWN; + return TelephonyManager.NETWORK_TYPE_UNKNOWN; + } + + private int getDataNetworkType() { + // TODO(b/214591923) + //return mServiceState != null ? + // mServiceState.getDataNetworkType() : TelephonyManager.NETWORK_TYPE_UNKNOWN; + return TelephonyManager.NETWORK_TYPE_UNKNOWN; + } + + private int getAlternateLteLevel(SignalStrength signalStrength) { + if (signalStrength == null) { + Log.e(mTag, "getAlternateLteLevel signalStrength is null"); + return 0; + } + + int lteRsrp = signalStrength.getLteDbm(); + if ( lteRsrp == SignalStrength.INVALID ) { + int signalStrengthLevel = signalStrength.getLevel(); + if (DEBUG) { + Log.d(mTag, "getAlternateLteLevel lteRsrp:INVALID " + + " signalStrengthLevel = " + signalStrengthLevel); + } + return signalStrengthLevel; + } + + int rsrpLevel = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + if (lteRsrp > -44) rsrpLevel = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + else if (lteRsrp >= -97) rsrpLevel = SignalStrength.SIGNAL_STRENGTH_GREAT; + else if (lteRsrp >= -105) rsrpLevel = SignalStrength.SIGNAL_STRENGTH_GOOD; + else if (lteRsrp >= -113) rsrpLevel = SignalStrength.SIGNAL_STRENGTH_MODERATE; + else if (lteRsrp >= -120) rsrpLevel = SignalStrength.SIGNAL_STRENGTH_POOR; + else if (lteRsrp >= -140) rsrpLevel = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + if (DEBUG) { + Log.d(mTag, "getAlternateLteLevel lteRsrp:" + lteRsrp + " rsrpLevel = " + rsrpLevel); + } + return rsrpLevel; + } + @VisibleForTesting void setActivity(int activity) { mCurrentState.activityIn = activity == TelephonyManager.DATA_ACTIVITY_INOUT @@ -808,6 +1081,79 @@ public class MobileSignalController extends SignalController<MobileState, Mobile mImsType = imsType; } + public void registerFiveGStateListener(FiveGServiceClient client) { + int phoneId = mSubscriptionInfo.getSimSlotIndex(); + client.registerListener(phoneId, mFiveGStateListener); + mClient = client; + } + + public void unregisterFiveGStateListener(FiveGServiceClient client) { + int phoneId = mSubscriptionInfo.getSimSlotIndex(); + client.unregisterListener(phoneId); + } + + private MobileIconGroup getNetworkTypeIconGroup() { + MobileIconGroup iconGroup = mDefaultIcons; + int overrideNetworkType = mCurrentState.telephonyDisplayInfo.getOverrideNetworkType(); + String iconKey = null; + if (overrideNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE + || overrideNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA_MMWAVE + || overrideNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA ){ + int networkType = mCurrentState.telephonyDisplayInfo.getNetworkType(); + if (networkType == TelephonyManager.NETWORK_TYPE_UNKNOWN) { + networkType = mCurrentState.getVoiceNetworkType(); + } + iconKey = toIconKey(networkType); + } else{ + iconKey = toDisplayIconKey(overrideNetworkType); + } + + return mNetworkToIconLookup.getOrDefault(iconKey, mDefaultIcons); + } + + private boolean showDataRatIcon() { + boolean result = false; + if ( mCurrentState.mobileDataEnabled ) { + if(mCurrentState.roamingDataEnabled || !mCurrentState.roaming) { + result = true; + } + } + return result; + } + + private int getEnhancementDataRatIcon() { + return showDataRatIcon() && mCurrentState.connected ? getRatIconGroup().dataType : 0; + } + + private int getEnhancementDdsRatIcon() { + return mCurrentState.dataSim && mCurrentState.connected ? getRatIconGroup().dataType : 0; + } + + private MobileIconGroup getRatIconGroup() { + MobileIconGroup iconGroup = mDefaultIcons; + if ( mFiveGState.isNrIconTypeValid() ) { + iconGroup = mFiveGState.getIconGroup(); + }else { + iconGroup = getNetworkTypeIconGroup(); + } + return iconGroup; + } + + private boolean isVowifiAvailable() { + return mCurrentState.voiceCapable && mCurrentState.imsRegistered + && mCurrentState.getDataNetworkType() == TelephonyManager.NETWORK_TYPE_IWLAN; + } + + private MobileIconGroup getVowifiIconGroup() { + if ( isVowifiAvailable() && !isCallIdle() ) { + return TelephonyIcons.VOWIFI_CALLING; + }else if (isVowifiAvailable()) { + return TelephonyIcons.VOWIFI; + }else { + return null; + } + } + @Override public void dump(PrintWriter pw) { super.dump(pw); @@ -816,6 +1162,14 @@ public class MobileSignalController extends SignalController<MobileState, Mobile pw.println(" mProviderModelBehavior=" + mProviderModelBehavior + ","); pw.println(" mInflateSignalStrengths=" + mInflateSignalStrengths + ","); pw.println(" isDataDisabled=" + isDataDisabled() + ","); + pw.println(" mConfig.enableRatIconEnhancement=" + mConfig.enableRatIconEnhancement + ","); + pw.println(" mConfig.enableDdsRatIconEnhancement=" + + mConfig.enableDdsRatIconEnhancement + ","); + pw.println(" mConfig.alwaysShowNetworkTypeIcon=" + + mConfig.alwaysShowNetworkTypeIcon + ","); + pw.println(" mConfig.showVowifiIcon=" + mConfig.showVowifiIcon + ","); + pw.println(" mConfig.showVolteIcon=" + mConfig.showVolteIcon + ","); + pw.println(" isVolteSwitchOn=" + isVolteSwitchOn() + ","); pw.println(" mNetworkToIconLookup=" + mNetworkToIconLookup + ","); pw.println(" MobileStatusHistory"); int size = 0; @@ -831,8 +1185,67 @@ public class MobileSignalController extends SignalController<MobileState, Mobile + (mMobileStatusHistoryIndex + STATUS_HISTORY_SIZE - i) + "): " + mMobileStatusHistory[i & (STATUS_HISTORY_SIZE - 1)]); } + pw.println(" mFiveGState=" + mFiveGState + ","); + } + + class FiveGStateListener implements IFiveGStateListener{ + + public void onStateChanged(FiveGServiceState state) { + if (DEBUG) { + Log.d(mTag, "onStateChanged: state=" + state); + } + mFiveGState = state; + updateTelephony(); + notifyListeners(); + } } + private ImsMmTelManager.CapabilityCallback mCapabilityCallback = new ImsMmTelManager.CapabilityCallback() { + @Override + public void onCapabilitiesStatusChanged(MmTelFeature.MmTelCapabilities config) { + mCurrentState.voiceCapable = + config.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE); + mCurrentState.videoCapable = + config.isCapable(MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VIDEO); + Log.d(mTag, "onCapabilitiesStatusChanged isVoiceCapable=" + mCurrentState.voiceCapable + + " isVideoCapable=" + mCurrentState.videoCapable); + notifyListenersIfNecessary(); + } + }; + + private final ImsMmTelManager.RegistrationCallback mImsRegistrationCallback = + new ImsMmTelManager.RegistrationCallback() { + @Override + public void onRegistered(int imsTransportType) { + Log.d(mTag, "onRegistered imsTransportType=" + imsTransportType); + mCurrentState.imsRegistered = true; + notifyListenersIfNecessary(); + } + + @Override + public void onRegistering(int imsTransportType) { + Log.d(mTag, "onRegistering imsTransportType=" + imsTransportType); + mCurrentState.imsRegistered = false; + notifyListenersIfNecessary(); + } + + @Override + public void onUnregistered(ImsReasonInfo info) { + Log.d(mTag, "onDeregistered imsReasonInfo=" + info); + mCurrentState.imsRegistered = false; + notifyListenersIfNecessary(); + } + }; + + private final BroadcastReceiver mVolteSwitchObserver = new BroadcastReceiver() { + public void onReceive(Context context, Intent intent) { + Log.d(mTag, "action=" + intent.getAction()); + if ( mConfig.showVolteIcon ) { + notifyListeners(); + } + } + }; + /** Box for QS icon info */ private static final class QsInfo { final int ratTypeIcon; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileState.kt b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileState.kt index 8a3b00662900..548a3fc4d02b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileState.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileState.kt @@ -41,7 +41,12 @@ internal class MobileState( @JvmField var roaming: Boolean = false, @JvmField var dataState: Int = TelephonyManager.DATA_DISCONNECTED, // Tracks the on/off state of the defaultDataSubscription - @JvmField var defaultDataOff: Boolean = false + @JvmField var defaultDataOff: Boolean = false, + @JvmField var imsRegistered: Boolean = false, + @JvmField var voiceCapable: Boolean = false, + @JvmField var videoCapable: Boolean = false, + @JvmField var mobileDataEnabled: Boolean = false, + @JvmField var roamingDataEnabled: Boolean = false ) : ConnectivityState() { @JvmField var telephonyDisplayInfo = TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_UNKNOWN, @@ -86,6 +91,11 @@ internal class MobileState( roaming = o.roaming dataState = o.dataState defaultDataOff = o.defaultDataOff + imsRegistered = o.imsRegistered + voiceCapable = o.voiceCapable + videoCapable = o.videoCapable + mobileDataEnabled = o.mobileDataEnabled + roamingDataEnabled = o.roamingDataEnabled telephonyDisplayInfo = o.telephonyDisplayInfo serviceState = o.serviceState @@ -125,6 +135,14 @@ internal class MobileState( return serviceState != null && serviceState!!.roaming } + fun getVoiceNetworkType(): Int { + return serviceState?.getVoiceNetworkType() ?: TelephonyManager.NETWORK_TYPE_UNKNOWN; + } + + fun getDataNetworkType(): Int { + return serviceState?.getDataNetworkType() ?: TelephonyManager.NETWORK_TYPE_UNKNOWN; + } + fun setFromMobileStatus(mobileStatus: MobileStatus) { activityIn = mobileStatus.activityIn activityOut = mobileStatus.activityOut @@ -151,6 +169,11 @@ internal class MobileState( builder.append("userSetup=$userSetup,") builder.append("dataState=$dataState,") builder.append("defaultDataOff=$defaultDataOff,") + builder.append("imsRegistered=$imsRegistered,") + builder.append("voiceCapable=$voiceCapable,") + builder.append("videoCapable=$videoCapable,") + builder.append("mobileDataEnabled=$mobileDataEnabled,") + builder.append("roamingDataEnabled=$roamingDataEnabled,") // Computed properties builder.append("showQuickSettingsRatIcon=${showQuickSettingsRatIcon()},") @@ -181,6 +204,11 @@ internal class MobileState( if (roaming != other.roaming) return false if (dataState != other.dataState) return false if (defaultDataOff != other.defaultDataOff) return false + if (imsRegistered != other.imsRegistered) return false + if (voiceCapable != other.voiceCapable) return false + if (videoCapable != other.videoCapable) return false + if (mobileDataEnabled != other.mobileDataEnabled) return false + if (roamingDataEnabled != other.roamingDataEnabled) return false if (telephonyDisplayInfo != other.telephonyDisplayInfo) return false if (serviceState != other.serviceState) return false if (signalStrength != other.signalStrength) return false @@ -202,6 +230,11 @@ internal class MobileState( result = 31 * result + roaming.hashCode() result = 31 * result + dataState result = 31 * result + defaultDataOff.hashCode() + result = 31 * result + imsRegistered.hashCode() + result = 31 * result + voiceCapable.hashCode() + result = 31 * result + videoCapable.hashCode() + result = 31 * result + mobileDataEnabled.hashCode() + result = 31 * result + roamingDataEnabled.hashCode() result = 31 * result + telephonyDisplayInfo.hashCode() result = 31 * result + (serviceState?.hashCode() ?: 0) result = 31 * result + (signalStrength?.hashCode() ?: 0) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java index 631a1ca3dcec..35701534ae2a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/NetworkControllerImpl.java @@ -40,6 +40,7 @@ import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.os.Looper; +import android.os.SystemProperties; import android.provider.Settings; import android.telephony.CarrierConfigManager; import android.telephony.CellSignalStrength; @@ -58,6 +59,7 @@ import androidx.annotation.NonNull; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.telephony.TelephonyIntents; import com.android.settingslib.Utils; import com.android.settingslib.mobile.MobileMappings.Config; import com.android.settingslib.mobile.MobileStatusTracker.SubscriptionDefaults; @@ -82,6 +84,7 @@ import com.android.systemui.statusbar.policy.DataSaverControllerImpl; import com.android.systemui.statusbar.policy.DeviceProvisionedController; import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener; import com.android.systemui.statusbar.policy.EncryptionHelper; +import com.android.systemui.statusbar.policy.FiveGServiceClient; import com.android.systemui.telephony.TelephonyListenerManager; import com.android.systemui.util.CarrierConfigTracker; @@ -202,6 +205,9 @@ public class NetworkControllerImpl extends BroadcastReceiver private InternetDialogFactory mInternetDialogFactory; private Handler mMainHandler; + @VisibleForTesting + FiveGServiceClient mFiveGServiceClient; + private ConfigurationController.ConfigurationListener mConfigurationListener = new ConfigurationController.ConfigurationListener() { @Override @@ -361,6 +367,8 @@ public class NetworkControllerImpl extends BroadcastReceiver mWifiManager.registerScanResultsCallback(mReceiverHandler::post, scanResultsCallback); } + mFiveGServiceClient = FiveGServiceClient.getInstance(context); + NetworkCallback callback = new NetworkCallback(NetworkCallback.FLAG_INCLUDE_LOCATION_INFO){ private Network mLastNetwork; @@ -476,6 +484,7 @@ public class NetworkControllerImpl extends BroadcastReceiver for (int i = 0; i < mMobileSignalControllers.size(); i++) { MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i); mobileSignalController.registerListener(); + mobileSignalController.registerFiveGStateListener(mFiveGServiceClient); } if (mSubscriptionListener == null) { mSubscriptionListener = new SubListener(mBgLooper); @@ -497,6 +506,7 @@ public class NetworkControllerImpl extends BroadcastReceiver if (InternetDialogUtil.isProviderModelEnabled(mContext)) { filter.addAction(Settings.Panel.ACTION_INTERNET_CONNECTIVITY); } + filter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); mBroadcastDispatcher.registerReceiverWithHandler(this, filter, mReceiverHandler); mListening = true; @@ -530,11 +540,17 @@ public class NetworkControllerImpl extends BroadcastReceiver for (int i = 0; i < mMobileSignalControllers.size(); i++) { MobileSignalController mobileSignalController = mMobileSignalControllers.valueAt(i); mobileSignalController.unregisterListener(); + mobileSignalController.unregisterFiveGStateListener(mFiveGServiceClient); } mSubscriptionManager.removeOnSubscriptionsChangedListener(mSubscriptionListener); mBroadcastDispatcher.unregisterReceiver(this); } + @VisibleForTesting + public FiveGServiceClient getFiveGServiceClient() { + return mFiveGServiceClient; + } + public int getConnectedWifiLevel() { return mWifiSignalController.getState().level; } @@ -968,6 +984,7 @@ public class NetworkControllerImpl extends BroadcastReceiver } if (mListening) { controller.registerListener(); + controller.registerFiveGStateListener(mFiveGServiceClient); } } } @@ -978,6 +995,7 @@ public class NetworkControllerImpl extends BroadcastReceiver mDefaultSignalController = null; } cachedControllers.get(key).unregisterListener(); + cachedControllers.get(key).unregisterFiveGStateListener(mFiveGServiceClient); } } mCallbackHandler.setSubs(subscriptions); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/SignalCallback.kt b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/SignalCallback.kt index 599beecb0e00..eb974219050e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/SignalCallback.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/SignalCallback.kt @@ -146,6 +146,7 @@ data class MobileDataIndicators( @JvmField val qsType: Int, @JvmField val activityIn: Boolean, @JvmField val activityOut: Boolean, + @JvmField val volteIcon: Int, @JvmField val typeContentDescription: CharSequence?, @JvmField val typeContentDescriptionHtml: CharSequence?, @JvmField val qsDescription: CharSequence?, @@ -161,6 +162,7 @@ data class MobileDataIndicators( .append(",qsType=").append(qsType) .append(",activityIn=").append(activityIn) .append(",activityOut=").append(activityOut) + .append(",volteIcon=").append(volteIcon) .append(",typeContentDescription=").append(typeContentDescription) .append(",typeContentDescriptionHtml=").append(typeContentDescriptionHtml) .append(",description=").append(qsDescription) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiIcons.java index 3c449ad270ef..4705c494f8e3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiIcons.java @@ -39,6 +39,54 @@ public class WifiIcons { R.drawable.ic_no_internet_wifi_signal_4 }; + static final int[] WIFI_4_FULL_ICONS = { + com.android.internal.R.drawable.ic_wifi_4_signal_0, + com.android.internal.R.drawable.ic_wifi_4_signal_1, + com.android.internal.R.drawable.ic_wifi_4_signal_2, + com.android.internal.R.drawable.ic_wifi_4_signal_3, + com.android.internal.R.drawable.ic_wifi_4_signal_4 + }; + + private static final int[] WIFI_4_NO_INTERNET_ICONS = { + R.drawable.ic_qs_wifi_4_0, + R.drawable.ic_qs_wifi_4_1, + R.drawable.ic_qs_wifi_4_2, + R.drawable.ic_qs_wifi_4_3, + R.drawable.ic_qs_wifi_4_4 + }; + + static final int[] WIFI_5_FULL_ICONS = { + com.android.internal.R.drawable.ic_wifi_5_signal_0, + com.android.internal.R.drawable.ic_wifi_5_signal_1, + com.android.internal.R.drawable.ic_wifi_5_signal_2, + com.android.internal.R.drawable.ic_wifi_5_signal_3, + com.android.internal.R.drawable.ic_wifi_5_signal_4 + }; + + private static final int[] WIFI_5_NO_INTERNET_ICONS = { + R.drawable.ic_qs_wifi_5_0, + R.drawable.ic_qs_wifi_5_1, + R.drawable.ic_qs_wifi_5_2, + R.drawable.ic_qs_wifi_5_3, + R.drawable.ic_qs_wifi_5_4 + }; + + static final int[] WIFI_6_FULL_ICONS = { + com.android.internal.R.drawable.ic_wifi_6_signal_0, + com.android.internal.R.drawable.ic_wifi_6_signal_1, + com.android.internal.R.drawable.ic_wifi_6_signal_2, + com.android.internal.R.drawable.ic_wifi_6_signal_3, + com.android.internal.R.drawable.ic_wifi_6_signal_4 + }; + + private static final int[] WIFI_6_NO_INTERNET_ICONS = { + R.drawable.ic_qs_wifi_6_0, + R.drawable.ic_qs_wifi_6_1, + R.drawable.ic_qs_wifi_6_2, + R.drawable.ic_qs_wifi_6_3, + R.drawable.ic_qs_wifi_6_4 + }; + public static final int[][] QS_WIFI_SIGNAL_STRENGTH = { WIFI_NO_INTERNET_ICONS, WIFI_FULL_ICONS @@ -46,6 +94,27 @@ public class WifiIcons { static final int[][] WIFI_SIGNAL_STRENGTH = QS_WIFI_SIGNAL_STRENGTH; + public static final int[][] QS_WIFI_4_SIGNAL_STRENGTH = { + WIFI_4_NO_INTERNET_ICONS, + WIFI_4_FULL_ICONS + }; + + static final int[][] WIFI_4_SIGNAL_STRENGTH = QS_WIFI_4_SIGNAL_STRENGTH; + + public static final int[][] QS_WIFI_5_SIGNAL_STRENGTH = { + WIFI_5_NO_INTERNET_ICONS, + WIFI_5_FULL_ICONS + }; + + static final int[][] WIFI_5_SIGNAL_STRENGTH = QS_WIFI_5_SIGNAL_STRENGTH; + + public static final int[][] QS_WIFI_6_SIGNAL_STRENGTH = { + WIFI_6_NO_INTERNET_ICONS, + WIFI_6_FULL_ICONS + }; + + static final int[][] WIFI_6_SIGNAL_STRENGTH = QS_WIFI_6_SIGNAL_STRENGTH; + public static final int QS_WIFI_DISABLED = com.android.internal.R.drawable.ic_wifi_signal_0; public static final int QS_WIFI_NO_NETWORK = com.android.internal.R.drawable.ic_wifi_signal_0; static final int WIFI_NO_NETWORK = QS_WIFI_NO_NETWORK; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java index ff9d919dda13..993a3a902d3d 100644..100755 --- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiSignalController.java @@ -28,6 +28,7 @@ import android.net.wifi.WifiManager; import android.text.Html; import com.android.internal.annotations.VisibleForTesting; +import com.android.settingslib.AccessibilityContentDescriptions; import com.android.settingslib.SignalIcon.IconGroup; import com.android.settingslib.SignalIcon.MobileIconGroup; import com.android.settingslib.graph.SignalDrawable; @@ -47,6 +48,11 @@ public class WifiSignalController extends SignalController<WifiState, IconGroup> private final WifiManager mWifiManager; private final boolean mProviderModelSetting; + private final IconGroup mDefaultWifiIconGroup; + private final IconGroup mWifi4IconGroup; + private final IconGroup mWifi5IconGroup; + private final IconGroup mWifi6IconGroup; + public WifiSignalController( Context context, boolean hasMobileDataFeature, @@ -67,8 +73,58 @@ public class WifiSignalController extends SignalController<WifiState, IconGroup> wifiManager.registerTrafficStateCallback(context.getMainExecutor(), new WifiTrafficStateCallback()); } - mCurrentState.iconGroup = mLastState.iconGroup = mUnmergedWifiIconGroup; + + mDefaultWifiIconGroup = new IconGroup( + "Wi-Fi Icons", + WifiIcons.WIFI_SIGNAL_STRENGTH, + WifiIcons.QS_WIFI_SIGNAL_STRENGTH, + AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH, + WifiIcons.WIFI_NO_NETWORK, + WifiIcons.QS_WIFI_NO_NETWORK, + WifiIcons.WIFI_NO_NETWORK, + WifiIcons.QS_WIFI_NO_NETWORK, + AccessibilityContentDescriptions.WIFI_NO_CONNECTION + ); + + mWifi4IconGroup = new IconGroup( + "Wi-Fi 4 Icons", + WifiIcons.WIFI_4_SIGNAL_STRENGTH, + WifiIcons.QS_WIFI_4_SIGNAL_STRENGTH, + AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH, + WifiIcons.WIFI_NO_NETWORK, + WifiIcons.QS_WIFI_NO_NETWORK, + WifiIcons.WIFI_NO_NETWORK, + WifiIcons.QS_WIFI_NO_NETWORK, + AccessibilityContentDescriptions.WIFI_NO_CONNECTION + ); + + mWifi5IconGroup = new IconGroup( + "Wi-Fi 5 Icons", + WifiIcons.WIFI_5_SIGNAL_STRENGTH, + WifiIcons.QS_WIFI_5_SIGNAL_STRENGTH, + AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH, + WifiIcons.WIFI_NO_NETWORK, + WifiIcons.QS_WIFI_NO_NETWORK, + WifiIcons.WIFI_NO_NETWORK, + WifiIcons.QS_WIFI_NO_NETWORK, + AccessibilityContentDescriptions.WIFI_NO_CONNECTION + ); + + mWifi6IconGroup = new IconGroup( + "Wi-Fi 6 Icons", + WifiIcons.WIFI_6_SIGNAL_STRENGTH, + WifiIcons.QS_WIFI_6_SIGNAL_STRENGTH, + AccessibilityContentDescriptions.WIFI_CONNECTION_STRENGTH, + WifiIcons.WIFI_NO_NETWORK, + WifiIcons.QS_WIFI_NO_NETWORK, + WifiIcons.WIFI_NO_NETWORK, + WifiIcons.QS_WIFI_NO_NETWORK, + AccessibilityContentDescriptions.WIFI_NO_CONNECTION + ); + + mCurrentState.iconGroup = mLastState.iconGroup = mDefaultWifiIconGroup; mProviderModelSetting = featureFlags.isProviderModelSettingEnabled(); + } @Override @@ -154,6 +210,8 @@ public class WifiSignalController extends SignalController<WifiState, IconGroup> new IconState(sbVisible, getCurrentIconIdForCarrierWifi(), contentDescription); int typeIcon = sbVisible ? icons.dataType : 0; int qsTypeIcon = 0; + // TODO(b/178561525) Populate volteIcon value as necessary + int volteIcon = 0; IconState qsIcon = null; if (sbVisible) { qsTypeIcon = icons.dataType; @@ -164,7 +222,7 @@ public class WifiSignalController extends SignalController<WifiState, IconGroup> mNetworkController.getNetworkNameForCarrierWiFi(mCurrentState.subId); MobileDataIndicators mobileDataIndicators = new MobileDataIndicators( statusIcon, qsIcon, typeIcon, qsTypeIcon, - mCurrentState.activityIn, mCurrentState.activityOut, dataContentDescription, + mCurrentState.activityIn, mCurrentState.activityOut, volteIcon, dataContentDescription, dataContentDescriptionHtml, description, mCurrentState.subId, /* roaming= */ false, /* showTriangle= */ true ); @@ -190,6 +248,19 @@ public class WifiSignalController extends SignalController<WifiState, IconGroup> return getCurrentIconIdForCarrierWifi(); } + + private void updateIconGroup() { + if (mCurrentState.wifiStandard == 4) { + mCurrentState.iconGroup = mWifi4IconGroup; + } else if (mCurrentState.wifiStandard == 5) { + mCurrentState.iconGroup = mCurrentState.isReady ? mWifi6IconGroup : mWifi5IconGroup; + } else if (mCurrentState.wifiStandard == 6) { + mCurrentState.iconGroup = mWifi6IconGroup; + } else { + mCurrentState.iconGroup = mDefaultWifiIconGroup; + } + + } /** * Fetches wifi initial state replacing the initial sticky broadcast. */ @@ -224,9 +295,10 @@ public class WifiSignalController extends SignalController<WifiState, IconGroup> mCurrentState.statusLabel = mWifiTracker.statusLabel; mCurrentState.isCarrierMerged = mWifiTracker.isCarrierMerged; mCurrentState.subId = mWifiTracker.subId; - mCurrentState.iconGroup = - mCurrentState.isCarrierMerged ? mCarrierMergedWifiIconGroup - : mUnmergedWifiIconGroup; + mCurrentState.wifiStandard = mWifiTracker.wifiStandard; + mCurrentState.isReady = (mWifiTracker.vhtMax8SpatialStreamsSupport + && mWifiTracker.he8ssCapableAp); + updateIconGroup(); } void notifyWifiLevelChangeIfNecessary(int level) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiState.kt b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiState.kt index ac15f78191f6..6df8d001d2bc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiState.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiState.kt @@ -24,7 +24,10 @@ internal class WifiState( @JvmField var isDefault: Boolean = false, @JvmField var statusLabel: String? = null, @JvmField var isCarrierMerged: Boolean = false, - @JvmField var subId: Int = 0 + @JvmField var subId: Int = 0, + @JvmField var wifiStandard: Int = 0, + @JvmField var isReady: Boolean = false + ) : ConnectivityState() { public override fun copyFrom(s: ConnectivityState) { @@ -36,11 +39,15 @@ internal class WifiState( statusLabel = state.statusLabel isCarrierMerged = state.isCarrierMerged subId = state.subId + wifiStandard = state.wifiStandard + isReady = state.isReady } override fun toString(builder: StringBuilder) { super.toString(builder) builder.append(",ssid=").append(ssid) + .append(",wifiStandard=").append(wifiStandard) + .append(",isReady=").append(isReady) .append(",isTransient=").append(isTransient) .append(",isDefault=").append(isDefault) .append(",statusLabel=").append(statusLabel) @@ -56,6 +63,8 @@ internal class WifiState( other as WifiState if (ssid != other.ssid) return false + if (wifiStandard != other.wifiStandard) return false + if (isReady != other.isReady) return false if (isTransient != other.isTransient) return false if (isDefault != other.isDefault) return false if (statusLabel != other.statusLabel) return false diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java index c75cd782c3e2..7459fe69ae3a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationMediaTemplateViewWrapper.java @@ -27,6 +27,7 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow */ public class NotificationMediaTemplateViewWrapper extends NotificationTemplateViewWrapper { + private static final long PROGRESS_UPDATE_INTERVAL = 1000; // 1s private View mActions; protected NotificationMediaTemplateViewWrapper(Context ctx, View view, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java index a88a3b6392c2..1c688975fef5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeServiceHost.java @@ -196,6 +196,8 @@ public final class DozeServiceHost implements DozeHost { updateDozing(); mDozeLog.traceDozing(mStatusBarStateController.isDozing()); mStatusBar.updateIsKeyguard(); + }else{ + mDozingRequested = true; } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java index aeef8cd433ab..1330f87f244e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -75,6 +75,7 @@ import androidx.annotation.Nullable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.widget.LockPatternUtils; +import com.android.keyguard.EmergencyCarrierArea; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.settingslib.Utils; @@ -136,6 +137,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL private static final int DOZE_ANIMATION_STAGGER_DELAY = 48; private static final int DOZE_ANIMATION_ELEMENT_DURATION = 250; + private EmergencyCarrierArea mEmergencyCarrierArea; + // TODO(b/179494051): May no longer be needed private final boolean mShowLeftAffordance; private final boolean mShowCameraAffordance; @@ -302,6 +305,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL super.onFinishInflate(); mPreviewInflater = new PreviewInflater(mContext, new LockPatternUtils(mContext), new ActivityIntentHelper(mContext)); + mEmergencyCarrierArea = (EmergencyCarrierArea) findViewById(R.id.keyguard_selector_fade_container); mOverlayContainer = findViewById(R.id.overlay_container); mRightAffordanceView = findViewById(R.id.camera_button); mLeftAffordanceView = findViewById(R.id.left_button); @@ -915,8 +919,10 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL if (dozing) { mOverlayContainer.setVisibility(INVISIBLE); + mEmergencyCarrierArea.setVisibility(INVISIBLE); } else { mOverlayContainer.setVisibility(VISIBLE); + mEmergencyCarrierArea.setVisibility(VISIBLE); if (animate) { startFinishDozeAnimation(); } @@ -952,6 +958,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL mIndicationArea.setAlpha(alpha); mWalletButton.setAlpha(alpha); mControlsButton.setAlpha(alpha); + mEmergencyCarrierArea.setAlpha(alpha); } private class DefaultLeftButton implements IntentButton { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java index cc4f901668ab..cc4f901668ab 100644..100755 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java 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 7432fa98051d..5f596f8afb7e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -98,6 +98,8 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.policy.ScreenDecorationsUtils; import com.android.internal.policy.SystemBarUtils; import com.android.internal.util.LatencyTracker; +import com.android.keyguard.EmergencyButton; +import com.android.keyguard.EmergencyButtonController; import com.android.keyguard.KeyguardStatusView; import com.android.keyguard.KeyguardStatusViewController; import com.android.keyguard.KeyguardUnfoldTransition; @@ -331,6 +333,9 @@ public class NotificationPanelViewController extends PanelViewController { private float mQuickQsOffsetHeight; private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController; + private final EmergencyButtonController.Factory mEmergencyButtonControllerFactory; + private EmergencyButtonController mEmergencyButtonController; + private int mTrackingPointer; private VelocityTracker mQsVelocityTracker; private boolean mQsTracking; @@ -713,7 +718,8 @@ public class NotificationPanelViewController extends PanelViewController { NotificationRemoteInputManager remoteInputManager, Optional<SysUIUnfoldComponent> unfoldComponent, ControlsComponent controlsComponent, - FeatureFlags featureFlags) { + FeatureFlags featureFlags, + EmergencyButtonController.Factory emergencyButtonControllerFactory) { super(view, falsingManager, dozeLog, @@ -751,6 +757,7 @@ public class NotificationPanelViewController extends PanelViewController { mContentResolver = contentResolver; mKeyguardQsUserSwitchComponentFactory = keyguardQsUserSwitchComponentFactory; mKeyguardUserSwitcherComponentFactory = keyguardUserSwitcherComponentFactory; + mEmergencyButtonControllerFactory = emergencyButtonControllerFactory; mQSDetailDisplayer = qsDetailDisplayer; mFragmentService = fragmentService; mSettingsChangeObserver = new SettingsChangeObserver(handler); @@ -1178,6 +1185,10 @@ public class NotificationPanelViewController extends PanelViewController { mKeyguardBottomArea.setFalsingManager(mFalsingManager); mKeyguardBottomArea.initWallet(mQuickAccessWalletController); mKeyguardBottomArea.initControls(mControlsComponent); + EmergencyButton emergencyButton = + mKeyguardBottomArea.findViewById(R.id.emergency_call_button); + mEmergencyButtonController = mEmergencyButtonControllerFactory.create(emergencyButton); + mEmergencyButtonController.init(); } private void updateMaxDisplayedNotifications(boolean recompute) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java index 040820e90790..956ac31b3627 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java @@ -62,6 +62,7 @@ import com.android.systemui.statusbar.notification.stack.AmbientState; import com.android.systemui.statusbar.phone.LockscreenGestureLogger.LockscreenUiEvent; import com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManager; import com.android.systemui.statusbar.policy.KeyguardStateController; +import android.util.BoostFramework; import com.android.wm.shell.animation.FlingAnimationUtils; import java.io.FileDescriptor; @@ -148,6 +149,11 @@ public abstract class PanelViewController { private final VibratorHelper mVibratorHelper; /** + * For PanelView fling perflock call + */ + private BoostFramework mPerf = null; + + /** * Whether an instant expand request is currently pending and we are just waiting for layout. */ private boolean mInstantExpanding; @@ -277,6 +283,8 @@ public abstract class PanelViewController { mVibratorHelper = vibratorHelper; mVibrateOnOpening = mResources.getBoolean(R.bool.config_vibrateOnIconAnimation); mStatusBarTouchableRegionManager = statusBarTouchableRegionManager; + + mPerf = new BoostFramework(); } protected void loadDimens() { @@ -629,6 +637,10 @@ public abstract class PanelViewController { animator.setDuration(mFixedDuration); } } + if (mPerf != null) { + String currentPackage = mView.getContext().getPackageName(); + mPerf.perfHint(BoostFramework.VENDOR_HINT_SCROLL_BOOST, currentPackage, -1, BoostFramework.Scroll.PANEL_VIEW); + } animator.addListener(new AnimatorListenerAdapter() { private boolean mCancelled; @@ -639,11 +651,17 @@ public abstract class PanelViewController { @Override public void onAnimationCancel(Animator animation) { + if (mPerf != null) { + mPerf.perfLockRelease(); + } mCancelled = true; } @Override public void onAnimationEnd(Animator animation) { + if (mPerf != null) { + mPerf.perfLockRelease(); + } if (shouldSpringBack && !mCancelled) { // After the shade is flinged open to an overscrolled state, spring back // the shade by reducing section padding to 0. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java index d19ed28bd823..b3917d03b189 100644..100755 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -29,6 +29,8 @@ import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.res.Resources; import android.media.AudioManager; +import android.net.wifi.ScanResult; +import android.net.wifi.WifiManager; import android.os.Handler; import android.os.RemoteException; import android.os.UserHandle; @@ -281,11 +283,6 @@ public class PhoneStatusBarPolicy mIconController.setIcon(mSlotCast, R.drawable.stat_sys_cast, null); mIconController.setIconVisibility(mSlotCast, false); - // hotspot - mIconController.setIcon(mSlotHotspot, R.drawable.stat_sys_hotspot, - mResources.getString(R.string.accessibility_status_bar_hotspot)); - mIconController.setIconVisibility(mSlotHotspot, mHotspot.isHotspotEnabled()); - // managed profile mIconController.setIcon(mSlotManagedProfile, R.drawable.stat_sys_managed_profile_status, mResources.getString(R.string.accessibility_managed_profile)); @@ -561,6 +558,11 @@ public class PhoneStatusBarPolicy public void onHotspotChanged(boolean enabled, int numDevices) { mIconController.setIconVisibility(mSlotHotspot, enabled); } + @Override + public void onHotspotChanged(boolean enabled, int numDevices, int standard) { + updateHotspotIcon(standard); + mIconController.setIconVisibility(mSlotHotspot, enabled); + } }; private final CastController.Callback mCastCallback = new CastController.Callback() { @@ -789,4 +791,20 @@ public class PhoneStatusBarPolicy if (DEBUG) Log.d(TAG, "screenrecord: hiding icon"); mHandler.post(() -> mIconController.setIconVisibility(mSlotScreenRecord, false)); } + + private void updateHotspotIcon(int standard) { + if (standard == ScanResult.WIFI_STANDARD_11AX) { + mIconController.setIcon(mSlotHotspot, R.drawable.stat_sys_wifi_6_hotspot, + mResources.getString(R.string.accessibility_status_bar_hotspot)); + } else if (standard == ScanResult.WIFI_STANDARD_11AC) { + mIconController.setIcon(mSlotHotspot, R.drawable.stat_sys_wifi_5_hotspot, + mResources.getString(R.string.accessibility_status_bar_hotspot)); + } else if (standard == ScanResult.WIFI_STANDARD_11N) { + mIconController.setIcon(mSlotHotspot, R.drawable.stat_sys_wifi_4_hotspot, + mResources.getString(R.string.accessibility_status_bar_hotspot)); + } else { + mIconController.setIcon(mSlotHotspot, R.drawable.stat_sys_hotspot, + mResources.getString(R.string.accessibility_status_bar_hotspot)); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index a6fb317cdfc8..50f5b216bfd6 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -3638,6 +3638,7 @@ public class StatusBar extends SystemUI implements @Override public void onScreenTurnedOff() { + mDozeServiceHost.updateDozing(); mFalsingCollector.onScreenOff(); mScrimController.onScreenTurnedOff(); updateIsKeyguard(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index fe96a5b9979f..f31e7264841d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -1079,12 +1079,12 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb */ protected boolean getLastNavBarVisible() { boolean keyguardShowing = mLastShowing && !mLastOccluded; - boolean hideWhileDozing = mLastDozing && mLastBiometricMode != MODE_WAKE_AND_UNLOCK_PULSING; - boolean keyguardWithGestureNav = (keyguardShowing && !mLastDozing - || mLastPulsing && !mLastIsDocked) && mLastGesturalNav; - return (!keyguardShowing && !hideWhileDozing || mLastBouncerShowing - || mLastRemoteInputActive || keyguardWithGestureNav - || mLastGlobalActionsVisible); + boolean hideWhileDozing = mLastDozing && mLastBiometricMode != MODE_WAKE_AND_UNLOCK_PULSING; + boolean keyguardWithGestureNav = (keyguardShowing && !mLastDozing + || mLastPulsing && !mLastIsDocked) && mLastGesturalNav; + return (!keyguardShowing && !hideWhileDozing || mLastBouncerShowing + || mLastRemoteInputActive || keyguardWithGestureNav + || mLastGlobalActionsVisible); } public boolean shouldDismissOnMenuPressed() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java index 360cb571c926..67850bc5fe04 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java @@ -274,6 +274,7 @@ public class StatusBarSignalPolicy implements SignalCallback, state.roaming = indicators.roaming; state.activityIn = indicators.activityIn && mActivityEnabled; state.activityOut = indicators.activityOut && mActivityEnabled; + state.volteId = indicators.volteIcon; if (DEBUG) { Log.d(TAG, "MobileIconStates: " @@ -607,6 +608,7 @@ public class StatusBarSignalPolicy implements SignalCallback, public boolean roaming; public boolean needsLeadingPadding; public CharSequence typeContentDescription; + public int volteId; private MobileIconState(int subId) { super(); @@ -628,7 +630,8 @@ public class StatusBarSignalPolicy implements SignalCallback, && showTriangle == that.showTriangle && roaming == that.roaming && needsLeadingPadding == that.needsLeadingPadding - && Objects.equals(typeContentDescription, that.typeContentDescription); + && Objects.equals(typeContentDescription, that.typeContentDescription) + && volteId == that.volteId; } @Override @@ -654,6 +657,7 @@ public class StatusBarSignalPolicy implements SignalCallback, other.roaming = roaming; other.needsLeadingPadding = needsLeadingPadding; other.typeContentDescription = typeContentDescription; + other.volteId = volteId; } private static List<MobileIconState> copyStates(List<MobileIconState> inStates) { @@ -670,7 +674,8 @@ public class StatusBarSignalPolicy implements SignalCallback, @Override public String toString() { return "MobileIconState(subId=" + subId + ", strengthId=" + strengthId + ", showTriangle=" + showTriangle + ", roaming=" + roaming - + ", typeId=" + typeId + ", visible=" + visible + ")"; + + ", typeId=" + typeId + ", volteId=" + volteId + + ", visible=" + visible + ")"; } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java new file mode 100644 index 000000000000..dea282befd64 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FiveGServiceClient.java @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package com.android.systemui.statusbar.policy; + +import android.content.ComponentName; +import android.content.Context; +import android.content.ServiceConnection; +import android.net.Uri; +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.os.DeadObjectException; +import android.os.RemoteException; +import android.util.Log; +import android.util.SparseArray; + +import com.google.android.collect.Lists; +import com.android.internal.annotations.VisibleForTesting; + +import java.lang.Exception; +import java.util.ArrayList; +import java.lang.ref.WeakReference; + +import com.android.keyguard.KeyguardUpdateMonitorCallback; +import com.android.settingslib.mobile.TelephonyIcons; +import com.android.settingslib.SignalIcon.MobileIconGroup; +import com.android.systemui.R; + +import com.qti.extphone.Client; +import com.qti.extphone.ExtTelephonyManager; +import com.qti.extphone.IExtPhoneCallback; +import com.qti.extphone.ExtPhoneCallbackBase; +import com.qti.extphone.NrIconType; +import com.qti.extphone.Status; +import com.qti.extphone.ServiceCallback; +import com.qti.extphone.Token; + +public class FiveGServiceClient { + private static final String TAG = "FiveGServiceClient"; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG)||true; + private static final int MESSAGE_REBIND = 1024; + private static final int MESSAGE_REINIT = MESSAGE_REBIND+1; + private static final int MESSAGE_NOTIFIY_MONITOR_CALLBACK = MESSAGE_REBIND+2; + private static final int MAX_RETRY = 4; + private static final int DELAY_MILLISECOND = 3000; + private static final int DELAY_INCREMENT = 2000; + + private static FiveGServiceClient sInstance; + private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>> + mKeyguardUpdateMonitorCallbacks = Lists.newArrayList(); + @VisibleForTesting + final SparseArray<IFiveGStateListener> mStatesListeners = new SparseArray<>(); + private final SparseArray<FiveGServiceState> mCurrentServiceStates = new SparseArray<>(); + private final SparseArray<FiveGServiceState> mLastServiceStates = new SparseArray<>(); + + private Context mContext; + private boolean mServiceConnected; + private String mPackageName; + private Client mClient; + private int mInitRetryTimes = 0; + private ExtTelephonyManager mExtTelephonyManager; + private boolean mIsConnectInProgress = false; + + public static class FiveGServiceState{ + private int mNrIconType; + private MobileIconGroup mIconGroup; + + public FiveGServiceState(){ + mNrIconType = NrIconType.INVALID; + mIconGroup = TelephonyIcons.UNKNOWN; + } + + public boolean isNrIconTypeValid() { + return mNrIconType != NrIconType.INVALID && mNrIconType != NrIconType.TYPE_NONE; + } + + @VisibleForTesting + public MobileIconGroup getIconGroup() { + return mIconGroup; + } + + @VisibleForTesting + int getNrIconType() { + return mNrIconType; + } + + public void copyFrom(FiveGServiceState state) { + this.mIconGroup = state.mIconGroup; + this.mNrIconType = state.mNrIconType; + } + + public boolean equals(FiveGServiceState state) { + return this.mIconGroup == state.mIconGroup + && this.mNrIconType == state.mNrIconType; + } + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("mNrIconType=").append(mNrIconType).append(", "). + append("mIconGroup=").append(mIconGroup); + + return builder.toString(); + } + } + + public FiveGServiceClient(Context context) { + mContext = context; + mPackageName = mContext.getPackageName(); + if (mExtTelephonyManager == null) { + mExtTelephonyManager = ExtTelephonyManager.getInstance(mContext); + } + } + + public static FiveGServiceClient getInstance(Context context) { + if ( sInstance == null ) { + sInstance = new FiveGServiceClient(context); + } + + return sInstance; + } + + public void registerCallback(KeyguardUpdateMonitorCallback callback) { + mKeyguardUpdateMonitorCallbacks.add( + new WeakReference<KeyguardUpdateMonitorCallback>(callback)); + } + + public void registerListener(int phoneId, IFiveGStateListener listener) { + Log.d(TAG, "registerListener phoneId=" + phoneId); + resetState(phoneId); + mStatesListeners.put(phoneId, listener); + if ( !isServiceConnected() ) { + connectService(); + }else{ + initFiveGServiceState(phoneId); + } + } + + private void resetState(int phoneId) { + Log.d(TAG, "resetState phoneId=" + phoneId); + FiveGServiceState currentState = getCurrentServiceState(phoneId); + currentState.mNrIconType = NrIconType.INVALID; + currentState.mIconGroup = TelephonyIcons.UNKNOWN; + + FiveGServiceState lastState = getLastServiceState(phoneId); + lastState.mNrIconType = NrIconType.INVALID; + lastState.mIconGroup = TelephonyIcons.UNKNOWN; + } + + public void unregisterListener(int phoneId) { + Log.d(TAG, "unregisterListener phoneId=" + phoneId); + mStatesListeners.remove(phoneId); + mCurrentServiceStates.remove(phoneId); + mLastServiceStates.remove(phoneId); + } + + public boolean isServiceConnected() { + return mServiceConnected; + } + + private void connectService() { + if (!isServiceConnected() && !mIsConnectInProgress) { + mIsConnectInProgress = true; + Log.d(TAG, "Connect to ExtTelephony bound service..."); + mExtTelephonyManager.connectService(mServiceCallback); + } + } + + private ServiceCallback mServiceCallback = new ServiceCallback() { + @Override + public void onConnected() { + Log.d(TAG, "ExtTelephony Service connected"); + mServiceConnected = true; + mIsConnectInProgress = false; + mClient = mExtTelephonyManager.registerCallback(mPackageName, mCallback); + initFiveGServiceState(); + Log.d(TAG, "Client = " + mClient); + } + @Override + public void onDisconnected() { + Log.d(TAG, "ExtTelephony Service disconnected..."); + if (mServiceConnected) { + mExtTelephonyManager.unRegisterCallback(mCallback); + } + mServiceConnected = false; + mClient = null; + mIsConnectInProgress = false; + mHandler.sendEmptyMessageDelayed(MESSAGE_REBIND, + DELAY_MILLISECOND + DELAY_INCREMENT); + } + }; + + @VisibleForTesting + public FiveGServiceState getCurrentServiceState(int phoneId) { + return getServiceState(phoneId, mCurrentServiceStates); + } + + private FiveGServiceState getLastServiceState(int phoneId) { + return getServiceState(phoneId, mLastServiceStates); + } + + private static FiveGServiceState getServiceState(int key, + SparseArray<FiveGServiceState> array) { + FiveGServiceState state = array.get(key); + if ( state == null ) { + state = new FiveGServiceState(); + array.put(key, state); + } + return state; + } + + private void notifyListenersIfNecessary(int phoneId) { + FiveGServiceState currentState = getCurrentServiceState(phoneId); + FiveGServiceState lastState = getLastServiceState(phoneId); + if ( !currentState.equals(lastState) ) { + + if ( DEBUG ) { + Log.d(TAG, "phoneId(" + phoneId + ") Change in state from " + lastState + " \n"+ + "\tto " + currentState); + + } + + lastState.copyFrom(currentState); + IFiveGStateListener listener = mStatesListeners.get(phoneId); + if (listener != null) { + listener.onStateChanged(currentState); + } + + mHandler.sendEmptyMessage(MESSAGE_NOTIFIY_MONITOR_CALLBACK); + + } + } + + private void initFiveGServiceState() { + Log.d(TAG, "initFiveGServiceState size=" + mStatesListeners.size()); + for( int i=0; i < mStatesListeners.size(); ++i ) { + int phoneId = mStatesListeners.keyAt(i); + initFiveGServiceState(phoneId); + } + } + + private void initFiveGServiceState(int phoneId) { + Log.d(TAG, "mServiceConnected=" + mServiceConnected + " mClient=" + mClient); + if ( mServiceConnected && mClient != null) { + Log.d(TAG, "query 5G service state for phoneId " + phoneId); + try { + Token token = mExtTelephonyManager.queryNrIconType(phoneId, mClient); + Log.d(TAG, "queryNrIconType result:" + token); + } catch (Exception e) { + Log.d(TAG, "initFiveGServiceState: Exception = " + e); + if ( mInitRetryTimes < MAX_RETRY && !mHandler.hasMessages(MESSAGE_REINIT) ) { + mHandler.sendEmptyMessageDelayed(MESSAGE_REINIT, + DELAY_MILLISECOND + mInitRetryTimes*DELAY_INCREMENT); + mInitRetryTimes +=1; + } + } + } + } + + @VisibleForTesting + void update5GIcon(FiveGServiceState state,int phoneId) { + state.mIconGroup = getNrIconGroup(state.mNrIconType, phoneId); + } + + private MobileIconGroup getNrIconGroup(int nrIconType , int phoneId) { + MobileIconGroup iconGroup = TelephonyIcons.UNKNOWN; + switch (nrIconType){ + case NrIconType.TYPE_5G_BASIC: + iconGroup = TelephonyIcons.FIVE_G_BASIC; + break; + case NrIconType.TYPE_5G_UWB: + iconGroup = TelephonyIcons.FIVE_G_UWB; + break; + } + return iconGroup; + } + + private void notifyMonitorCallback() { + for (int i = 0; i < mKeyguardUpdateMonitorCallbacks.size(); i++) { + KeyguardUpdateMonitorCallback cb = mKeyguardUpdateMonitorCallbacks.get(i).get(); + if (cb != null) { + cb.onRefreshCarrierInfo(); + } + } + } + + private Handler mHandler = new Handler() { + public void handleMessage(Message msg) { + int what = msg.what; + switch ( msg.what ) { + case MESSAGE_REBIND: + connectService(); + break; + + case MESSAGE_REINIT: + initFiveGServiceState(); + break; + + case MESSAGE_NOTIFIY_MONITOR_CALLBACK: + notifyMonitorCallback(); + break; + } + + } + }; + + + @VisibleForTesting + protected IExtPhoneCallback mCallback = new ExtPhoneCallbackBase() { + @Override + public void onNrIconType(int slotId, Token token, Status status, NrIconType + nrIconType) throws RemoteException { + Log.d(TAG, + "onNrIconType: slotId = " + slotId + " token = " + token + " " + "status" + + status + " NrIconType = " + nrIconType); + if (status.get() == Status.SUCCESS) { + FiveGServiceState state = getCurrentServiceState(slotId); + state.mNrIconType = nrIconType.get(); + update5GIcon(state, slotId); + notifyListenersIfNecessary(slotId); + } + } + }; + + public interface IFiveGStateListener { + public void onStateChanged(FiveGServiceState state); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java index 8231f8b3a09b..e44e6d2d050a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotController.java @@ -30,6 +30,10 @@ public interface HotspotController extends CallbackController<Callback>, Dumpabl interface Callback { void onHotspotChanged(boolean enabled, int numDevices); + default void onHotspotChanged(boolean enabled, int numDevices, + int standard) { + onHotspotChanged(enabled, numDevices); + } default void onHotspotAvailabilityChanged(boolean available) {} } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java index f364e49bb757..f6b8b22d9d44 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java @@ -23,6 +23,7 @@ import android.content.Context; import android.net.ConnectivityManager; import android.net.TetheringManager; import android.net.TetheringManager.TetheringRequest; +import android.net.wifi.ScanResult; import android.net.wifi.WifiClient; import android.net.wifi.WifiManager; import android.os.Handler; @@ -163,7 +164,8 @@ public class HotspotControllerImpl implements HotspotController, WifiManager.Sof // on the Main Handler. In order to always update the callback on added, we // make this call when adding callbacks after the first. mMainHandler.post(() -> - callback.onHotspotChanged(isHotspotEnabled(), mNumConnectedDevices)); + callback.onHotspotChanged(isHotspotEnabled(), mNumConnectedDevices, + getHotspotWifiStandard())); } } } @@ -186,6 +188,13 @@ public class HotspotControllerImpl implements HotspotController, WifiManager.Sof return mHotspotState == WifiManager.WIFI_AP_STATE_ENABLED; } + public int getHotspotWifiStandard() { + if (mWifiManager != null) { + return mWifiManager.getSoftApWifiStandard(); + } + return ScanResult.WIFI_STANDARD_LEGACY; + } + @Override public boolean isHotspotTransient() { return mWaitingForTerminalState || (mHotspotState == WifiManager.WIFI_AP_STATE_ENABLING); @@ -232,7 +241,8 @@ public class HotspotControllerImpl implements HotspotController, WifiManager.Sof list = new ArrayList<>(mCallbacks); } for (Callback callback : list) { - callback.onHotspotChanged(isHotspotEnabled(), mNumConnectedDevices); + callback.onHotspotChanged(isHotspotEnabled(), mNumConnectedDevices, + getHotspotWifiStandard()); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java new file mode 100644 index 000000000000..be2bf0750d92 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2014 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.policy; + +import android.content.Context; +import android.content.Intent; +import android.telephony.SubscriptionInfo; + +import com.android.settingslib.net.DataUsageController; +import com.android.systemui.demomode.DemoMode; +import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; +import com.android.wifitrackerlib.MergedCarrierEntry; +import com.android.wifitrackerlib.WifiEntry; + +import java.util.List; + +public interface NetworkController extends CallbackController<SignalCallback>, DemoMode { + + boolean hasMobileDataFeature(); + void setWifiEnabled(boolean enabled); + AccessPointController getAccessPointController(); + DataUsageController getMobileDataController(); + DataSaverController getDataSaverController(); + String getMobileDataNetworkName(); + boolean isMobileDataNetworkInService(); + int getNumberSubscriptions(); + + boolean hasVoiceCallingFeature(); + + void addEmergencyListener(EmergencyListener listener); + void removeEmergencyListener(EmergencyListener listener); + boolean hasEmergencyCryptKeeperText(); + + boolean isRadioOn(); + + /** + * Wrapper class for all the WiFi signals used for WiFi indicators. + */ + final class WifiIndicators { + public boolean enabled; + public IconState statusIcon; + public IconState qsIcon; + public boolean activityIn; + public boolean activityOut; + public String description; + public boolean isTransient; + public String statusLabel; + + public WifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon, + boolean activityIn, boolean activityOut, String description, + boolean isTransient, String statusLabel) { + this.enabled = enabled; + this.statusIcon = statusIcon; + this.qsIcon = qsIcon; + this.activityIn = activityIn; + this.activityOut = activityOut; + this.description = description; + this.isTransient = isTransient; + this.statusLabel = statusLabel; + } + + @Override + public String toString() { + return new StringBuilder("WifiIndicators[") + .append("enabled=").append(enabled) + .append(",statusIcon=").append(statusIcon == null ? "" : statusIcon.toString()) + .append(",qsIcon=").append(qsIcon == null ? "" : qsIcon.toString()) + .append(",activityIn=").append(activityIn) + .append(",activityOut=").append(activityOut) + .append(",description=").append(description) + .append(",isTransient=").append(isTransient) + .append(",statusLabel=").append(statusLabel) + .append(']').toString(); + } + } + + /** + * Wrapper class for all the mobile signals used for mobile data indicators. + */ + final class MobileDataIndicators { + public IconState statusIcon; + public IconState qsIcon; + public int statusType; + public int qsType; + public boolean activityIn; + public boolean activityOut; + public int volteIcon; + public CharSequence typeContentDescription; + public CharSequence typeContentDescriptionHtml; + public CharSequence description; + public boolean isWide; + public int subId; + public boolean roaming; + public boolean showTriangle; + + public MobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType, + int qsType, boolean activityIn, boolean activityOut, int volteIcon, + CharSequence typeContentDescription, CharSequence typeContentDescriptionHtml, + CharSequence description, boolean isWide, int subId, boolean roaming, + boolean showTriangle) { + this.statusIcon = statusIcon; + this.qsIcon = qsIcon; + this.statusType = statusType; + this.qsType = qsType; + this.activityIn = activityIn; + this.activityOut = activityOut; + this.volteIcon = volteIcon; + this.typeContentDescription = typeContentDescription; + this.typeContentDescriptionHtml = typeContentDescriptionHtml; + this.description = description; + this.isWide = isWide; + this.subId = subId; + this.roaming = roaming; + this.showTriangle = showTriangle; + } + + @Override + public String toString() { + return new StringBuilder("MobileDataIndicators[") + .append("statusIcon=").append(statusIcon == null ? "" : statusIcon.toString()) + .append(",qsIcon=").append(qsIcon == null ? "" : qsIcon.toString()) + .append(",statusType=").append(statusType) + .append(",qsType=").append(qsType) + .append(",activityIn=").append(activityIn) + .append(",activityOut=").append(activityOut) + .append(",volteIcon=").append(volteIcon) + .append(",typeContentDescription=").append(typeContentDescription) + .append(",typeContentDescriptionHtml=").append(typeContentDescriptionHtml) + .append(",description=").append(description) + .append(",isWide=").append(isWide) + .append(",subId=").append(subId) + .append(",roaming=").append(roaming) + .append(",showTriangle=").append(showTriangle) + .append(']').toString(); + } + } + + public interface SignalCallback { + /** + * Callback for listeners to be able to update the state of any UI tracking connectivity of + * WiFi networks. + */ + default void setWifiIndicators(WifiIndicators wifiIndicators) {} + + /** + * Callback for listeners to be able to update the state of any UI tracking connectivity + * of Mobile networks. + */ + default void setMobileDataIndicators(MobileDataIndicators mobileDataIndicators) {} + + default void setSubs(List<SubscriptionInfo> subs) {} + + default void setNoSims(boolean show, boolean simDetected) {} + + default void setEthernetIndicators(IconState icon) {} + + default void setIsAirplaneMode(IconState icon) {} + + default void setMobileDataEnabled(boolean enabled) {} + + /** + * Callback for listeners to be able to update the connectivity status + * @param noDefaultNetwork whether there is any default network. + * @param noValidatedNetwork whether there is any validated network. + * @param noNetworksAvailable whether there is any WiFi networks available. + */ + default void setConnectivityStatus(boolean noDefaultNetwork, boolean noValidatedNetwork, + boolean noNetworksAvailable) {} + + /** + * Callback for listeners to be able to update the call indicator + * @param statusIcon the icon for the call indicator + * @param subId subscription ID for which to update the UI + */ + default void setCallIndicator(IconState statusIcon, int subId) {} + } + + public interface EmergencyListener { + void setEmergencyCallsOnly(boolean emergencyOnly); + } + + public static class IconState { + public final boolean visible; + public final int icon; + public final String contentDescription; + + public IconState(boolean visible, int icon, String contentDescription) { + this.visible = visible; + this.icon = icon; + this.contentDescription = contentDescription; + } + + public IconState(boolean visible, int icon, int contentDescription, + Context context) { + this(visible, icon, context.getString(contentDescription)); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + return builder.append("[visible=").append(visible).append(',') + .append("icon=").append(icon).append(',') + .append("contentDescription=").append(contentDescription).append(']') + .toString(); + } + } + + /** + * Tracks changes in access points. Allows listening for changes, scanning for new APs, + * and connecting to new ones. + */ + public interface AccessPointController { + void addAccessPointCallback(AccessPointCallback callback); + void removeAccessPointCallback(AccessPointCallback callback); + void scanForAccessPoints(); + MergedCarrierEntry getMergedCarrierEntry(); + int getIcon(WifiEntry ap); + boolean connect(WifiEntry ap); + boolean canConfigWifi(); + boolean canConfigMobileData(); + + public interface AccessPointCallback { + void onAccessPointsChanged(List<WifiEntry> accessPoints); + void onSettingsActivityTriggered(Intent settingsIntent); + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/AsyncSensorManager.java b/packages/SystemUI/src/com/android/systemui/util/sensors/AsyncSensorManager.java index 48759824f5ef..747efc806838 100644..100755 --- a/packages/SystemUI/src/com/android/systemui/util/sensors/AsyncSensorManager.java +++ b/packages/SystemUI/src/com/android/systemui/util/sensors/AsyncSensorManager.java @@ -86,7 +86,14 @@ public class AsyncSensorManager extends SensorManager protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor, int delayUs, Handler handler, int maxReportLatencyUs, int reservedFlags) { + if ( sensor == null ) { + Log.e(TAG, "sensor cannot be null \n" + Log.getStackTraceString(new Throwable())); + return false; + } mExecutor.execute(() -> { + if ( sensor == null ) { + Log.e(TAG, "sensor cannot be null"); + } if (!mInner.registerListener(listener, sensor, delayUs, maxReportLatencyUs, handler)) { Log.e(TAG, "Registering " + listener + " for " + sensor + " failed."); } @@ -135,6 +142,9 @@ public class AsyncSensorManager extends SensorManager throw new IllegalArgumentException("sensor cannot be null"); } mExecutor.execute(() -> { + if ( sensor == null ) { + Log.e(TAG, "sensor cannot be null"); + } if (!mInner.requestTriggerSensor(listener, sensor)) { Log.e(TAG, "Requesting " + listener + " for " + sensor + " failed."); } |