diff --git a/packages/SystemUI/res/layout/internet_connectivity_dialog.xml b/packages/SystemUI/res/layout/internet_connectivity_dialog.xml index 5b961595fbd36..ae2537fe29f6c 100644 --- a/packages/SystemUI/res/layout/internet_connectivity_dialog.xml +++ b/packages/SystemUI/res/layout/internet_connectivity_dialog.xml @@ -190,6 +190,11 @@ + + + + + + + + + + + + + + + + + + diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index dc84435f40818..eead934745746 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -2041,6 +2041,15 @@ your carrier + + Switch back to %s? + + Mobile data won\’t automatically switch based on availability + + No thanks + + Yes, switch + @@ -2510,6 +2519,12 @@ Connected + + Temporarily connected + + Poor connection Mobile data won\u0027t auto\u2011connect diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt index 99dfefa4fa417..10732639fc351 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt @@ -205,6 +205,9 @@ object Flags { val QS_SECONDARY_DATA_SUB_INFO = unreleasedFlag(508, "qs_secondary_data_sub_info", teamfood = true) + // TODO(b/244064524): Tracking Bug + @JvmField val QS_SECONDARY_DATA_SUB_INFO = UnreleasedFlag(508, teamfood = true) + // 600- status bar // TODO(b/254513246): Tracking Bug val STATUS_BAR_USER_SWITCHER = 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 ad739cc4a261d..27ad86f0ae122 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 @@ -39,6 +39,7 @@ import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; +import android.view.ViewStub; import android.view.Window; import android.view.WindowManager; import android.widget.Button; @@ -62,6 +63,7 @@ import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils; import com.android.systemui.Prefs; import com.android.systemui.R; import com.android.systemui.accessibility.floatingmenu.AnnotationLinkSpan; +import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; @@ -72,6 +74,8 @@ import com.android.wifitrackerlib.WifiEntry; import java.util.List; import java.util.concurrent.Executor; +import javax.inject.Inject; + /** * Dialog for showing mobile network, connected Wi-Fi network and Wi-Fi networks. */ @@ -86,6 +90,7 @@ public class InternetDialog extends SystemUIDialog implements private final Handler mHandler; private final Executor mBackgroundExecutor; + private final DialogLaunchAnimator mDialogLaunchAnimator; @VisibleForTesting protected InternetAdapter mAdapter; @@ -109,6 +114,7 @@ public class InternetDialog extends SystemUIDialog implements private LinearLayout mInternetDialogLayout; private LinearLayout mConnectedWifListLayout; private LinearLayout mMobileNetworkLayout; + private LinearLayout mSecondaryMobileNetworkLayout; private LinearLayout mTurnWifiOnLayout; private LinearLayout mEthernetLayout; private TextView mWifiToggleTitleText; @@ -123,6 +129,8 @@ public class InternetDialog extends SystemUIDialog implements private ImageView mSignalIcon; private TextView mMobileTitleText; private TextView mMobileSummaryText; + private TextView mSecondaryMobileTitleText; + private TextView mSecondaryMobileSummaryText; private TextView mAirplaneModeSummaryText; private Switch mMobileDataToggle; private View mMobileToggleDivider; @@ -158,9 +166,11 @@ public class InternetDialog extends SystemUIDialog implements mInternetDialogSubTitle.setText(getSubtitleText()); }; + @Inject public InternetDialog(Context context, InternetDialogFactory internetDialogFactory, InternetDialogController internetDialogController, boolean canConfigMobileData, boolean canConfigWifi, boolean aboveStatusBar, UiEventLogger uiEventLogger, + DialogLaunchAnimator dialogLaunchAnimator, @Main Handler handler, @Background Executor executor, KeyguardStateController keyguardStateController) { super(context); @@ -183,6 +193,7 @@ public class InternetDialog extends SystemUIDialog implements mKeyguard = keyguardStateController; mUiEventLogger = uiEventLogger; + mDialogLaunchAnimator = dialogLaunchAnimator; mAdapter = new InternetAdapter(mInternetDialogController); if (!aboveStatusBar) { getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY); @@ -287,6 +298,9 @@ public class InternetDialog extends SystemUIDialog implements mMobileNetworkLayout.setOnClickListener(null); mMobileDataToggle.setOnCheckedChangeListener(null); mConnectedWifListLayout.setOnClickListener(null); + if (mSecondaryMobileNetworkLayout != null) { + mSecondaryMobileNetworkLayout.setOnClickListener(null); + } mSeeAllLayout.setOnClickListener(null); mWiFiToggle.setOnCheckedChangeListener(null); mDoneButton.setOnClickListener(null); @@ -341,6 +355,10 @@ public class InternetDialog extends SystemUIDialog implements private void setOnClickListener() { mMobileNetworkLayout.setOnClickListener(v -> { + int autoSwitchNonDdsSubId = mInternetDialogController.getActiveAutoSwitchNonDdsSubId(); + if (autoSwitchNonDdsSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { + showTurnOffAutoDataSwitchDialog(autoSwitchNonDdsSubId); + } if (mInternetDialogController.isMobileDataEnabled() && !mInternetDialogController.isDeviceLocked()) { if (!mInternetDialogController.activeNetworkIsCellular()) { @@ -390,11 +408,14 @@ public class InternetDialog extends SystemUIDialog implements if (!mInternetDialogController.hasActiveSubId() && (!isWifiEnabled || !isCarrierNetworkActive)) { mMobileNetworkLayout.setVisibility(View.GONE); + if (mSecondaryMobileNetworkLayout != null) { + mSecondaryMobileNetworkLayout.setVisibility(View.GONE); + } } else { mMobileNetworkLayout.setVisibility(View.VISIBLE); mMobileDataToggle.setChecked(mInternetDialogController.isMobileDataEnabled()); - mMobileTitleText.setText(getMobileNetworkTitle()); - String summary = getMobileNetworkSummary(); + mMobileTitleText.setText(getMobileNetworkTitle(mDefaultDataSubId)); + String summary = getMobileNetworkSummary(mDefaultDataSubId); if (!TextUtils.isEmpty(summary)) { mMobileSummaryText.setText( Html.fromHtml(summary, Html.FROM_HTML_MODE_LEGACY)); @@ -404,28 +425,11 @@ public class InternetDialog extends SystemUIDialog implements mMobileSummaryText.setVisibility(View.GONE); } mBackgroundExecutor.execute(() -> { - Drawable drawable = getSignalStrengthDrawable(); + Drawable drawable = getSignalStrengthDrawable(mDefaultDataSubId); mHandler.post(() -> { mSignalIcon.setImageDrawable(drawable); }); }); - mMobileTitleText.setTextAppearance(isNetworkConnected - ? R.style.TextAppearance_InternetDialog_Active - : R.style.TextAppearance_InternetDialog); - int secondaryRes = isNetworkConnected - ? R.style.TextAppearance_InternetDialog_Secondary_Active - : R.style.TextAppearance_InternetDialog_Secondary; - mMobileSummaryText.setTextAppearance(secondaryRes); - // Set airplane mode to the summary for carrier network - if (mInternetDialogController.isAirplaneModeEnabled()) { - mAirplaneModeSummaryText.setVisibility(View.VISIBLE); - mAirplaneModeSummaryText.setText(mContext.getText(R.string.airplane_mode)); - mAirplaneModeSummaryText.setTextAppearance(secondaryRes); - } else { - mAirplaneModeSummaryText.setVisibility(View.GONE); - } - mMobileNetworkLayout.setBackground( - isNetworkConnected ? mBackgroundOn : mBackgroundOff); TypedArray array = mContext.obtainStyledAttributes( R.style.InternetDialog_Divider_Active, new int[]{android.R.attr.background}); @@ -438,6 +442,86 @@ public class InternetDialog extends SystemUIDialog implements mMobileDataToggle.setVisibility(mCanConfigMobileData ? View.VISIBLE : View.INVISIBLE); mMobileToggleDivider.setVisibility( mCanConfigMobileData ? View.VISIBLE : View.INVISIBLE); + + // Display the info for the non-DDS if it's actively being used + int autoSwitchNonDdsSubId = mInternetDialogController.getActiveAutoSwitchNonDdsSubId(); + int nonDdsVisibility = autoSwitchNonDdsSubId + != SubscriptionManager.INVALID_SUBSCRIPTION_ID ? View.VISIBLE : View.GONE; + + int secondaryRes = isNetworkConnected + ? R.style.TextAppearance_InternetDialog_Secondary_Active + : R.style.TextAppearance_InternetDialog_Secondary; + if (nonDdsVisibility == View.VISIBLE) { + // non DDS is the currently active sub, set primary visual for it + ViewStub stub = mDialogView.findViewById(R.id.secondary_mobile_network_stub); + if (stub != null) { + stub.inflate(); + } + mSecondaryMobileNetworkLayout = findViewById(R.id.secondary_mobile_network_layout); + mSecondaryMobileNetworkLayout.setOnClickListener( + this::onClickConnectedSecondarySub); + mSecondaryMobileNetworkLayout.setBackground(mBackgroundOn); + + mSecondaryMobileTitleText = mDialogView.requireViewById( + R.id.secondary_mobile_title); + mSecondaryMobileTitleText.setText(getMobileNetworkTitle(autoSwitchNonDdsSubId)); + mSecondaryMobileTitleText.setTextAppearance( + R.style.TextAppearance_InternetDialog_Active); + + mSecondaryMobileSummaryText = + mDialogView.requireViewById(R.id.secondary_mobile_summary); + summary = getMobileNetworkSummary(autoSwitchNonDdsSubId); + if (!TextUtils.isEmpty(summary)) { + mSecondaryMobileSummaryText.setText( + Html.fromHtml(summary, Html.FROM_HTML_MODE_LEGACY)); + mSecondaryMobileSummaryText.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE); + mSecondaryMobileSummaryText.setTextAppearance( + R.style.TextAppearance_InternetDialog_Active); + } + + ImageView mSecondarySignalIcon = + mDialogView.requireViewById(R.id.secondary_signal_icon); + mBackgroundExecutor.execute(() -> { + Drawable drawable = getSignalStrengthDrawable(autoSwitchNonDdsSubId); + mHandler.post(() -> { + mSecondarySignalIcon.setImageDrawable(drawable); + }); + }); + + ImageView mSecondaryMobileSettingsIcon = + mDialogView.requireViewById(R.id.secondary_settings_icon); + mSecondaryMobileSettingsIcon.setColorFilter( + mContext.getColor(R.color.connected_network_primary_color)); + + // set secondary visual for default data sub + mMobileNetworkLayout.setBackground(mBackgroundOff); + mMobileTitleText.setTextAppearance(R.style.TextAppearance_InternetDialog); + mMobileSummaryText.setTextAppearance( + R.style.TextAppearance_InternetDialog_Secondary); + mSignalIcon.setColorFilter( + mContext.getColor(R.color.connected_network_secondary_color)); + } else { + mMobileNetworkLayout.setBackground( + isNetworkConnected ? mBackgroundOn : mBackgroundOff); + mMobileTitleText.setTextAppearance(isNetworkConnected + ? + R.style.TextAppearance_InternetDialog_Active + : R.style.TextAppearance_InternetDialog); + mMobileSummaryText.setTextAppearance(secondaryRes); + } + + if (mSecondaryMobileNetworkLayout != null) { + mSecondaryMobileNetworkLayout.setVisibility(nonDdsVisibility); + } + + // Set airplane mode to the summary for carrier network + if (mInternetDialogController.isAirplaneModeEnabled()) { + mAirplaneModeSummaryText.setVisibility(View.VISIBLE); + mAirplaneModeSummaryText.setText(mContext.getText(R.string.airplane_mode)); + mAirplaneModeSummaryText.setTextAppearance(secondaryRes); + } else { + mAirplaneModeSummaryText.setVisibility(View.GONE); + } } } @@ -476,6 +560,10 @@ public class InternetDialog extends SystemUIDialog implements mInternetDialogController.getInternetWifiDrawable(mConnectedWifiEntry)); mWifiSettingsIcon.setColorFilter( mContext.getColor(R.color.connected_network_primary_color)); + + if (mSecondaryMobileNetworkLayout != null) { + mSecondaryMobileNetworkLayout.setVisibility(View.GONE); + } } @MainThread @@ -546,6 +634,11 @@ public class InternetDialog extends SystemUIDialog implements mInternetDialogController.launchWifiDetailsSetting(mConnectedWifiEntry.getKey(), view); } + /** For DSDS auto data switch **/ + void onClickConnectedSecondarySub(View view) { + mInternetDialogController.launchMobileNetworkSettings(view); + } + void onClickSeeMoreButton(View view) { mInternetDialogController.launchNetworkSetting(view); } @@ -560,16 +653,16 @@ public class InternetDialog extends SystemUIDialog implements mIsProgressBarVisible && !mIsSearchingHidden); } - private Drawable getSignalStrengthDrawable() { - return mInternetDialogController.getSignalStrengthDrawable(); + private Drawable getSignalStrengthDrawable(int subId) { + return mInternetDialogController.getSignalStrengthDrawable(subId); } - CharSequence getMobileNetworkTitle() { - return mInternetDialogController.getMobileNetworkTitle(); + CharSequence getMobileNetworkTitle(int subId) { + return mInternetDialogController.getMobileNetworkTitle(subId); } - String getMobileNetworkSummary() { - return mInternetDialogController.getMobileNetworkSummary(); + String getMobileNetworkSummary(int subId) { + return mInternetDialogController.getMobileNetworkSummary(subId); } protected void showProgressBar() { @@ -607,8 +700,8 @@ public class InternetDialog extends SystemUIDialog implements } private void showTurnOffMobileDialog() { - CharSequence carrierName = getMobileNetworkTitle(); - boolean isInService = mInternetDialogController.isVoiceStateInService(); + CharSequence carrierName = getMobileNetworkTitle(mDefaultDataSubId); + boolean isInService = mInternetDialogController.isVoiceStateInService(mDefaultDataSubId); if (TextUtils.isEmpty(carrierName) || !isInService) { carrierName = mContext.getString(R.string.mobile_data_disable_message_default_carrier); } @@ -632,7 +725,33 @@ public class InternetDialog extends SystemUIDialog implements SystemUIDialog.setShowForAllUsers(mAlertDialog, true); SystemUIDialog.registerDismissListener(mAlertDialog); SystemUIDialog.setWindowOnTop(mAlertDialog, mKeyguard.isShowing()); - mAlertDialog.show(); + mDialogLaunchAnimator.showFromDialog(mAlertDialog, this, null, false); + } + + private void showTurnOffAutoDataSwitchDialog(int subId) { + CharSequence carrierName = getMobileNetworkTitle(mDefaultDataSubId); + if (TextUtils.isEmpty(carrierName)) { + carrierName = mContext.getString(R.string.mobile_data_disable_message_default_carrier); + } + mAlertDialog = new Builder(mContext) + .setTitle(mContext.getString(R.string.auto_data_switch_disable_title, carrierName)) + .setMessage(R.string.auto_data_switch_disable_message) + .setNegativeButton(R.string.auto_data_switch_dialog_negative_button, + (d, w) -> {}) + .setPositiveButton(R.string.auto_data_switch_dialog_positive_button, + (d, w) -> { + mInternetDialogController + .setAutoDataSwitchMobileDataPolicy(subId, false); + if (mSecondaryMobileNetworkLayout != null) { + mSecondaryMobileNetworkLayout.setVisibility(View.GONE); + } + }) + .create(); + mAlertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); + SystemUIDialog.setShowForAllUsers(mAlertDialog, true); + SystemUIDialog.registerDismissListener(mAlertDialog); + SystemUIDialog.setWindowOnTop(mAlertDialog, mKeyguard.isShowing()); + mDialogLaunchAnimator.showFromDialog(mAlertDialog, this, null, false); } @Override 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 9c0a087c01b8f..4c7f10e2bc6b9 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 @@ -37,6 +37,7 @@ import android.net.ConnectivityManager; import android.net.Network; import android.net.NetworkCapabilities; import android.net.wifi.WifiManager; +import android.os.Bundle; import android.os.Handler; import android.os.UserHandle; import android.provider.Settings; @@ -78,6 +79,8 @@ import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.flags.Flags; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.statusbar.connectivity.AccessPointController; import com.android.systemui.statusbar.policy.KeyguardStateController; @@ -90,6 +93,7 @@ import com.android.wifitrackerlib.MergedCarrierEntry; import com.android.wifitrackerlib.WifiEntry; import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -113,6 +117,17 @@ public class InternetDialogController implements AccessPointController.AccessPoi "android.settings.NETWORK_PROVIDER_SETTINGS"; private static final String ACTION_WIFI_SCANNING_SETTINGS = "android.settings.WIFI_SCANNING_SETTINGS"; + /** + * Fragment "key" argument passed thru {@link #SETTINGS_EXTRA_SHOW_FRAGMENT_ARGUMENTS} + */ + private static final String SETTINGS_EXTRA_FRAGMENT_ARG_KEY = ":settings:fragment_args_key"; + /** + * When starting this activity, this extra can also be specified to supply a Bundle of arguments + * to pass to that fragment when it is instantiated during the initial creation of the activity. + */ + private static final String SETTINGS_EXTRA_SHOW_FRAGMENT_ARGUMENTS = + ":settings:show_fragment_args"; + private static final String AUTO_DATA_SWITCH_SETTING_R_ID = "auto_data_switch"; public static final Drawable EMPTY_DRAWABLE = new ColorDrawable(Color.TRANSPARENT); public static final int NO_CELL_DATA_TYPE_ICON = 0; private static final int SUBTITLE_TEXT_WIFI_IS_OFF = R.string.wifi_is_off; @@ -130,9 +145,12 @@ public class InternetDialogController implements AccessPointController.AccessPoi static final int MAX_WIFI_ENTRY_COUNT = 3; + private final FeatureFlags mFeatureFlags; + private WifiManager mWifiManager; private Context mContext; private SubscriptionManager mSubscriptionManager; + private Map mSubIdTelephonyManagerMap = new HashMap<>(); private TelephonyManager mTelephonyManager; private ConnectivityManager mConnectivityManager; private CarrierConfigTracker mCarrierConfigTracker; @@ -155,6 +173,7 @@ public class InternetDialogController implements AccessPointController.AccessPoi private WindowManager mWindowManager; private ToastFactory mToastFactory; private SignalDrawable mSignalDrawable; + private SignalDrawable mSecondarySignalDrawable; // For the secondary mobile data sub in DSDS private LocationController mLocationController; private DialogLaunchAnimator mDialogLaunchAnimator; private boolean mHasWifiEntries; @@ -213,7 +232,8 @@ public class InternetDialogController implements AccessPointController.AccessPoi CarrierConfigTracker carrierConfigTracker, LocationController locationController, DialogLaunchAnimator dialogLaunchAnimator, - WifiStateWorker wifiStateWorker + WifiStateWorker wifiStateWorker, + FeatureFlags featureFlags ) { if (DEBUG) { Log.d(TAG, "Init InternetDialogController"); @@ -242,10 +262,12 @@ public class InternetDialogController implements AccessPointController.AccessPoi mWindowManager = windowManager; mToastFactory = toastFactory; mSignalDrawable = new SignalDrawable(mContext); + mSecondarySignalDrawable = new SignalDrawable(mContext); mLocationController = locationController; mDialogLaunchAnimator = dialogLaunchAnimator; mConnectedWifiInternetMonitor = new ConnectedWifiInternetMonitor(); mWifiStateWorker = wifiStateWorker; + mFeatureFlags = featureFlags; } void onStart(@NonNull InternetDialogCallback callback, boolean canConfigWifi) { @@ -267,6 +289,7 @@ public class InternetDialogController implements AccessPointController.AccessPoi } mConfig = MobileMappings.Config.readConfig(mContext); mTelephonyManager = mTelephonyManager.createForSubscriptionId(mDefaultDataSubId); + mSubIdTelephonyManagerMap.put(mDefaultDataSubId, mTelephonyManager); mInternetTelephonyCallback = new InternetTelephonyCallback(); mTelephonyManager.registerTelephonyCallback(mExecutor, mInternetTelephonyCallback); // Listen the connectivity changes @@ -280,7 +303,9 @@ public class InternetDialogController implements AccessPointController.AccessPoi Log.d(TAG, "onStop"); } mBroadcastDispatcher.unregisterReceiver(mConnectionStateReceiver); - mTelephonyManager.unregisterTelephonyCallback(mInternetTelephonyCallback); + for (TelephonyManager tm : mSubIdTelephonyManagerMap.values()) { + tm.unregisterTelephonyCallback(mInternetTelephonyCallback); + } mSubscriptionManager.removeOnSubscriptionsChangedListener( mOnSubscriptionsChangedListener); mAccessPointController.removeAccessPointCallback(this); @@ -371,7 +396,10 @@ public class InternetDialogController implements AccessPointController.AccessPoi if (DEBUG) { Log.d(TAG, "No Wi-Fi item."); } - if (!hasActiveSubId() || (!isVoiceStateInService() && !isDataStateInService())) { + boolean isActiveOnNonDds = getActiveAutoSwitchNonDdsSubId() != SubscriptionManager + .INVALID_SUBSCRIPTION_ID; + if (!hasActiveSubId() || (!isVoiceStateInService(mDefaultDataSubId) + && !isDataStateInService(mDefaultDataSubId) && !isActiveOnNonDds)) { if (DEBUG) { Log.d(TAG, "No carrier or service is out of service."); } @@ -412,7 +440,7 @@ public class InternetDialogController implements AccessPointController.AccessPoi return drawable; } - Drawable getSignalStrengthDrawable() { + Drawable getSignalStrengthDrawable(int subId) { Drawable drawable = mContext.getDrawable( R.drawable.ic_signal_strength_zero_bar_no_internet); try { @@ -424,9 +452,10 @@ public class InternetDialogController implements AccessPointController.AccessPoi } boolean isCarrierNetworkActive = isCarrierNetworkActive(); - if (isDataStateInService() || isVoiceStateInService() || isCarrierNetworkActive) { + if (isDataStateInService(subId) || isVoiceStateInService(subId) + || isCarrierNetworkActive) { AtomicReference shared = new AtomicReference<>(); - shared.set(getSignalStrengthDrawableWithLevel(isCarrierNetworkActive)); + shared.set(getSignalStrengthDrawableWithLevel(isCarrierNetworkActive, subId)); drawable = shared.get(); } @@ -447,24 +476,30 @@ public class InternetDialogController implements AccessPointController.AccessPoi * * @return The Drawable which is a signal bar icon with level. */ - Drawable getSignalStrengthDrawableWithLevel(boolean isCarrierNetworkActive) { - final SignalStrength strength = mTelephonyManager.getSignalStrength(); + Drawable getSignalStrengthDrawableWithLevel(boolean isCarrierNetworkActive, int subId) { + TelephonyManager tm = mSubIdTelephonyManagerMap.getOrDefault(subId, mTelephonyManager); + final SignalStrength strength = tm.getSignalStrength(); int level = (strength == null) ? 0 : strength.getLevel(); int numLevels = SignalStrength.NUM_SIGNAL_STRENGTH_BINS; if (isCarrierNetworkActive) { level = getCarrierNetworkLevel(); numLevels = WifiEntry.WIFI_LEVEL_MAX + 1; - } else if (mSubscriptionManager != null && shouldInflateSignalStrength(mDefaultDataSubId)) { + } else if (mSubscriptionManager != null && shouldInflateSignalStrength(subId)) { level += 1; numLevels += 1; } - return getSignalStrengthIcon(mContext, level, numLevels, NO_CELL_DATA_TYPE_ICON, + return getSignalStrengthIcon(subId, mContext, level, numLevels, NO_CELL_DATA_TYPE_ICON, !isMobileDataEnabled()); } - Drawable getSignalStrengthIcon(Context context, int level, int numLevels, + Drawable getSignalStrengthIcon(int subId, Context context, int level, int numLevels, int iconType, boolean cutOut) { - mSignalDrawable.setLevel(SignalDrawable.getState(level, numLevels, cutOut)); + boolean isForDds = subId == mDefaultDataSubId; + if (isForDds) { + mSignalDrawable.setLevel(SignalDrawable.getState(level, numLevels, cutOut)); + } else { + mSecondarySignalDrawable.setLevel(SignalDrawable.getState(level, numLevels, cutOut)); + } // Make the network type drawable final Drawable networkDrawable = @@ -473,7 +508,8 @@ public class InternetDialogController implements AccessPointController.AccessPoi : context.getResources().getDrawable(iconType, context.getTheme()); // Overlay the two drawables - final Drawable[] layers = {networkDrawable, mSignalDrawable}; + final Drawable[] layers = {networkDrawable, isForDds + ? mSignalDrawable : mSecondarySignalDrawable}; final int iconSize = context.getResources().getDimensionPixelSize(R.dimen.signal_strength_icon_size); @@ -571,14 +607,39 @@ public class InternetDialogController implements AccessPointController.AccessPoi info -> info.uniqueName)); } - CharSequence getMobileNetworkTitle() { - return getUniqueSubscriptionDisplayName(mDefaultDataSubId, mContext); + /** + * @return the subId of the visible non-DDS if it's actively being used for data, otherwise + * return {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}. + */ + int getActiveAutoSwitchNonDdsSubId() { + if (!mFeatureFlags.isEnabled(Flags.QS_SECONDARY_DATA_SUB_INFO)) { + // sets the non-DDS to be not found to hide its visual + return SubscriptionManager.INVALID_SUBSCRIPTION_ID; + } + SubscriptionInfo subInfo = mSubscriptionManager.getActiveSubscriptionInfo( + SubscriptionManager.getActiveDataSubscriptionId()); + if (subInfo != null && subInfo.getSubscriptionId() != mDefaultDataSubId + && !subInfo.isOpportunistic()) { + int subId = subInfo.getSubscriptionId(); + if (mSubIdTelephonyManagerMap.get(subId) == null) { + TelephonyManager secondaryTm = mTelephonyManager.createForSubscriptionId(subId); + secondaryTm.registerTelephonyCallback(mExecutor, mInternetTelephonyCallback); + mSubIdTelephonyManagerMap.put(subId, secondaryTm); + } + return subId; + } + return SubscriptionManager.INVALID_SUBSCRIPTION_ID; + } - String getMobileNetworkSummary() { + CharSequence getMobileNetworkTitle(int subId) { + return getUniqueSubscriptionDisplayName(subId, mContext); + } + + String getMobileNetworkSummary(int subId) { String description = getNetworkTypeDescription(mContext, mConfig, - mTelephonyDisplayInfo, mDefaultDataSubId); - return getMobileSummary(mContext, description); + mTelephonyDisplayInfo, subId); + return getMobileSummary(mContext, description, subId); } /** @@ -606,22 +667,28 @@ public class InternetDialogController implements AccessPointController.AccessPoi ? SubscriptionManager.getResourcesForSubId(context, subId).getString(resId) : ""; } - private String getMobileSummary(Context context, String networkTypeDescription) { + private String getMobileSummary(Context context, String networkTypeDescription, int subId) { if (!isMobileDataEnabled()) { return context.getString(R.string.mobile_data_off_summary); } String summary = networkTypeDescription; + boolean isForDds = subId == mDefaultDataSubId; + int activeSubId = getActiveAutoSwitchNonDdsSubId(); + boolean isOnNonDds = activeSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID; // Set network description for the carrier network when connecting to the carrier network // under the airplane mode ON. if (activeNetworkIsCellular() || isCarrierNetworkActive()) { summary = context.getString(R.string.preference_summary_default_combination, - context.getString(R.string.mobile_data_connection_active), + context.getString( + isForDds // if nonDds is active, explains Dds status as poor connection + ? (isOnNonDds ? R.string.mobile_data_poor_connection + : R.string.mobile_data_connection_active) + : R.string.mobile_data_temp_connection_active), networkTypeDescription); - } else if (!isDataStateInService()) { + } else if (!isDataStateInService(subId)) { summary = context.getString(R.string.mobile_data_no_connection); } - return summary; } @@ -647,6 +714,26 @@ public class InternetDialogController implements AccessPointController.AccessPoi } } + void launchMobileNetworkSettings(View view) { + final int subId = getActiveAutoSwitchNonDdsSubId(); + if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { + Log.w(TAG, "launchMobileNetworkSettings fail, invalid subId:" + subId); + return; + } + startActivity(getSubSettingIntent(subId), view); + } + + Intent getSubSettingIntent(int subId) { + final Intent intent = new Intent(Settings.ACTION_NETWORK_OPERATOR_SETTINGS); + + final Bundle fragmentArgs = new Bundle(); + // Special contract for Settings to highlight permission row + fragmentArgs.putString(SETTINGS_EXTRA_FRAGMENT_ARG_KEY, AUTO_DATA_SWITCH_SETTING_R_ID); + fragmentArgs.putInt(Settings.EXTRA_SUB_ID, subId); + intent.putExtra(SETTINGS_EXTRA_SHOW_FRAGMENT_ARGUMENTS, fragmentArgs); + return intent; + } + void launchWifiScanningSetting(View view) { final Intent intent = new Intent(ACTION_WIFI_SCANNING_SETTINGS); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); @@ -796,8 +883,20 @@ public class InternetDialogController implements AccessPointController.AccessPoi mWorkerHandler.post(() -> setMergedCarrierWifiEnabledIfNeed(subId, enabled)); } - boolean isDataStateInService() { - final ServiceState serviceState = mTelephonyManager.getServiceState(); + void setAutoDataSwitchMobileDataPolicy(int subId, boolean enable) { + TelephonyManager tm = mSubIdTelephonyManagerMap.getOrDefault(subId, mTelephonyManager); + if (tm == null) { + if (DEBUG) { + Log.d(TAG, "TelephonyManager is null, can not set mobile data."); + } + return; + } + tm.setMobileDataPolicyEnabled(TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH, enable); + } + + boolean isDataStateInService(int subId) { + TelephonyManager tm = mSubIdTelephonyManagerMap.getOrDefault(subId, mTelephonyManager); + final ServiceState serviceState = tm.getServiceState(); NetworkRegistrationInfo regInfo = (serviceState == null) ? null : serviceState.getNetworkRegistrationInfo( NetworkRegistrationInfo.DOMAIN_PS, @@ -805,7 +904,7 @@ public class InternetDialogController implements AccessPointController.AccessPoi return (regInfo == null) ? false : regInfo.isRegistered(); } - boolean isVoiceStateInService() { + boolean isVoiceStateInService(int subId) { if (mTelephonyManager == null) { if (DEBUG) { Log.d(TAG, "TelephonyManager is null, can not detect voice state."); @@ -813,7 +912,8 @@ public class InternetDialogController implements AccessPointController.AccessPoi return false; } - final ServiceState serviceState = mTelephonyManager.getServiceState(); + TelephonyManager tm = mSubIdTelephonyManagerMap.getOrDefault(subId, mTelephonyManager); + final ServiceState serviceState = tm.getServiceState(); return serviceState != null && serviceState.getState() == serviceState.STATE_IN_SERVICE; } @@ -1104,6 +1204,7 @@ public class InternetDialogController implements AccessPointController.AccessPoi if (SubscriptionManager.isUsableSubscriptionId(mDefaultDataSubId)) { mTelephonyManager.unregisterTelephonyCallback(mInternetTelephonyCallback); mTelephonyManager = mTelephonyManager.createForSubscriptionId(mDefaultDataSubId); + mSubIdTelephonyManagerMap.put(mDefaultDataSubId, mTelephonyManager); mTelephonyManager.registerTelephonyCallback(mHandler::post, mInternetTelephonyCallback); mCallback.onSubscriptionsChanged(mDefaultDataSubId); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogFactory.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogFactory.kt index 8566ca3087382..796672dc0ead8 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogFactory.kt @@ -66,7 +66,8 @@ class InternetDialogFactory @Inject constructor( } else { internetDialog = InternetDialog( context, this, internetDialogController, - canConfigMobileData, canConfigWifi, aboveStatusBar, uiEventLogger, handler, + canConfigMobileData, canConfigWifi, aboveStatusBar, uiEventLogger, + dialogLaunchAnimator, handler, executor, keyguardStateController ) if (view != null) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java index 7b1e5c9f72641..05c1f1574d1c8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogControllerTest.java @@ -5,6 +5,7 @@ import static android.telephony.SignalStrength.NUM_SIGNAL_STRENGTH_BINS; import static android.telephony.SignalStrength.SIGNAL_STRENGTH_GREAT; import static android.telephony.SignalStrength.SIGNAL_STRENGTH_POOR; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; import static com.android.systemui.qs.tiles.dialog.InternetDialogController.TOAST_PARAMS_HORIZONTAL_WEIGHT; import static com.android.systemui.qs.tiles.dialog.InternetDialogController.TOAST_PARAMS_VERTICAL_WEIGHT; import static com.android.wifitrackerlib.WifiEntry.WIFI_LEVEL_MAX; @@ -13,6 +14,7 @@ import static com.android.wifitrackerlib.WifiEntry.WIFI_LEVEL_UNREACHABLE; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -36,6 +38,7 @@ import android.net.wifi.WifiManager; import android.os.Handler; import android.telephony.ServiceState; import android.telephony.SignalStrength; +import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.testing.AndroidTestingRunner; @@ -55,6 +58,8 @@ import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.flags.UnreleasedFlag; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.statusbar.connectivity.AccessPointController; import com.android.systemui.statusbar.policy.KeyguardStateController; @@ -68,12 +73,15 @@ import com.android.systemui.util.time.FakeSystemClock; import com.android.wifitrackerlib.MergedCarrierEntry; import com.android.wifitrackerlib.WifiEntry; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.mockito.MockitoSession; +import org.mockito.quality.Strictness; import java.util.ArrayList; import java.util.List; @@ -84,6 +92,9 @@ import java.util.List; public class InternetDialogControllerTest extends SysuiTestCase { private static final int SUB_ID = 1; + private static final int SUB_ID2 = 2; + + private MockitoSession mStaticMockSession; //SystemUIToast private static final int GRAVITY_FLAGS = Gravity.FILL_HORIZONTAL | Gravity.FILL_VERTICAL; @@ -150,6 +161,8 @@ public class InternetDialogControllerTest extends SysuiTestCase { private WifiStateWorker mWifiStateWorker; @Mock private SignalStrength mSignalStrength; + @Mock + private FeatureFlags mFlags; private TestableResources mTestableResources; private InternetDialogController mInternetDialogController; @@ -159,6 +172,10 @@ public class InternetDialogControllerTest extends SysuiTestCase { @Before public void setUp() { + mStaticMockSession = mockitoSession() + .mockStatic(SubscriptionManager.class) + .strictness(Strictness.LENIENT) + .startMocking(); MockitoAnnotations.initMocks(this); mTestableResources = mContext.getOrCreateTestableResources(); doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(anyInt()); @@ -175,6 +192,7 @@ public class InternetDialogControllerTest extends SysuiTestCase { mAccessPoints.add(mWifiEntry1); when(mAccessPointController.getMergedCarrierEntry()).thenReturn(mMergedCarrierEntry); when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[]{SUB_ID}); + when(SubscriptionManager.getDefaultDataSubscriptionId()).thenReturn(SUB_ID); when(mToastFactory.createToast(any(), anyString(), anyString(), anyInt(), anyInt())) .thenReturn(mSystemUIToast); when(mSystemUIToast.getView()).thenReturn(mToastView); @@ -188,7 +206,7 @@ public class InternetDialogControllerTest extends SysuiTestCase { mock(ConnectivityManager.class), mHandler, mExecutor, mBroadcastDispatcher, mock(KeyguardUpdateMonitor.class), mGlobalSettings, mKeyguardStateController, mWindowManager, mToastFactory, mWorkerHandler, mCarrierConfigTracker, - mLocationController, mDialogLaunchAnimator, mWifiStateWorker); + mLocationController, mDialogLaunchAnimator, mWifiStateWorker, mFlags); mSubscriptionManager.addOnSubscriptionsChangedListener(mExecutor, mInternetDialogController.mOnSubscriptionsChangedListener); mInternetDialogController.onStart(mInternetDialogCallback, true); @@ -197,6 +215,11 @@ public class InternetDialogControllerTest extends SysuiTestCase { mInternetDialogController.mWifiIconInjector = mWifiIconInjector; } + @After + public void tearDown() { + mStaticMockSession.finishMocking(); + } + @Test public void connectCarrierNetwork_mergedCarrierEntryCanConnect_connectAndCreateSysUiToast() { when(mMergedCarrierEntry.canConnect()).thenReturn(true); @@ -325,15 +348,45 @@ public class InternetDialogControllerTest extends SysuiTestCase { @Test public void getSubtitleText_withNoService_returnNoNetworksAvailable() { + when(mFlags.isEnabled(any(UnreleasedFlag.class))).thenReturn(true); + InternetDialogController spyController = spy(mInternetDialogController); fakeAirplaneModeEnabled(false); when(mWifiStateWorker.isWifiEnabled()).thenReturn(true); - mInternetDialogController.onAccessPointsChanged(null /* accessPoints */); + spyController.onAccessPointsChanged(null /* accessPoints */); + + doReturn(SUB_ID2).when(spyController).getActiveAutoSwitchNonDdsSubId(); + doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getState(); + doReturn(mServiceState).when(mTelephonyManager).getServiceState(); + doReturn(TelephonyManager.DATA_DISCONNECTED).when(mTelephonyManager).getDataState(); + + assertFalse(TextUtils.equals(spyController.getSubtitleText(false), + getResourcesString("all_network_unavailable"))); + + doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID) + .when(spyController).getActiveAutoSwitchNonDdsSubId(); + spyController.onAccessPointsChanged(null /* accessPoints */); + assertTrue(TextUtils.equals(spyController.getSubtitleText(false), + getResourcesString("all_network_unavailable"))); + } + + @Test + public void getSubtitleText_withNoService_returnNoNetworksAvailable_flagOff() { + InternetDialogController spyController = spy(mInternetDialogController); + fakeAirplaneModeEnabled(false); + when(mWifiStateWorker.isWifiEnabled()).thenReturn(true); + spyController.onAccessPointsChanged(null /* accessPoints */); doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getState(); doReturn(mServiceState).when(mTelephonyManager).getServiceState(); doReturn(TelephonyManager.DATA_DISCONNECTED).when(mTelephonyManager).getDataState(); - assertTrue(TextUtils.equals(mInternetDialogController.getSubtitleText(false), + assertTrue(TextUtils.equals(spyController.getSubtitleText(false), + getResourcesString("all_network_unavailable"))); + + doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID) + .when(spyController).getActiveAutoSwitchNonDdsSubId(); + spyController.onAccessPointsChanged(null /* accessPoints */); + assertTrue(TextUtils.equals(spyController.getSubtitleText(false), getResourcesString("all_network_unavailable"))); } @@ -650,6 +703,108 @@ public class InternetDialogControllerTest extends SysuiTestCase { assertThat(mInternetDialogController.isWifiScanEnabled()).isTrue(); } + @Test + public void getSignalStrengthIcon_differentSubId() { + when(mFlags.isEnabled(any(UnreleasedFlag.class))).thenReturn(true); + InternetDialogController spyController = spy(mInternetDialogController); + Drawable icons = spyController.getSignalStrengthIcon(SUB_ID, mContext, 1, 1, 0, false); + Drawable icons2 = spyController.getSignalStrengthIcon(SUB_ID2, mContext, 1, 1, 0, false); + + assertThat(icons).isNotEqualTo(icons2); + } + + @Test + public void getActiveAutoSwitchNonDdsSubId() { + when(mFlags.isEnabled(any(UnreleasedFlag.class))).thenReturn(true); + // active on non-DDS + SubscriptionInfo info = mock(SubscriptionInfo.class); + doReturn(SUB_ID2).when(info).getSubscriptionId(); + when(mSubscriptionManager.getActiveSubscriptionInfo(anyInt())).thenReturn(info); + + int subId = mInternetDialogController.getActiveAutoSwitchNonDdsSubId(); + assertThat(subId).isEqualTo(SUB_ID2); + + // active on CBRS + doReturn(true).when(info).isOpportunistic(); + subId = mInternetDialogController.getActiveAutoSwitchNonDdsSubId(); + assertThat(subId).isEqualTo(SubscriptionManager.INVALID_SUBSCRIPTION_ID); + + // active on DDS + doReturn(false).when(info).isOpportunistic(); + doReturn(SUB_ID).when(info).getSubscriptionId(); + when(mSubscriptionManager.getActiveSubscriptionInfo(anyInt())).thenReturn(info); + + subId = mInternetDialogController.getActiveAutoSwitchNonDdsSubId(); + assertThat(subId).isEqualTo(SubscriptionManager.INVALID_SUBSCRIPTION_ID); + } + + @Test + public void getActiveAutoSwitchNonDdsSubId_flagOff() { + // active on non-DDS + SubscriptionInfo info = mock(SubscriptionInfo.class); + doReturn(SUB_ID2).when(info).getSubscriptionId(); + when(mSubscriptionManager.getActiveSubscriptionInfo(anyInt())).thenReturn(info); + + int subId = mInternetDialogController.getActiveAutoSwitchNonDdsSubId(); + assertThat(subId).isEqualTo(SubscriptionManager.INVALID_SUBSCRIPTION_ID); + } + + @Test + public void getMobileNetworkSummary() { + when(mFlags.isEnabled(any(UnreleasedFlag.class))).thenReturn(true); + InternetDialogController spyController = spy(mInternetDialogController); + doReturn(SUB_ID2).when(spyController).getActiveAutoSwitchNonDdsSubId(); + doReturn(true).when(spyController).isMobileDataEnabled(); + doReturn(true).when(spyController).activeNetworkIsCellular(); + String dds = spyController.getMobileNetworkSummary(SUB_ID); + String nonDds = spyController.getMobileNetworkSummary(SUB_ID2); + + assertThat(dds).contains(mContext.getString(R.string.mobile_data_poor_connection)); + assertThat(dds).isNotEqualTo(nonDds); + } + + @Test + public void getMobileNetworkSummary_flagOff() { + InternetDialogController spyController = spy(mInternetDialogController); + doReturn(true).when(spyController).isMobileDataEnabled(); + doReturn(true).when(spyController).activeNetworkIsCellular(); + String dds = spyController.getMobileNetworkSummary(SUB_ID); + + assertThat(dds).contains(mContext.getString(R.string.mobile_data_connection_active)); + } + + @Test + public void launchMobileNetworkSettings_validSubId() { + when(mFlags.isEnabled(any(UnreleasedFlag.class))).thenReturn(true); + InternetDialogController spyController = spy(mInternetDialogController); + doReturn(SUB_ID2).when(spyController).getActiveAutoSwitchNonDdsSubId(); + spyController.launchMobileNetworkSettings(mDialogLaunchView); + + verify(mActivityStarter).postStartActivityDismissingKeyguard(any(Intent.class), anyInt(), + any()); + } + + @Test + public void launchMobileNetworkSettings_invalidSubId() { + when(mFlags.isEnabled(any(UnreleasedFlag.class))).thenReturn(true); + InternetDialogController spyController = spy(mInternetDialogController); + doReturn(SubscriptionManager.INVALID_SUBSCRIPTION_ID) + .when(spyController).getActiveAutoSwitchNonDdsSubId(); + spyController.launchMobileNetworkSettings(mDialogLaunchView); + + verify(mActivityStarter, never()) + .postStartActivityDismissingKeyguard(any(Intent.class), anyInt()); + } + + @Test + public void setAutoDataSwitchMobileDataPolicy() { + when(mFlags.isEnabled(any(UnreleasedFlag.class))).thenReturn(true); + mInternetDialogController.setAutoDataSwitchMobileDataPolicy(SUB_ID, true); + + verify(mTelephonyManager).setMobileDataPolicyEnabled(eq( + TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH), eq(true)); + } + @Test public void getSignalStrengthDrawableWithLevel_carrierNetworkIsNotActive_useMobileDataLevel() { // Fake mobile data level as SIGNAL_STRENGTH_POOR(1) @@ -658,9 +813,9 @@ public class InternetDialogControllerTest extends SysuiTestCase { when(mInternetDialogController.getCarrierNetworkLevel()).thenReturn(WIFI_LEVEL_MAX); InternetDialogController spyController = spy(mInternetDialogController); - spyController.getSignalStrengthDrawableWithLevel(false /* isCarrierNetworkActive */); + spyController.getSignalStrengthDrawableWithLevel(false /* isCarrierNetworkActive */, 0); - verify(spyController).getSignalStrengthIcon(any(), eq(SIGNAL_STRENGTH_POOR), + verify(spyController).getSignalStrengthIcon(eq(0), any(), eq(SIGNAL_STRENGTH_POOR), eq(NUM_SIGNAL_STRENGTH_BINS), anyInt(), anyBoolean()); } @@ -672,9 +827,9 @@ public class InternetDialogControllerTest extends SysuiTestCase { when(mInternetDialogController.getCarrierNetworkLevel()).thenReturn(WIFI_LEVEL_MAX); InternetDialogController spyController = spy(mInternetDialogController); - spyController.getSignalStrengthDrawableWithLevel(true /* isCarrierNetworkActive */); + spyController.getSignalStrengthDrawableWithLevel(true /* isCarrierNetworkActive */, 0); - verify(spyController).getSignalStrengthIcon(any(), eq(WIFI_LEVEL_MAX), + verify(spyController).getSignalStrengthIcon(eq(0), any(), eq(WIFI_LEVEL_MAX), eq(WIFI_LEVEL_MAX + 1), anyInt(), anyBoolean()); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java index f92247580df01..8c8fdc5bf1267 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/InternetDialogTest.java @@ -8,12 +8,15 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.AlertDialog; +import android.content.DialogInterface; import android.os.Handler; import android.telephony.TelephonyManager; import android.testing.AndroidTestingRunner; @@ -31,6 +34,7 @@ import com.android.internal.logging.UiEventLogger; import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils; import com.android.systemui.R; import com.android.systemui.SysuiTestCase; +import com.android.systemui.animation.DialogLaunchAnimator; import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; @@ -72,6 +76,8 @@ public class InternetDialogTest extends SysuiTestCase { private InternetDialogController mInternetDialogController; @Mock private KeyguardStateController mKeyguard; + @Mock + private DialogLaunchAnimator mDialogLaunchAnimator; private FakeExecutor mBgExecutor = new FakeExecutor(new FakeSystemClock()); private InternetDialog mInternetDialog; @@ -100,8 +106,9 @@ public class InternetDialogTest extends SysuiTestCase { when(mInternetWifiEntry.hasInternetAccess()).thenReturn(true); when(mWifiEntries.size()).thenReturn(1); - when(mInternetDialogController.getMobileNetworkTitle()).thenReturn(MOBILE_NETWORK_TITLE); - when(mInternetDialogController.getMobileNetworkSummary()) + when(mInternetDialogController.getMobileNetworkTitle(anyInt())) + .thenReturn(MOBILE_NETWORK_TITLE); + when(mInternetDialogController.getMobileNetworkSummary(anyInt())) .thenReturn(MOBILE_NETWORK_SUMMARY); when(mInternetDialogController.isWifiEnabled()).thenReturn(true); @@ -115,7 +122,8 @@ public class InternetDialogTest extends SysuiTestCase { private void createInternetDialog() { mInternetDialog = new InternetDialog(mContext, mock(InternetDialogFactory.class), - mInternetDialogController, true, true, true, mock(UiEventLogger.class), mHandler, + mInternetDialogController, true, true, true, mock(UiEventLogger.class), + mDialogLaunchAnimator, mHandler, mBgExecutor, mKeyguard); mInternetDialog.mAdapter = mInternetAdapter; mInternetDialog.mConnectedWifiEntry = mInternetWifiEntry; @@ -307,12 +315,18 @@ public class InternetDialogTest extends SysuiTestCase { @Test public void updateDialog_wifiOnAndHasInternetWifi_showConnectedWifi() { + mInternetDialog.dismissDialog(); + doReturn(true).when(mInternetDialogController).hasActiveSubId(); + createInternetDialog(); // The preconditions WiFi ON and Internet WiFi are already in setUp() doReturn(false).when(mInternetDialogController).activeNetworkIsCellular(); - mInternetDialog.updateDialog(false); + mInternetDialog.updateDialog(true); assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.VISIBLE); + LinearLayout secondaryLayout = mDialogView.requireViewById( + R.id.secondary_mobile_network_layout); + assertThat(secondaryLayout.getVisibility()).isEqualTo(View.GONE); } @Test @@ -459,6 +473,45 @@ public class InternetDialogTest extends SysuiTestCase { assertThat(mWifiToggleSummary.getVisibility()).isEqualTo(View.GONE); } + @Test + public void updateDialog_showSecondaryDataSub() { + mInternetDialog.dismissDialog(); + doReturn(1).when(mInternetDialogController).getActiveAutoSwitchNonDdsSubId(); + doReturn(true).when(mInternetDialogController).hasActiveSubId(); + doReturn(false).when(mInternetDialogController).isAirplaneModeEnabled(); + createInternetDialog(); + + clearInvocations(mInternetDialogController); + mInternetDialog.updateDialog(true); + + LinearLayout primaryLayout = mDialogView.requireViewById( + R.id.mobile_network_layout); + LinearLayout secondaryLayout = mDialogView.requireViewById( + R.id.secondary_mobile_network_layout); + + verify(mInternetDialogController).getMobileNetworkSummary(1); + assertThat(primaryLayout.getBackground()).isNotEqualTo(secondaryLayout.getBackground()); + + // Tap the primary sub info + primaryLayout.performClick(); + ArgumentCaptor dialogArgumentCaptor = + ArgumentCaptor.forClass(AlertDialog.class); + verify(mDialogLaunchAnimator).showFromDialog(dialogArgumentCaptor.capture(), + eq(mInternetDialog), eq(null), eq(false)); + AlertDialog dialog = dialogArgumentCaptor.getValue(); + dialog.show(); + dialog.getButton(DialogInterface.BUTTON_POSITIVE).performClick(); + // TODO(b/253399304) + // TestableLooper.get(this).processAllMessages(); + // verify(mInternetDialogController).setAutoDataSwitchMobileDataPolicy(1, false); + + // Tap the secondary sub info + secondaryLayout.performClick(); + verify(mInternetDialogController).launchMobileNetworkSettings(any(View.class)); + + dialog.dismiss(); + } + @Test public void updateDialog_wifiOn_hideWifiScanNotify() { // The preconditions WiFi ON and WiFi entries are already in setUp()