Merge "Add the secondary sub to internet dialog" into tm-qpr-dev
This commit is contained in:
@@ -190,6 +190,11 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ViewStub android:id="@+id/secondary_mobile_network_stub"
|
||||||
|
android:inflatedId="@+id/secondary_mobile_network_layout"
|
||||||
|
android:layout="@layout/qs_dialog_secondary_mobile_network"
|
||||||
|
style="@style/InternetDialog.Network"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/turn_on_wifi_layout"
|
android:id="@+id/turn_on_wifi_layout"
|
||||||
style="@style/InternetDialog.Network"
|
style="@style/InternetDialog.Network"
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright (C) 2021 The Android Open Source Project
|
||||||
|
~
|
||||||
|
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
~ you may not use this file except in compliance with the License.
|
||||||
|
~ You may obtain a copy of the License at
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
~ See the License for the specific language governing permissions and
|
||||||
|
~ limitations under the License.
|
||||||
|
-->
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
style="@style/InternetDialog.Network">
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:clickable="false"
|
||||||
|
android:layout_gravity="center_vertical|start">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/secondary_signal_icon"
|
||||||
|
android:autoMirrored="true"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"/>
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:clickable="false"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="start|center_vertical">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/secondary_mobile_title"
|
||||||
|
android:maxLines="1"
|
||||||
|
style="@style/InternetDialog.NetworkTitle"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/secondary_mobile_summary"
|
||||||
|
style="@style/InternetDialog.NetworkSummary"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:clickable="false"
|
||||||
|
android:layout_gravity="end|center_vertical"
|
||||||
|
android:gravity="center">
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/secondary_settings_icon"
|
||||||
|
android:src="@drawable/ic_settings_24dp"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_gravity="end|center_vertical"
|
||||||
|
android:layout_height="wrap_content"/>
|
||||||
|
</FrameLayout>
|
||||||
|
</LinearLayout>
|
||||||
@@ -2041,6 +2041,15 @@
|
|||||||
<!-- Text used to refer to the user's current carrier in mobile_data_disable_message if the users's mobile network carrier name is not available [CHAR LIMIT=NONE] -->
|
<!-- Text used to refer to the user's current carrier in mobile_data_disable_message if the users's mobile network carrier name is not available [CHAR LIMIT=NONE] -->
|
||||||
<string name="mobile_data_disable_message_default_carrier">your carrier</string>
|
<string name="mobile_data_disable_message_default_carrier">your carrier</string>
|
||||||
|
|
||||||
|
<!-- Title of the dialog to turn off data usage [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="auto_data_switch_disable_title">Switch back to <xliff:g id="carrier" example="T-Mobile">%s</xliff:g>?</string>
|
||||||
|
<!-- Message body of the dialog to turn off data usage [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="auto_data_switch_disable_message">Mobile data won\’t automatically switch based on availability</string>
|
||||||
|
<!-- Negative button title of the quick settings switch back to DDS dialog [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="auto_data_switch_dialog_negative_button">No thanks</string>
|
||||||
|
<!-- Positive button title of the quick settings switch back to DDS dialog [CHAR LIMIT=NONE] -->
|
||||||
|
<string name="auto_data_switch_dialog_positive_button">Yes, switch</string>
|
||||||
|
|
||||||
<!-- Warning shown when user input has been blocked due to another app overlaying screen
|
<!-- Warning shown when user input has been blocked due to another app overlaying screen
|
||||||
content. Since we don't know what the app is showing on top of the input target, we
|
content. Since we don't know what the app is showing on top of the input target, we
|
||||||
can't verify user consent. [CHAR LIMIT=NONE] -->
|
can't verify user consent. [CHAR LIMIT=NONE] -->
|
||||||
@@ -2510,6 +2519,12 @@
|
|||||||
<!-- Provider Model:
|
<!-- Provider Model:
|
||||||
Summary indicating that a SIM has an active mobile data connection [CHAR LIMIT=50] -->
|
Summary indicating that a SIM has an active mobile data connection [CHAR LIMIT=50] -->
|
||||||
<string name="mobile_data_connection_active">Connected</string>
|
<string name="mobile_data_connection_active">Connected</string>
|
||||||
|
<!-- Provider Model:
|
||||||
|
Summary indicating that a SIM is temporarily connected to mobile data [CHAR LIMIT=50] -->
|
||||||
|
<string name="mobile_data_temp_connection_active">Temporarily connected</string>
|
||||||
|
<!-- Provider Model:
|
||||||
|
Summary indicating that a SIM is temporarily connected to mobile data [CHAR LIMIT=50] -->
|
||||||
|
<string name="mobile_data_poor_connection">Poor connection</string>
|
||||||
<!-- Provider Model:
|
<!-- Provider Model:
|
||||||
Summary indicating that a SIM has no mobile data connection [CHAR LIMIT=50] -->
|
Summary indicating that a SIM has no mobile data connection [CHAR LIMIT=50] -->
|
||||||
<string name="mobile_data_off_summary">Mobile data won\u0027t auto\u2011connect</string>
|
<string name="mobile_data_off_summary">Mobile data won\u0027t auto\u2011connect</string>
|
||||||
|
|||||||
@@ -205,6 +205,9 @@ object Flags {
|
|||||||
val QS_SECONDARY_DATA_SUB_INFO =
|
val QS_SECONDARY_DATA_SUB_INFO =
|
||||||
unreleasedFlag(508, "qs_secondary_data_sub_info", teamfood = true)
|
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
|
// 600- status bar
|
||||||
// TODO(b/254513246): Tracking Bug
|
// TODO(b/254513246): Tracking Bug
|
||||||
val STATUS_BAR_USER_SWITCHER =
|
val STATUS_BAR_USER_SWITCHER =
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import android.util.Log;
|
|||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewStub;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
@@ -62,6 +63,7 @@ import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils;
|
|||||||
import com.android.systemui.Prefs;
|
import com.android.systemui.Prefs;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.accessibility.floatingmenu.AnnotationLinkSpan;
|
import com.android.systemui.accessibility.floatingmenu.AnnotationLinkSpan;
|
||||||
|
import com.android.systemui.animation.DialogLaunchAnimator;
|
||||||
import com.android.systemui.dagger.SysUISingleton;
|
import com.android.systemui.dagger.SysUISingleton;
|
||||||
import com.android.systemui.dagger.qualifiers.Background;
|
import com.android.systemui.dagger.qualifiers.Background;
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
import com.android.systemui.dagger.qualifiers.Main;
|
||||||
@@ -72,6 +74,8 @@ import com.android.wifitrackerlib.WifiEntry;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialog for showing mobile network, connected Wi-Fi network and Wi-Fi networks.
|
* 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 Handler mHandler;
|
||||||
private final Executor mBackgroundExecutor;
|
private final Executor mBackgroundExecutor;
|
||||||
|
private final DialogLaunchAnimator mDialogLaunchAnimator;
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
protected InternetAdapter mAdapter;
|
protected InternetAdapter mAdapter;
|
||||||
@@ -109,6 +114,7 @@ public class InternetDialog extends SystemUIDialog implements
|
|||||||
private LinearLayout mInternetDialogLayout;
|
private LinearLayout mInternetDialogLayout;
|
||||||
private LinearLayout mConnectedWifListLayout;
|
private LinearLayout mConnectedWifListLayout;
|
||||||
private LinearLayout mMobileNetworkLayout;
|
private LinearLayout mMobileNetworkLayout;
|
||||||
|
private LinearLayout mSecondaryMobileNetworkLayout;
|
||||||
private LinearLayout mTurnWifiOnLayout;
|
private LinearLayout mTurnWifiOnLayout;
|
||||||
private LinearLayout mEthernetLayout;
|
private LinearLayout mEthernetLayout;
|
||||||
private TextView mWifiToggleTitleText;
|
private TextView mWifiToggleTitleText;
|
||||||
@@ -123,6 +129,8 @@ public class InternetDialog extends SystemUIDialog implements
|
|||||||
private ImageView mSignalIcon;
|
private ImageView mSignalIcon;
|
||||||
private TextView mMobileTitleText;
|
private TextView mMobileTitleText;
|
||||||
private TextView mMobileSummaryText;
|
private TextView mMobileSummaryText;
|
||||||
|
private TextView mSecondaryMobileTitleText;
|
||||||
|
private TextView mSecondaryMobileSummaryText;
|
||||||
private TextView mAirplaneModeSummaryText;
|
private TextView mAirplaneModeSummaryText;
|
||||||
private Switch mMobileDataToggle;
|
private Switch mMobileDataToggle;
|
||||||
private View mMobileToggleDivider;
|
private View mMobileToggleDivider;
|
||||||
@@ -158,9 +166,11 @@ public class InternetDialog extends SystemUIDialog implements
|
|||||||
mInternetDialogSubTitle.setText(getSubtitleText());
|
mInternetDialogSubTitle.setText(getSubtitleText());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@Inject
|
||||||
public InternetDialog(Context context, InternetDialogFactory internetDialogFactory,
|
public InternetDialog(Context context, InternetDialogFactory internetDialogFactory,
|
||||||
InternetDialogController internetDialogController, boolean canConfigMobileData,
|
InternetDialogController internetDialogController, boolean canConfigMobileData,
|
||||||
boolean canConfigWifi, boolean aboveStatusBar, UiEventLogger uiEventLogger,
|
boolean canConfigWifi, boolean aboveStatusBar, UiEventLogger uiEventLogger,
|
||||||
|
DialogLaunchAnimator dialogLaunchAnimator,
|
||||||
@Main Handler handler, @Background Executor executor,
|
@Main Handler handler, @Background Executor executor,
|
||||||
KeyguardStateController keyguardStateController) {
|
KeyguardStateController keyguardStateController) {
|
||||||
super(context);
|
super(context);
|
||||||
@@ -183,6 +193,7 @@ public class InternetDialog extends SystemUIDialog implements
|
|||||||
mKeyguard = keyguardStateController;
|
mKeyguard = keyguardStateController;
|
||||||
|
|
||||||
mUiEventLogger = uiEventLogger;
|
mUiEventLogger = uiEventLogger;
|
||||||
|
mDialogLaunchAnimator = dialogLaunchAnimator;
|
||||||
mAdapter = new InternetAdapter(mInternetDialogController);
|
mAdapter = new InternetAdapter(mInternetDialogController);
|
||||||
if (!aboveStatusBar) {
|
if (!aboveStatusBar) {
|
||||||
getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
|
getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
|
||||||
@@ -287,6 +298,9 @@ public class InternetDialog extends SystemUIDialog implements
|
|||||||
mMobileNetworkLayout.setOnClickListener(null);
|
mMobileNetworkLayout.setOnClickListener(null);
|
||||||
mMobileDataToggle.setOnCheckedChangeListener(null);
|
mMobileDataToggle.setOnCheckedChangeListener(null);
|
||||||
mConnectedWifListLayout.setOnClickListener(null);
|
mConnectedWifListLayout.setOnClickListener(null);
|
||||||
|
if (mSecondaryMobileNetworkLayout != null) {
|
||||||
|
mSecondaryMobileNetworkLayout.setOnClickListener(null);
|
||||||
|
}
|
||||||
mSeeAllLayout.setOnClickListener(null);
|
mSeeAllLayout.setOnClickListener(null);
|
||||||
mWiFiToggle.setOnCheckedChangeListener(null);
|
mWiFiToggle.setOnCheckedChangeListener(null);
|
||||||
mDoneButton.setOnClickListener(null);
|
mDoneButton.setOnClickListener(null);
|
||||||
@@ -341,6 +355,10 @@ public class InternetDialog extends SystemUIDialog implements
|
|||||||
|
|
||||||
private void setOnClickListener() {
|
private void setOnClickListener() {
|
||||||
mMobileNetworkLayout.setOnClickListener(v -> {
|
mMobileNetworkLayout.setOnClickListener(v -> {
|
||||||
|
int autoSwitchNonDdsSubId = mInternetDialogController.getActiveAutoSwitchNonDdsSubId();
|
||||||
|
if (autoSwitchNonDdsSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||||
|
showTurnOffAutoDataSwitchDialog(autoSwitchNonDdsSubId);
|
||||||
|
}
|
||||||
if (mInternetDialogController.isMobileDataEnabled()
|
if (mInternetDialogController.isMobileDataEnabled()
|
||||||
&& !mInternetDialogController.isDeviceLocked()) {
|
&& !mInternetDialogController.isDeviceLocked()) {
|
||||||
if (!mInternetDialogController.activeNetworkIsCellular()) {
|
if (!mInternetDialogController.activeNetworkIsCellular()) {
|
||||||
@@ -390,11 +408,14 @@ public class InternetDialog extends SystemUIDialog implements
|
|||||||
if (!mInternetDialogController.hasActiveSubId()
|
if (!mInternetDialogController.hasActiveSubId()
|
||||||
&& (!isWifiEnabled || !isCarrierNetworkActive)) {
|
&& (!isWifiEnabled || !isCarrierNetworkActive)) {
|
||||||
mMobileNetworkLayout.setVisibility(View.GONE);
|
mMobileNetworkLayout.setVisibility(View.GONE);
|
||||||
|
if (mSecondaryMobileNetworkLayout != null) {
|
||||||
|
mSecondaryMobileNetworkLayout.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mMobileNetworkLayout.setVisibility(View.VISIBLE);
|
mMobileNetworkLayout.setVisibility(View.VISIBLE);
|
||||||
mMobileDataToggle.setChecked(mInternetDialogController.isMobileDataEnabled());
|
mMobileDataToggle.setChecked(mInternetDialogController.isMobileDataEnabled());
|
||||||
mMobileTitleText.setText(getMobileNetworkTitle());
|
mMobileTitleText.setText(getMobileNetworkTitle(mDefaultDataSubId));
|
||||||
String summary = getMobileNetworkSummary();
|
String summary = getMobileNetworkSummary(mDefaultDataSubId);
|
||||||
if (!TextUtils.isEmpty(summary)) {
|
if (!TextUtils.isEmpty(summary)) {
|
||||||
mMobileSummaryText.setText(
|
mMobileSummaryText.setText(
|
||||||
Html.fromHtml(summary, Html.FROM_HTML_MODE_LEGACY));
|
Html.fromHtml(summary, Html.FROM_HTML_MODE_LEGACY));
|
||||||
@@ -404,28 +425,11 @@ public class InternetDialog extends SystemUIDialog implements
|
|||||||
mMobileSummaryText.setVisibility(View.GONE);
|
mMobileSummaryText.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
mBackgroundExecutor.execute(() -> {
|
mBackgroundExecutor.execute(() -> {
|
||||||
Drawable drawable = getSignalStrengthDrawable();
|
Drawable drawable = getSignalStrengthDrawable(mDefaultDataSubId);
|
||||||
mHandler.post(() -> {
|
mHandler.post(() -> {
|
||||||
mSignalIcon.setImageDrawable(drawable);
|
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(
|
TypedArray array = mContext.obtainStyledAttributes(
|
||||||
R.style.InternetDialog_Divider_Active, new int[]{android.R.attr.background});
|
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);
|
mMobileDataToggle.setVisibility(mCanConfigMobileData ? View.VISIBLE : View.INVISIBLE);
|
||||||
mMobileToggleDivider.setVisibility(
|
mMobileToggleDivider.setVisibility(
|
||||||
mCanConfigMobileData ? View.VISIBLE : View.INVISIBLE);
|
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));
|
mInternetDialogController.getInternetWifiDrawable(mConnectedWifiEntry));
|
||||||
mWifiSettingsIcon.setColorFilter(
|
mWifiSettingsIcon.setColorFilter(
|
||||||
mContext.getColor(R.color.connected_network_primary_color));
|
mContext.getColor(R.color.connected_network_primary_color));
|
||||||
|
|
||||||
|
if (mSecondaryMobileNetworkLayout != null) {
|
||||||
|
mSecondaryMobileNetworkLayout.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainThread
|
@MainThread
|
||||||
@@ -546,6 +634,11 @@ public class InternetDialog extends SystemUIDialog implements
|
|||||||
mInternetDialogController.launchWifiDetailsSetting(mConnectedWifiEntry.getKey(), view);
|
mInternetDialogController.launchWifiDetailsSetting(mConnectedWifiEntry.getKey(), view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** For DSDS auto data switch **/
|
||||||
|
void onClickConnectedSecondarySub(View view) {
|
||||||
|
mInternetDialogController.launchMobileNetworkSettings(view);
|
||||||
|
}
|
||||||
|
|
||||||
void onClickSeeMoreButton(View view) {
|
void onClickSeeMoreButton(View view) {
|
||||||
mInternetDialogController.launchNetworkSetting(view);
|
mInternetDialogController.launchNetworkSetting(view);
|
||||||
}
|
}
|
||||||
@@ -560,16 +653,16 @@ public class InternetDialog extends SystemUIDialog implements
|
|||||||
mIsProgressBarVisible && !mIsSearchingHidden);
|
mIsProgressBarVisible && !mIsSearchingHidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Drawable getSignalStrengthDrawable() {
|
private Drawable getSignalStrengthDrawable(int subId) {
|
||||||
return mInternetDialogController.getSignalStrengthDrawable();
|
return mInternetDialogController.getSignalStrengthDrawable(subId);
|
||||||
}
|
}
|
||||||
|
|
||||||
CharSequence getMobileNetworkTitle() {
|
CharSequence getMobileNetworkTitle(int subId) {
|
||||||
return mInternetDialogController.getMobileNetworkTitle();
|
return mInternetDialogController.getMobileNetworkTitle(subId);
|
||||||
}
|
}
|
||||||
|
|
||||||
String getMobileNetworkSummary() {
|
String getMobileNetworkSummary(int subId) {
|
||||||
return mInternetDialogController.getMobileNetworkSummary();
|
return mInternetDialogController.getMobileNetworkSummary(subId);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void showProgressBar() {
|
protected void showProgressBar() {
|
||||||
@@ -607,8 +700,8 @@ public class InternetDialog extends SystemUIDialog implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void showTurnOffMobileDialog() {
|
private void showTurnOffMobileDialog() {
|
||||||
CharSequence carrierName = getMobileNetworkTitle();
|
CharSequence carrierName = getMobileNetworkTitle(mDefaultDataSubId);
|
||||||
boolean isInService = mInternetDialogController.isVoiceStateInService();
|
boolean isInService = mInternetDialogController.isVoiceStateInService(mDefaultDataSubId);
|
||||||
if (TextUtils.isEmpty(carrierName) || !isInService) {
|
if (TextUtils.isEmpty(carrierName) || !isInService) {
|
||||||
carrierName = mContext.getString(R.string.mobile_data_disable_message_default_carrier);
|
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.setShowForAllUsers(mAlertDialog, true);
|
||||||
SystemUIDialog.registerDismissListener(mAlertDialog);
|
SystemUIDialog.registerDismissListener(mAlertDialog);
|
||||||
SystemUIDialog.setWindowOnTop(mAlertDialog, mKeyguard.isShowing());
|
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
|
@Override
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import android.net.ConnectivityManager;
|
|||||||
import android.net.Network;
|
import android.net.Network;
|
||||||
import android.net.NetworkCapabilities;
|
import android.net.NetworkCapabilities;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
@@ -78,6 +79,8 @@ import com.android.systemui.animation.DialogLaunchAnimator;
|
|||||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||||
import com.android.systemui.dagger.qualifiers.Background;
|
import com.android.systemui.dagger.qualifiers.Background;
|
||||||
import com.android.systemui.dagger.qualifiers.Main;
|
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.plugins.ActivityStarter;
|
||||||
import com.android.systemui.statusbar.connectivity.AccessPointController;
|
import com.android.systemui.statusbar.connectivity.AccessPointController;
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||||
@@ -90,6 +93,7 @@ import com.android.wifitrackerlib.MergedCarrierEntry;
|
|||||||
import com.android.wifitrackerlib.WifiEntry;
|
import com.android.wifitrackerlib.WifiEntry;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -113,6 +117,17 @@ public class InternetDialogController implements AccessPointController.AccessPoi
|
|||||||
"android.settings.NETWORK_PROVIDER_SETTINGS";
|
"android.settings.NETWORK_PROVIDER_SETTINGS";
|
||||||
private static final String ACTION_WIFI_SCANNING_SETTINGS =
|
private static final String ACTION_WIFI_SCANNING_SETTINGS =
|
||||||
"android.settings.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 Drawable EMPTY_DRAWABLE = new ColorDrawable(Color.TRANSPARENT);
|
||||||
public static final int NO_CELL_DATA_TYPE_ICON = 0;
|
public static final int NO_CELL_DATA_TYPE_ICON = 0;
|
||||||
private static final int SUBTITLE_TEXT_WIFI_IS_OFF = R.string.wifi_is_off;
|
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;
|
static final int MAX_WIFI_ENTRY_COUNT = 3;
|
||||||
|
|
||||||
|
private final FeatureFlags mFeatureFlags;
|
||||||
|
|
||||||
private WifiManager mWifiManager;
|
private WifiManager mWifiManager;
|
||||||
private Context mContext;
|
private Context mContext;
|
||||||
private SubscriptionManager mSubscriptionManager;
|
private SubscriptionManager mSubscriptionManager;
|
||||||
|
private Map<Integer, TelephonyManager> mSubIdTelephonyManagerMap = new HashMap<>();
|
||||||
private TelephonyManager mTelephonyManager;
|
private TelephonyManager mTelephonyManager;
|
||||||
private ConnectivityManager mConnectivityManager;
|
private ConnectivityManager mConnectivityManager;
|
||||||
private CarrierConfigTracker mCarrierConfigTracker;
|
private CarrierConfigTracker mCarrierConfigTracker;
|
||||||
@@ -155,6 +173,7 @@ public class InternetDialogController implements AccessPointController.AccessPoi
|
|||||||
private WindowManager mWindowManager;
|
private WindowManager mWindowManager;
|
||||||
private ToastFactory mToastFactory;
|
private ToastFactory mToastFactory;
|
||||||
private SignalDrawable mSignalDrawable;
|
private SignalDrawable mSignalDrawable;
|
||||||
|
private SignalDrawable mSecondarySignalDrawable; // For the secondary mobile data sub in DSDS
|
||||||
private LocationController mLocationController;
|
private LocationController mLocationController;
|
||||||
private DialogLaunchAnimator mDialogLaunchAnimator;
|
private DialogLaunchAnimator mDialogLaunchAnimator;
|
||||||
private boolean mHasWifiEntries;
|
private boolean mHasWifiEntries;
|
||||||
@@ -213,7 +232,8 @@ public class InternetDialogController implements AccessPointController.AccessPoi
|
|||||||
CarrierConfigTracker carrierConfigTracker,
|
CarrierConfigTracker carrierConfigTracker,
|
||||||
LocationController locationController,
|
LocationController locationController,
|
||||||
DialogLaunchAnimator dialogLaunchAnimator,
|
DialogLaunchAnimator dialogLaunchAnimator,
|
||||||
WifiStateWorker wifiStateWorker
|
WifiStateWorker wifiStateWorker,
|
||||||
|
FeatureFlags featureFlags
|
||||||
) {
|
) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "Init InternetDialogController");
|
Log.d(TAG, "Init InternetDialogController");
|
||||||
@@ -242,10 +262,12 @@ public class InternetDialogController implements AccessPointController.AccessPoi
|
|||||||
mWindowManager = windowManager;
|
mWindowManager = windowManager;
|
||||||
mToastFactory = toastFactory;
|
mToastFactory = toastFactory;
|
||||||
mSignalDrawable = new SignalDrawable(mContext);
|
mSignalDrawable = new SignalDrawable(mContext);
|
||||||
|
mSecondarySignalDrawable = new SignalDrawable(mContext);
|
||||||
mLocationController = locationController;
|
mLocationController = locationController;
|
||||||
mDialogLaunchAnimator = dialogLaunchAnimator;
|
mDialogLaunchAnimator = dialogLaunchAnimator;
|
||||||
mConnectedWifiInternetMonitor = new ConnectedWifiInternetMonitor();
|
mConnectedWifiInternetMonitor = new ConnectedWifiInternetMonitor();
|
||||||
mWifiStateWorker = wifiStateWorker;
|
mWifiStateWorker = wifiStateWorker;
|
||||||
|
mFeatureFlags = featureFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
void onStart(@NonNull InternetDialogCallback callback, boolean canConfigWifi) {
|
void onStart(@NonNull InternetDialogCallback callback, boolean canConfigWifi) {
|
||||||
@@ -267,6 +289,7 @@ public class InternetDialogController implements AccessPointController.AccessPoi
|
|||||||
}
|
}
|
||||||
mConfig = MobileMappings.Config.readConfig(mContext);
|
mConfig = MobileMappings.Config.readConfig(mContext);
|
||||||
mTelephonyManager = mTelephonyManager.createForSubscriptionId(mDefaultDataSubId);
|
mTelephonyManager = mTelephonyManager.createForSubscriptionId(mDefaultDataSubId);
|
||||||
|
mSubIdTelephonyManagerMap.put(mDefaultDataSubId, mTelephonyManager);
|
||||||
mInternetTelephonyCallback = new InternetTelephonyCallback();
|
mInternetTelephonyCallback = new InternetTelephonyCallback();
|
||||||
mTelephonyManager.registerTelephonyCallback(mExecutor, mInternetTelephonyCallback);
|
mTelephonyManager.registerTelephonyCallback(mExecutor, mInternetTelephonyCallback);
|
||||||
// Listen the connectivity changes
|
// Listen the connectivity changes
|
||||||
@@ -280,7 +303,9 @@ public class InternetDialogController implements AccessPointController.AccessPoi
|
|||||||
Log.d(TAG, "onStop");
|
Log.d(TAG, "onStop");
|
||||||
}
|
}
|
||||||
mBroadcastDispatcher.unregisterReceiver(mConnectionStateReceiver);
|
mBroadcastDispatcher.unregisterReceiver(mConnectionStateReceiver);
|
||||||
mTelephonyManager.unregisterTelephonyCallback(mInternetTelephonyCallback);
|
for (TelephonyManager tm : mSubIdTelephonyManagerMap.values()) {
|
||||||
|
tm.unregisterTelephonyCallback(mInternetTelephonyCallback);
|
||||||
|
}
|
||||||
mSubscriptionManager.removeOnSubscriptionsChangedListener(
|
mSubscriptionManager.removeOnSubscriptionsChangedListener(
|
||||||
mOnSubscriptionsChangedListener);
|
mOnSubscriptionsChangedListener);
|
||||||
mAccessPointController.removeAccessPointCallback(this);
|
mAccessPointController.removeAccessPointCallback(this);
|
||||||
@@ -371,7 +396,10 @@ public class InternetDialogController implements AccessPointController.AccessPoi
|
|||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "No Wi-Fi item.");
|
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) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "No carrier or service is out of service.");
|
Log.d(TAG, "No carrier or service is out of service.");
|
||||||
}
|
}
|
||||||
@@ -412,7 +440,7 @@ public class InternetDialogController implements AccessPointController.AccessPoi
|
|||||||
return drawable;
|
return drawable;
|
||||||
}
|
}
|
||||||
|
|
||||||
Drawable getSignalStrengthDrawable() {
|
Drawable getSignalStrengthDrawable(int subId) {
|
||||||
Drawable drawable = mContext.getDrawable(
|
Drawable drawable = mContext.getDrawable(
|
||||||
R.drawable.ic_signal_strength_zero_bar_no_internet);
|
R.drawable.ic_signal_strength_zero_bar_no_internet);
|
||||||
try {
|
try {
|
||||||
@@ -424,9 +452,10 @@ public class InternetDialogController implements AccessPointController.AccessPoi
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean isCarrierNetworkActive = isCarrierNetworkActive();
|
boolean isCarrierNetworkActive = isCarrierNetworkActive();
|
||||||
if (isDataStateInService() || isVoiceStateInService() || isCarrierNetworkActive) {
|
if (isDataStateInService(subId) || isVoiceStateInService(subId)
|
||||||
|
|| isCarrierNetworkActive) {
|
||||||
AtomicReference<Drawable> shared = new AtomicReference<>();
|
AtomicReference<Drawable> shared = new AtomicReference<>();
|
||||||
shared.set(getSignalStrengthDrawableWithLevel(isCarrierNetworkActive));
|
shared.set(getSignalStrengthDrawableWithLevel(isCarrierNetworkActive, subId));
|
||||||
drawable = shared.get();
|
drawable = shared.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -447,24 +476,30 @@ public class InternetDialogController implements AccessPointController.AccessPoi
|
|||||||
*
|
*
|
||||||
* @return The Drawable which is a signal bar icon with level.
|
* @return The Drawable which is a signal bar icon with level.
|
||||||
*/
|
*/
|
||||||
Drawable getSignalStrengthDrawableWithLevel(boolean isCarrierNetworkActive) {
|
Drawable getSignalStrengthDrawableWithLevel(boolean isCarrierNetworkActive, int subId) {
|
||||||
final SignalStrength strength = mTelephonyManager.getSignalStrength();
|
TelephonyManager tm = mSubIdTelephonyManagerMap.getOrDefault(subId, mTelephonyManager);
|
||||||
|
final SignalStrength strength = tm.getSignalStrength();
|
||||||
int level = (strength == null) ? 0 : strength.getLevel();
|
int level = (strength == null) ? 0 : strength.getLevel();
|
||||||
int numLevels = SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
|
int numLevels = SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
|
||||||
if (isCarrierNetworkActive) {
|
if (isCarrierNetworkActive) {
|
||||||
level = getCarrierNetworkLevel();
|
level = getCarrierNetworkLevel();
|
||||||
numLevels = WifiEntry.WIFI_LEVEL_MAX + 1;
|
numLevels = WifiEntry.WIFI_LEVEL_MAX + 1;
|
||||||
} else if (mSubscriptionManager != null && shouldInflateSignalStrength(mDefaultDataSubId)) {
|
} else if (mSubscriptionManager != null && shouldInflateSignalStrength(subId)) {
|
||||||
level += 1;
|
level += 1;
|
||||||
numLevels += 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());
|
!isMobileDataEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
Drawable getSignalStrengthIcon(Context context, int level, int numLevels,
|
Drawable getSignalStrengthIcon(int subId, Context context, int level, int numLevels,
|
||||||
int iconType, boolean cutOut) {
|
int iconType, boolean cutOut) {
|
||||||
|
boolean isForDds = subId == mDefaultDataSubId;
|
||||||
|
if (isForDds) {
|
||||||
mSignalDrawable.setLevel(SignalDrawable.getState(level, numLevels, cutOut));
|
mSignalDrawable.setLevel(SignalDrawable.getState(level, numLevels, cutOut));
|
||||||
|
} else {
|
||||||
|
mSecondarySignalDrawable.setLevel(SignalDrawable.getState(level, numLevels, cutOut));
|
||||||
|
}
|
||||||
|
|
||||||
// Make the network type drawable
|
// Make the network type drawable
|
||||||
final Drawable networkDrawable =
|
final Drawable networkDrawable =
|
||||||
@@ -473,7 +508,8 @@ public class InternetDialogController implements AccessPointController.AccessPoi
|
|||||||
: context.getResources().getDrawable(iconType, context.getTheme());
|
: context.getResources().getDrawable(iconType, context.getTheme());
|
||||||
|
|
||||||
// Overlay the two drawables
|
// Overlay the two drawables
|
||||||
final Drawable[] layers = {networkDrawable, mSignalDrawable};
|
final Drawable[] layers = {networkDrawable, isForDds
|
||||||
|
? mSignalDrawable : mSecondarySignalDrawable};
|
||||||
final int iconSize =
|
final int iconSize =
|
||||||
context.getResources().getDimensionPixelSize(R.dimen.signal_strength_icon_size);
|
context.getResources().getDimensionPixelSize(R.dimen.signal_strength_icon_size);
|
||||||
|
|
||||||
@@ -571,14 +607,39 @@ public class InternetDialogController implements AccessPointController.AccessPoi
|
|||||||
info -> info.uniqueName));
|
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,
|
String description = getNetworkTypeDescription(mContext, mConfig,
|
||||||
mTelephonyDisplayInfo, mDefaultDataSubId);
|
mTelephonyDisplayInfo, subId);
|
||||||
return getMobileSummary(mContext, description);
|
return getMobileSummary(mContext, description, subId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -606,22 +667,28 @@ public class InternetDialogController implements AccessPointController.AccessPoi
|
|||||||
? SubscriptionManager.getResourcesForSubId(context, subId).getString(resId) : "";
|
? SubscriptionManager.getResourcesForSubId(context, subId).getString(resId) : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getMobileSummary(Context context, String networkTypeDescription) {
|
private String getMobileSummary(Context context, String networkTypeDescription, int subId) {
|
||||||
if (!isMobileDataEnabled()) {
|
if (!isMobileDataEnabled()) {
|
||||||
return context.getString(R.string.mobile_data_off_summary);
|
return context.getString(R.string.mobile_data_off_summary);
|
||||||
}
|
}
|
||||||
|
|
||||||
String summary = networkTypeDescription;
|
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
|
// Set network description for the carrier network when connecting to the carrier network
|
||||||
// under the airplane mode ON.
|
// under the airplane mode ON.
|
||||||
if (activeNetworkIsCellular() || isCarrierNetworkActive()) {
|
if (activeNetworkIsCellular() || isCarrierNetworkActive()) {
|
||||||
summary = context.getString(R.string.preference_summary_default_combination,
|
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);
|
networkTypeDescription);
|
||||||
} else if (!isDataStateInService()) {
|
} else if (!isDataStateInService(subId)) {
|
||||||
summary = context.getString(R.string.mobile_data_no_connection);
|
summary = context.getString(R.string.mobile_data_no_connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
return summary;
|
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) {
|
void launchWifiScanningSetting(View view) {
|
||||||
final Intent intent = new Intent(ACTION_WIFI_SCANNING_SETTINGS);
|
final Intent intent = new Intent(ACTION_WIFI_SCANNING_SETTINGS);
|
||||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
@@ -796,8 +883,20 @@ public class InternetDialogController implements AccessPointController.AccessPoi
|
|||||||
mWorkerHandler.post(() -> setMergedCarrierWifiEnabledIfNeed(subId, enabled));
|
mWorkerHandler.post(() -> setMergedCarrierWifiEnabledIfNeed(subId, enabled));
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isDataStateInService() {
|
void setAutoDataSwitchMobileDataPolicy(int subId, boolean enable) {
|
||||||
final ServiceState serviceState = mTelephonyManager.getServiceState();
|
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 =
|
NetworkRegistrationInfo regInfo =
|
||||||
(serviceState == null) ? null : serviceState.getNetworkRegistrationInfo(
|
(serviceState == null) ? null : serviceState.getNetworkRegistrationInfo(
|
||||||
NetworkRegistrationInfo.DOMAIN_PS,
|
NetworkRegistrationInfo.DOMAIN_PS,
|
||||||
@@ -805,7 +904,7 @@ public class InternetDialogController implements AccessPointController.AccessPoi
|
|||||||
return (regInfo == null) ? false : regInfo.isRegistered();
|
return (regInfo == null) ? false : regInfo.isRegistered();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isVoiceStateInService() {
|
boolean isVoiceStateInService(int subId) {
|
||||||
if (mTelephonyManager == null) {
|
if (mTelephonyManager == null) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "TelephonyManager is null, can not detect voice state.");
|
Log.d(TAG, "TelephonyManager is null, can not detect voice state.");
|
||||||
@@ -813,7 +912,8 @@ public class InternetDialogController implements AccessPointController.AccessPoi
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final ServiceState serviceState = mTelephonyManager.getServiceState();
|
TelephonyManager tm = mSubIdTelephonyManagerMap.getOrDefault(subId, mTelephonyManager);
|
||||||
|
final ServiceState serviceState = tm.getServiceState();
|
||||||
return serviceState != null
|
return serviceState != null
|
||||||
&& serviceState.getState() == serviceState.STATE_IN_SERVICE;
|
&& serviceState.getState() == serviceState.STATE_IN_SERVICE;
|
||||||
}
|
}
|
||||||
@@ -1104,6 +1204,7 @@ public class InternetDialogController implements AccessPointController.AccessPoi
|
|||||||
if (SubscriptionManager.isUsableSubscriptionId(mDefaultDataSubId)) {
|
if (SubscriptionManager.isUsableSubscriptionId(mDefaultDataSubId)) {
|
||||||
mTelephonyManager.unregisterTelephonyCallback(mInternetTelephonyCallback);
|
mTelephonyManager.unregisterTelephonyCallback(mInternetTelephonyCallback);
|
||||||
mTelephonyManager = mTelephonyManager.createForSubscriptionId(mDefaultDataSubId);
|
mTelephonyManager = mTelephonyManager.createForSubscriptionId(mDefaultDataSubId);
|
||||||
|
mSubIdTelephonyManagerMap.put(mDefaultDataSubId, mTelephonyManager);
|
||||||
mTelephonyManager.registerTelephonyCallback(mHandler::post,
|
mTelephonyManager.registerTelephonyCallback(mHandler::post,
|
||||||
mInternetTelephonyCallback);
|
mInternetTelephonyCallback);
|
||||||
mCallback.onSubscriptionsChanged(mDefaultDataSubId);
|
mCallback.onSubscriptionsChanged(mDefaultDataSubId);
|
||||||
|
|||||||
@@ -66,7 +66,8 @@ class InternetDialogFactory @Inject constructor(
|
|||||||
} else {
|
} else {
|
||||||
internetDialog = InternetDialog(
|
internetDialog = InternetDialog(
|
||||||
context, this, internetDialogController,
|
context, this, internetDialogController,
|
||||||
canConfigMobileData, canConfigWifi, aboveStatusBar, uiEventLogger, handler,
|
canConfigMobileData, canConfigWifi, aboveStatusBar, uiEventLogger,
|
||||||
|
dialogLaunchAnimator, handler,
|
||||||
executor, keyguardStateController
|
executor, keyguardStateController
|
||||||
)
|
)
|
||||||
if (view != null) {
|
if (view != null) {
|
||||||
|
|||||||
@@ -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_GREAT;
|
||||||
import static android.telephony.SignalStrength.SIGNAL_STRENGTH_POOR;
|
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_HORIZONTAL_WEIGHT;
|
||||||
import static com.android.systemui.qs.tiles.dialog.InternetDialogController.TOAST_PARAMS_VERTICAL_WEIGHT;
|
import static com.android.systemui.qs.tiles.dialog.InternetDialogController.TOAST_PARAMS_VERTICAL_WEIGHT;
|
||||||
import static com.android.wifitrackerlib.WifiEntry.WIFI_LEVEL_MAX;
|
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 com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
@@ -36,6 +38,7 @@ import android.net.wifi.WifiManager;
|
|||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.telephony.ServiceState;
|
import android.telephony.ServiceState;
|
||||||
import android.telephony.SignalStrength;
|
import android.telephony.SignalStrength;
|
||||||
|
import android.telephony.SubscriptionInfo;
|
||||||
import android.telephony.SubscriptionManager;
|
import android.telephony.SubscriptionManager;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.testing.AndroidTestingRunner;
|
import android.testing.AndroidTestingRunner;
|
||||||
@@ -55,6 +58,8 @@ import com.android.systemui.R;
|
|||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
import com.android.systemui.animation.DialogLaunchAnimator;
|
import com.android.systemui.animation.DialogLaunchAnimator;
|
||||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
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.plugins.ActivityStarter;
|
||||||
import com.android.systemui.statusbar.connectivity.AccessPointController;
|
import com.android.systemui.statusbar.connectivity.AccessPointController;
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
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.MergedCarrierEntry;
|
||||||
import com.android.wifitrackerlib.WifiEntry;
|
import com.android.wifitrackerlib.WifiEntry;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.mockito.MockitoSession;
|
||||||
|
import org.mockito.quality.Strictness;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -84,6 +92,9 @@ import java.util.List;
|
|||||||
public class InternetDialogControllerTest extends SysuiTestCase {
|
public class InternetDialogControllerTest extends SysuiTestCase {
|
||||||
|
|
||||||
private static final int SUB_ID = 1;
|
private static final int SUB_ID = 1;
|
||||||
|
private static final int SUB_ID2 = 2;
|
||||||
|
|
||||||
|
private MockitoSession mStaticMockSession;
|
||||||
|
|
||||||
//SystemUIToast
|
//SystemUIToast
|
||||||
private static final int GRAVITY_FLAGS = Gravity.FILL_HORIZONTAL | Gravity.FILL_VERTICAL;
|
private static final int GRAVITY_FLAGS = Gravity.FILL_HORIZONTAL | Gravity.FILL_VERTICAL;
|
||||||
@@ -150,6 +161,8 @@ public class InternetDialogControllerTest extends SysuiTestCase {
|
|||||||
private WifiStateWorker mWifiStateWorker;
|
private WifiStateWorker mWifiStateWorker;
|
||||||
@Mock
|
@Mock
|
||||||
private SignalStrength mSignalStrength;
|
private SignalStrength mSignalStrength;
|
||||||
|
@Mock
|
||||||
|
private FeatureFlags mFlags;
|
||||||
|
|
||||||
private TestableResources mTestableResources;
|
private TestableResources mTestableResources;
|
||||||
private InternetDialogController mInternetDialogController;
|
private InternetDialogController mInternetDialogController;
|
||||||
@@ -159,6 +172,10 @@ public class InternetDialogControllerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
|
mStaticMockSession = mockitoSession()
|
||||||
|
.mockStatic(SubscriptionManager.class)
|
||||||
|
.strictness(Strictness.LENIENT)
|
||||||
|
.startMocking();
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mTestableResources = mContext.getOrCreateTestableResources();
|
mTestableResources = mContext.getOrCreateTestableResources();
|
||||||
doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(anyInt());
|
doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(anyInt());
|
||||||
@@ -175,6 +192,7 @@ public class InternetDialogControllerTest extends SysuiTestCase {
|
|||||||
mAccessPoints.add(mWifiEntry1);
|
mAccessPoints.add(mWifiEntry1);
|
||||||
when(mAccessPointController.getMergedCarrierEntry()).thenReturn(mMergedCarrierEntry);
|
when(mAccessPointController.getMergedCarrierEntry()).thenReturn(mMergedCarrierEntry);
|
||||||
when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[]{SUB_ID});
|
when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(new int[]{SUB_ID});
|
||||||
|
when(SubscriptionManager.getDefaultDataSubscriptionId()).thenReturn(SUB_ID);
|
||||||
when(mToastFactory.createToast(any(), anyString(), anyString(), anyInt(), anyInt()))
|
when(mToastFactory.createToast(any(), anyString(), anyString(), anyInt(), anyInt()))
|
||||||
.thenReturn(mSystemUIToast);
|
.thenReturn(mSystemUIToast);
|
||||||
when(mSystemUIToast.getView()).thenReturn(mToastView);
|
when(mSystemUIToast.getView()).thenReturn(mToastView);
|
||||||
@@ -188,7 +206,7 @@ public class InternetDialogControllerTest extends SysuiTestCase {
|
|||||||
mock(ConnectivityManager.class), mHandler, mExecutor, mBroadcastDispatcher,
|
mock(ConnectivityManager.class), mHandler, mExecutor, mBroadcastDispatcher,
|
||||||
mock(KeyguardUpdateMonitor.class), mGlobalSettings, mKeyguardStateController,
|
mock(KeyguardUpdateMonitor.class), mGlobalSettings, mKeyguardStateController,
|
||||||
mWindowManager, mToastFactory, mWorkerHandler, mCarrierConfigTracker,
|
mWindowManager, mToastFactory, mWorkerHandler, mCarrierConfigTracker,
|
||||||
mLocationController, mDialogLaunchAnimator, mWifiStateWorker);
|
mLocationController, mDialogLaunchAnimator, mWifiStateWorker, mFlags);
|
||||||
mSubscriptionManager.addOnSubscriptionsChangedListener(mExecutor,
|
mSubscriptionManager.addOnSubscriptionsChangedListener(mExecutor,
|
||||||
mInternetDialogController.mOnSubscriptionsChangedListener);
|
mInternetDialogController.mOnSubscriptionsChangedListener);
|
||||||
mInternetDialogController.onStart(mInternetDialogCallback, true);
|
mInternetDialogController.onStart(mInternetDialogCallback, true);
|
||||||
@@ -197,6 +215,11 @@ public class InternetDialogControllerTest extends SysuiTestCase {
|
|||||||
mInternetDialogController.mWifiIconInjector = mWifiIconInjector;
|
mInternetDialogController.mWifiIconInjector = mWifiIconInjector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
mStaticMockSession.finishMocking();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void connectCarrierNetwork_mergedCarrierEntryCanConnect_connectAndCreateSysUiToast() {
|
public void connectCarrierNetwork_mergedCarrierEntryCanConnect_connectAndCreateSysUiToast() {
|
||||||
when(mMergedCarrierEntry.canConnect()).thenReturn(true);
|
when(mMergedCarrierEntry.canConnect()).thenReturn(true);
|
||||||
@@ -325,15 +348,45 @@ public class InternetDialogControllerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getSubtitleText_withNoService_returnNoNetworksAvailable() {
|
public void getSubtitleText_withNoService_returnNoNetworksAvailable() {
|
||||||
|
when(mFlags.isEnabled(any(UnreleasedFlag.class))).thenReturn(true);
|
||||||
|
InternetDialogController spyController = spy(mInternetDialogController);
|
||||||
fakeAirplaneModeEnabled(false);
|
fakeAirplaneModeEnabled(false);
|
||||||
when(mWifiStateWorker.isWifiEnabled()).thenReturn(true);
|
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(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getState();
|
||||||
doReturn(mServiceState).when(mTelephonyManager).getServiceState();
|
doReturn(mServiceState).when(mTelephonyManager).getServiceState();
|
||||||
doReturn(TelephonyManager.DATA_DISCONNECTED).when(mTelephonyManager).getDataState();
|
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")));
|
getResourcesString("all_network_unavailable")));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -650,6 +703,108 @@ public class InternetDialogControllerTest extends SysuiTestCase {
|
|||||||
assertThat(mInternetDialogController.isWifiScanEnabled()).isTrue();
|
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
|
@Test
|
||||||
public void getSignalStrengthDrawableWithLevel_carrierNetworkIsNotActive_useMobileDataLevel() {
|
public void getSignalStrengthDrawableWithLevel_carrierNetworkIsNotActive_useMobileDataLevel() {
|
||||||
// Fake mobile data level as SIGNAL_STRENGTH_POOR(1)
|
// 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);
|
when(mInternetDialogController.getCarrierNetworkLevel()).thenReturn(WIFI_LEVEL_MAX);
|
||||||
|
|
||||||
InternetDialogController spyController = spy(mInternetDialogController);
|
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());
|
eq(NUM_SIGNAL_STRENGTH_BINS), anyInt(), anyBoolean());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -672,9 +827,9 @@ public class InternetDialogControllerTest extends SysuiTestCase {
|
|||||||
when(mInternetDialogController.getCarrierNetworkLevel()).thenReturn(WIFI_LEVEL_MAX);
|
when(mInternetDialogController.getCarrierNetworkLevel()).thenReturn(WIFI_LEVEL_MAX);
|
||||||
|
|
||||||
InternetDialogController spyController = spy(mInternetDialogController);
|
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());
|
eq(WIFI_LEVEL_MAX + 1), anyInt(), anyBoolean());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,12 +8,15 @@ import static org.mockito.ArgumentMatchers.any;
|
|||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.anyLong;
|
import static org.mockito.ArgumentMatchers.anyLong;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.clearInvocations;
|
||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.testing.AndroidTestingRunner;
|
import android.testing.AndroidTestingRunner;
|
||||||
@@ -31,6 +34,7 @@ import com.android.internal.logging.UiEventLogger;
|
|||||||
import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils;
|
import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
|
import com.android.systemui.animation.DialogLaunchAnimator;
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||||
import com.android.systemui.util.time.FakeSystemClock;
|
import com.android.systemui.util.time.FakeSystemClock;
|
||||||
@@ -72,6 +76,8 @@ public class InternetDialogTest extends SysuiTestCase {
|
|||||||
private InternetDialogController mInternetDialogController;
|
private InternetDialogController mInternetDialogController;
|
||||||
@Mock
|
@Mock
|
||||||
private KeyguardStateController mKeyguard;
|
private KeyguardStateController mKeyguard;
|
||||||
|
@Mock
|
||||||
|
private DialogLaunchAnimator mDialogLaunchAnimator;
|
||||||
|
|
||||||
private FakeExecutor mBgExecutor = new FakeExecutor(new FakeSystemClock());
|
private FakeExecutor mBgExecutor = new FakeExecutor(new FakeSystemClock());
|
||||||
private InternetDialog mInternetDialog;
|
private InternetDialog mInternetDialog;
|
||||||
@@ -100,8 +106,9 @@ public class InternetDialogTest extends SysuiTestCase {
|
|||||||
when(mInternetWifiEntry.hasInternetAccess()).thenReturn(true);
|
when(mInternetWifiEntry.hasInternetAccess()).thenReturn(true);
|
||||||
when(mWifiEntries.size()).thenReturn(1);
|
when(mWifiEntries.size()).thenReturn(1);
|
||||||
|
|
||||||
when(mInternetDialogController.getMobileNetworkTitle()).thenReturn(MOBILE_NETWORK_TITLE);
|
when(mInternetDialogController.getMobileNetworkTitle(anyInt()))
|
||||||
when(mInternetDialogController.getMobileNetworkSummary())
|
.thenReturn(MOBILE_NETWORK_TITLE);
|
||||||
|
when(mInternetDialogController.getMobileNetworkSummary(anyInt()))
|
||||||
.thenReturn(MOBILE_NETWORK_SUMMARY);
|
.thenReturn(MOBILE_NETWORK_SUMMARY);
|
||||||
when(mInternetDialogController.isWifiEnabled()).thenReturn(true);
|
when(mInternetDialogController.isWifiEnabled()).thenReturn(true);
|
||||||
|
|
||||||
@@ -115,7 +122,8 @@ public class InternetDialogTest extends SysuiTestCase {
|
|||||||
|
|
||||||
private void createInternetDialog() {
|
private void createInternetDialog() {
|
||||||
mInternetDialog = new InternetDialog(mContext, mock(InternetDialogFactory.class),
|
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);
|
mBgExecutor, mKeyguard);
|
||||||
mInternetDialog.mAdapter = mInternetAdapter;
|
mInternetDialog.mAdapter = mInternetAdapter;
|
||||||
mInternetDialog.mConnectedWifiEntry = mInternetWifiEntry;
|
mInternetDialog.mConnectedWifiEntry = mInternetWifiEntry;
|
||||||
@@ -307,12 +315,18 @@ public class InternetDialogTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void updateDialog_wifiOnAndHasInternetWifi_showConnectedWifi() {
|
public void updateDialog_wifiOnAndHasInternetWifi_showConnectedWifi() {
|
||||||
|
mInternetDialog.dismissDialog();
|
||||||
|
doReturn(true).when(mInternetDialogController).hasActiveSubId();
|
||||||
|
createInternetDialog();
|
||||||
// The preconditions WiFi ON and Internet WiFi are already in setUp()
|
// The preconditions WiFi ON and Internet WiFi are already in setUp()
|
||||||
doReturn(false).when(mInternetDialogController).activeNetworkIsCellular();
|
doReturn(false).when(mInternetDialogController).activeNetworkIsCellular();
|
||||||
|
|
||||||
mInternetDialog.updateDialog(false);
|
mInternetDialog.updateDialog(true);
|
||||||
|
|
||||||
assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.VISIBLE);
|
assertThat(mConnectedWifi.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
LinearLayout secondaryLayout = mDialogView.requireViewById(
|
||||||
|
R.id.secondary_mobile_network_layout);
|
||||||
|
assertThat(secondaryLayout.getVisibility()).isEqualTo(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -459,6 +473,45 @@ public class InternetDialogTest extends SysuiTestCase {
|
|||||||
assertThat(mWifiToggleSummary.getVisibility()).isEqualTo(View.GONE);
|
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<AlertDialog> 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
|
@Test
|
||||||
public void updateDialog_wifiOn_hideWifiScanNotify() {
|
public void updateDialog_wifiOn_hideWifiScanNotify() {
|
||||||
// The preconditions WiFi ON and WiFi entries are already in setUp()
|
// The preconditions WiFi ON and WiFi entries are already in setUp()
|
||||||
|
|||||||
Reference in New Issue
Block a user