Merge "Refactor MobileDataPreference"
This commit is contained in:
@@ -16,6 +16,8 @@
|
|||||||
<PreferenceScreen
|
<PreferenceScreen
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:key="mobile_network_pref_screen"
|
||||||
|
android:title="@string/network_settings_title"
|
||||||
settings:initialExpandedChildrenCount="4">
|
settings:initialExpandedChildrenCount="4">
|
||||||
|
|
||||||
<PreferenceScreen
|
<PreferenceScreen
|
||||||
@@ -23,10 +25,11 @@
|
|||||||
android:title="@string/cdma_lte_data_service">
|
android:title="@string/cdma_lte_data_service">
|
||||||
</PreferenceScreen>
|
</PreferenceScreen>
|
||||||
|
|
||||||
<com.android.settings.mobilenetwork.MobileDataPreference
|
<SwitchPreference
|
||||||
android:key="mobile_data_enable"
|
android:key="mobile_data_enable"
|
||||||
android:title="@string/mobile_data_settings_title"
|
android:title="@string/mobile_data_settings_title"
|
||||||
android:summary="@string/mobile_data_settings_summary"/>
|
android:summary="@string/mobile_data_settings_summary"
|
||||||
|
settings:controller="com.android.settings.mobilenetwork.MobileDataPreferenceController"/>
|
||||||
|
|
||||||
<com.android.settingslib.RestrictedSwitchPreference
|
<com.android.settingslib.RestrictedSwitchPreference
|
||||||
android:key="button_roaming_key"
|
android:key="button_roaming_key"
|
||||||
|
@@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.mobilenetwork;
|
||||||
|
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.telephony.SubscriptionInfo;
|
||||||
|
import android.telephony.SubscriptionManager;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dialog Fragment to show dialog for "mobile data"
|
||||||
|
*
|
||||||
|
* 1. When user want to disable data in single sim case, show dialog to confirm
|
||||||
|
* 2. When user want to enable data in multiple sim case, show dialog to confirm to disable other
|
||||||
|
* sim
|
||||||
|
*/
|
||||||
|
public class MobileDataDialogFragment extends InstrumentedDialogFragment implements
|
||||||
|
DialogInterface.OnClickListener {
|
||||||
|
|
||||||
|
public static final int TYPE_DISABLE_DIALOG = 0;
|
||||||
|
public static final int TYPE_MULTI_SIM_DIALOG = 1;
|
||||||
|
|
||||||
|
private static final String ARG_DIALOG_TYPE = "dialog_type";
|
||||||
|
private static final String ARG_SUB_ID = "subId";
|
||||||
|
|
||||||
|
private SubscriptionManager mSubscriptionManager;
|
||||||
|
private int mType;
|
||||||
|
private int mSubId;
|
||||||
|
|
||||||
|
public static MobileDataDialogFragment newInstance(int type, int subId) {
|
||||||
|
final MobileDataDialogFragment dialogFragment = new MobileDataDialogFragment();
|
||||||
|
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putInt(ARG_DIALOG_TYPE, type);
|
||||||
|
args.putInt(ARG_SUB_ID, subId);
|
||||||
|
dialogFragment.setArguments(args);
|
||||||
|
|
||||||
|
return dialogFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
mSubscriptionManager = getContext().getSystemService(SubscriptionManager.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
final Bundle bundle = getArguments();
|
||||||
|
final Context context = getContext();
|
||||||
|
|
||||||
|
mType = bundle.getInt(ARG_DIALOG_TYPE);
|
||||||
|
mSubId = bundle.getInt(ARG_SUB_ID);
|
||||||
|
|
||||||
|
switch (mType) {
|
||||||
|
case TYPE_DISABLE_DIALOG:
|
||||||
|
return new AlertDialog.Builder(context)
|
||||||
|
.setMessage(R.string.data_usage_disable_mobile)
|
||||||
|
.setPositiveButton(android.R.string.ok, this)
|
||||||
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
|
.create();
|
||||||
|
case TYPE_MULTI_SIM_DIALOG:
|
||||||
|
final SubscriptionInfo currentSubInfo =
|
||||||
|
mSubscriptionManager.getActiveSubscriptionInfo(mSubId);
|
||||||
|
final SubscriptionInfo nextSubInfo =
|
||||||
|
mSubscriptionManager.getDefaultDataSubscriptionInfo();
|
||||||
|
|
||||||
|
final String previousName = (nextSubInfo == null)
|
||||||
|
? getContext().getResources().getString(
|
||||||
|
R.string.sim_selection_required_pref)
|
||||||
|
: nextSubInfo.getDisplayName().toString();
|
||||||
|
|
||||||
|
return new AlertDialog.Builder(context)
|
||||||
|
.setTitle(R.string.sim_change_data_title)
|
||||||
|
.setMessage(context.getString(R.string.sim_change_data_message,
|
||||||
|
currentSubInfo != null
|
||||||
|
? currentSubInfo.getDisplayName()
|
||||||
|
: "",
|
||||||
|
previousName))
|
||||||
|
.setPositiveButton(android.R.string.ok, this)
|
||||||
|
.setNegativeButton(R.string.cancel, null)
|
||||||
|
.create();
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("unknown type " + mType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMetricsCategory() {
|
||||||
|
//TODO(b/114749736): add metric id for this fragment
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
switch (mType) {
|
||||||
|
case TYPE_DISABLE_DIALOG:
|
||||||
|
MobileNetworkUtils.setMobileDataEnabled(getContext(), mSubId, false /* enabled */,
|
||||||
|
false /* disableOtherSubscriptions */);
|
||||||
|
break;
|
||||||
|
case TYPE_MULTI_SIM_DIALOG:
|
||||||
|
mSubscriptionManager.setDefaultDataSubId(mSubId);
|
||||||
|
MobileNetworkUtils.setMobileDataEnabled(getContext(), mSubId, true /* enabled */,
|
||||||
|
true /* disableOtherSubscriptions */);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("unknown type " + mType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -1,324 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2018 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.android.settings.mobilenetwork;
|
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.database.ContentObserver;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.Looper;
|
|
||||||
import android.os.Parcel;
|
|
||||||
import android.os.Parcelable;
|
|
||||||
import android.provider.Settings.Global;
|
|
||||||
import android.telephony.SubscriptionInfo;
|
|
||||||
import android.telephony.SubscriptionManager;
|
|
||||||
import android.telephony.TelephonyManager;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.Checkable;
|
|
||||||
|
|
||||||
import androidx.preference.DialogPreference;
|
|
||||||
import androidx.preference.PreferenceScreen;
|
|
||||||
import androidx.preference.PreferenceViewHolder;
|
|
||||||
|
|
||||||
import com.android.internal.logging.MetricsLogger;
|
|
||||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
|
||||||
import com.android.settings.R;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Customized Preference to enable / disable mobile data.
|
|
||||||
* Basically copy of with com.android.settings.CellDataPreference.
|
|
||||||
*/
|
|
||||||
public class MobileDataPreference extends DialogPreference implements
|
|
||||||
DialogInterface.OnClickListener {
|
|
||||||
|
|
||||||
private static final boolean DBG = false;
|
|
||||||
private static final String TAG = "MobileDataPreference";
|
|
||||||
|
|
||||||
public int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
|
||||||
public boolean mChecked;
|
|
||||||
// Whether to show the dialog to ask switching default data subscription.
|
|
||||||
// Should be true only when a multi-sim phone only supports data connection on a single phone,
|
|
||||||
// and user is enabling data on the non-default phone.
|
|
||||||
public boolean mMultiSimDialog;
|
|
||||||
private TelephonyManager mTelephonyManager;
|
|
||||||
private SubscriptionManager mSubscriptionManager;
|
|
||||||
|
|
||||||
public MobileDataPreference(Context context, AttributeSet attrs) {
|
|
||||||
super(context, attrs, com.android.internal.R.attr.switchPreferenceStyle);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Must be called to avoid binder leakage.
|
|
||||||
void dispose() {
|
|
||||||
mListener.setListener(false, mSubId, getContext());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onRestoreInstanceState(Parcelable s) {
|
|
||||||
CellDataState state = (CellDataState) s;
|
|
||||||
super.onRestoreInstanceState(state.getSuperState());
|
|
||||||
mTelephonyManager = TelephonyManager.from(getContext());
|
|
||||||
mChecked = state.mChecked;
|
|
||||||
mMultiSimDialog = state.mMultiSimDialog;
|
|
||||||
if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
|
||||||
mSubId = state.mSubId;
|
|
||||||
setKey(getKey() + mSubId);
|
|
||||||
}
|
|
||||||
notifyChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Parcelable onSaveInstanceState() {
|
|
||||||
CellDataState state = new CellDataState(super.onSaveInstanceState());
|
|
||||||
state.mChecked = mChecked;
|
|
||||||
state.mMultiSimDialog = mMultiSimDialog;
|
|
||||||
state.mSubId = mSubId;
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAttached() {
|
|
||||||
super.onAttached();
|
|
||||||
mListener.setListener(true, mSubId, getContext());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPrepareForRemoval() {
|
|
||||||
mListener.setListener(false, mSubId, getContext());
|
|
||||||
super.onPrepareForRemoval();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize this preference with subId.
|
|
||||||
*/
|
|
||||||
public void initialize(int subId) {
|
|
||||||
if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
|
||||||
throw new IllegalArgumentException("MobileDataPreference needs a SubscriptionInfo");
|
|
||||||
}
|
|
||||||
mSubscriptionManager = SubscriptionManager.from(getContext());
|
|
||||||
mTelephonyManager = TelephonyManager.from(getContext());
|
|
||||||
if (mSubId != subId) {
|
|
||||||
mSubId = subId;
|
|
||||||
setKey(getKey() + subId);
|
|
||||||
}
|
|
||||||
updateChecked();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateChecked() {
|
|
||||||
setChecked(mTelephonyManager.getDataEnabled(mSubId));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void performClick() {
|
|
||||||
if (!isEnabled() || !SubscriptionManager.isValidSubscriptionId(mSubId)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
final SubscriptionInfo currentSir = mSubscriptionManager.getActiveSubscriptionInfo(
|
|
||||||
mSubId);
|
|
||||||
final SubscriptionInfo nextSir = mSubscriptionManager.getDefaultDataSubscriptionInfo();
|
|
||||||
final boolean isMultiSim = (mTelephonyManager.getSimCount() > 1);
|
|
||||||
final boolean isMultipleDataOnCapable =
|
|
||||||
(mTelephonyManager.getNumberOfModemsWithSimultaneousDataConnections() > 1);
|
|
||||||
final boolean isDefaultDataSubscription = (nextSir != null && currentSir != null
|
|
||||||
&& currentSir.getSubscriptionId() == nextSir.getSubscriptionId());
|
|
||||||
if (mChecked) {
|
|
||||||
if (!isMultiSim) {
|
|
||||||
// disabling data; show confirmation dialog which eventually
|
|
||||||
// calls setMobileDataEnabled() once user confirms.
|
|
||||||
mMultiSimDialog = false;
|
|
||||||
super.performClick();
|
|
||||||
} else {
|
|
||||||
// Don't show any dialog.
|
|
||||||
setMobileDataEnabled(false /* enabled */, false /* disableOtherSubscriptions */);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (isMultiSim && !isMultipleDataOnCapable && !isDefaultDataSubscription) {
|
|
||||||
// enabling data and setting to default; show confirmation dialog which eventually
|
|
||||||
// calls setMobileDataEnabled() once user confirms.
|
|
||||||
mMultiSimDialog = true;
|
|
||||||
super.performClick();
|
|
||||||
} else {
|
|
||||||
// Don't show any dialog.
|
|
||||||
setMobileDataEnabled(true /* enabled */, false /* disableOtherSubscriptions */);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setMobileDataEnabled(boolean enabled, boolean disableOtherSubscriptions) {
|
|
||||||
if (DBG) Log.d(TAG, "setMobileDataEnabled(" + enabled + "," + mSubId + ")");
|
|
||||||
|
|
||||||
MetricsLogger.action(getContext(), MetricsEvent.ACTION_MOBILE_NETWORK_MOBILE_DATA_TOGGLE,
|
|
||||||
enabled);
|
|
||||||
|
|
||||||
mTelephonyManager.setDataEnabled(mSubId, enabled);
|
|
||||||
|
|
||||||
if (disableOtherSubscriptions) {
|
|
||||||
disableDataForOtherSubscriptions(mSubId);
|
|
||||||
}
|
|
||||||
|
|
||||||
setChecked(enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setChecked(boolean checked) {
|
|
||||||
if (mChecked == checked) return;
|
|
||||||
mChecked = checked;
|
|
||||||
notifyChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBindViewHolder(PreferenceViewHolder holder) {
|
|
||||||
super.onBindViewHolder(holder);
|
|
||||||
View checkableView = holder.findViewById(com.android.internal.R.id.switch_widget);
|
|
||||||
checkableView.setClickable(false);
|
|
||||||
((Checkable) checkableView).setChecked(mChecked);
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO(b/114749736): move it to preference controller
|
|
||||||
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
|
|
||||||
if (mMultiSimDialog) {
|
|
||||||
showMultiSimDialog(builder);
|
|
||||||
} else {
|
|
||||||
showDisableDialog(builder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showDisableDialog(AlertDialog.Builder builder) {
|
|
||||||
builder.setTitle(null)
|
|
||||||
.setMessage(R.string.data_usage_disable_mobile)
|
|
||||||
.setPositiveButton(android.R.string.ok, this)
|
|
||||||
.setNegativeButton(android.R.string.cancel, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showMultiSimDialog(AlertDialog.Builder builder) {
|
|
||||||
final SubscriptionInfo currentSir = mSubscriptionManager.getActiveSubscriptionInfo(mSubId);
|
|
||||||
final SubscriptionInfo nextSir = mSubscriptionManager.getDefaultDataSubscriptionInfo();
|
|
||||||
|
|
||||||
final String previousName = (nextSir == null)
|
|
||||||
? getContext().getResources().getString(R.string.sim_selection_required_pref)
|
|
||||||
: nextSir.getDisplayName().toString();
|
|
||||||
|
|
||||||
builder.setTitle(R.string.sim_change_data_title);
|
|
||||||
builder.setMessage(getContext().getString(R.string.sim_change_data_message,
|
|
||||||
String.valueOf(currentSir != null ? currentSir.getDisplayName() : null),
|
|
||||||
previousName));
|
|
||||||
|
|
||||||
builder.setPositiveButton(android.R.string.ok, this);
|
|
||||||
builder.setNegativeButton(R.string.cancel, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void disableDataForOtherSubscriptions(int subId) {
|
|
||||||
List<SubscriptionInfo> subInfoList = mSubscriptionManager.getActiveSubscriptionInfoList();
|
|
||||||
if (subInfoList != null) {
|
|
||||||
for (SubscriptionInfo subInfo : subInfoList) {
|
|
||||||
if (subInfo.getSubscriptionId() != subId) {
|
|
||||||
mTelephonyManager.setDataEnabled(subInfo.getSubscriptionId(), false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
if (which != DialogInterface.BUTTON_POSITIVE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (mMultiSimDialog) {
|
|
||||||
mSubscriptionManager.setDefaultDataSubId(mSubId);
|
|
||||||
setMobileDataEnabled(true /* enabled */, true /* disableOtherSubscriptions */);
|
|
||||||
} else {
|
|
||||||
// TODO: extend to modify policy enabled flag.
|
|
||||||
setMobileDataEnabled(false /* enabled */, false /* disableOtherSubscriptions */);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final DataStateListener mListener = new DataStateListener() {
|
|
||||||
@Override
|
|
||||||
public void onChange(boolean selfChange) {
|
|
||||||
updateChecked();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listener that listens mobile data state change.
|
|
||||||
*/
|
|
||||||
public abstract static class DataStateListener extends ContentObserver {
|
|
||||||
public DataStateListener() {
|
|
||||||
super(new Handler(Looper.getMainLooper()));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set / Unset data state listening, specifying subId.
|
|
||||||
*/
|
|
||||||
public void setListener(boolean listening, int subId, Context context) {
|
|
||||||
if (listening) {
|
|
||||||
Uri uri = Global.getUriFor(Global.MOBILE_DATA);
|
|
||||||
if (TelephonyManager.getDefault().getSimCount() != 1) {
|
|
||||||
uri = Global.getUriFor(Global.MOBILE_DATA + subId);
|
|
||||||
}
|
|
||||||
context.getContentResolver().registerContentObserver(uri, false, this);
|
|
||||||
} else {
|
|
||||||
context.getContentResolver().unregisterContentObserver(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class that represents state of mobile data state.
|
|
||||||
* Used by onSaveInstanceState and onRestoreInstanceState.
|
|
||||||
*/
|
|
||||||
public static class CellDataState extends BaseSavedState {
|
|
||||||
public int mSubId;
|
|
||||||
public boolean mChecked;
|
|
||||||
public boolean mMultiSimDialog;
|
|
||||||
|
|
||||||
public CellDataState(Parcelable base) {
|
|
||||||
super(base);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CellDataState(Parcel source) {
|
|
||||||
super(source);
|
|
||||||
mChecked = source.readByte() != 0;
|
|
||||||
mMultiSimDialog = source.readByte() != 0;
|
|
||||||
mSubId = source.readInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeToParcel(Parcel dest, int flags) {
|
|
||||||
super.writeToParcel(dest, flags);
|
|
||||||
dest.writeByte((byte) (mChecked ? 1 : 0));
|
|
||||||
dest.writeByte((byte) (mMultiSimDialog ? 1 : 0));
|
|
||||||
dest.writeInt(mSubId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static final Creator<CellDataState> CREATOR = new Creator<CellDataState>() {
|
|
||||||
@Override
|
|
||||||
public CellDataState createFromParcel(Parcel source) {
|
|
||||||
return new CellDataState(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public CellDataState[] newArray(int size) {
|
|
||||||
return new CellDataState[size];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.mobilenetwork;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.database.ContentObserver;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.provider.Settings;
|
||||||
|
import android.telephony.SubscriptionInfo;
|
||||||
|
import android.telephony.SubscriptionManager;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
import androidx.preference.PreferenceScreen;
|
||||||
|
import androidx.preference.SwitchPreference;
|
||||||
|
|
||||||
|
import com.android.settings.core.TogglePreferenceController;
|
||||||
|
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||||
|
import com.android.settingslib.core.lifecycle.events.OnStart;
|
||||||
|
import com.android.settingslib.core.lifecycle.events.OnStop;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preference controller for "Mobile data"
|
||||||
|
*/
|
||||||
|
public class MobileDataPreferenceController extends TogglePreferenceController
|
||||||
|
implements LifecycleObserver, OnStart, OnStop {
|
||||||
|
|
||||||
|
private static final String DIALOG_TAG = "MobileDataDialog";
|
||||||
|
|
||||||
|
private SwitchPreference mPreference;
|
||||||
|
private TelephonyManager mTelephonyManager;
|
||||||
|
private SubscriptionManager mSubscriptionManager;
|
||||||
|
private DataContentObserver mDataContentObserver;
|
||||||
|
private FragmentManager mFragmentManager;
|
||||||
|
private int mSubId;
|
||||||
|
@VisibleForTesting
|
||||||
|
int mDialogType;
|
||||||
|
@VisibleForTesting
|
||||||
|
boolean mNeedDialog;
|
||||||
|
|
||||||
|
public MobileDataPreferenceController(Context context, String key) {
|
||||||
|
super(context, key);
|
||||||
|
mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
|
||||||
|
mDataContentObserver = new DataContentObserver(new Handler(Looper.getMainLooper()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getAvailabilityStatus() {
|
||||||
|
return mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
|
||||||
|
? AVAILABLE
|
||||||
|
: CONDITIONALLY_UNAVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void displayPreference(PreferenceScreen screen) {
|
||||||
|
super.displayPreference(screen);
|
||||||
|
mPreference = (SwitchPreference) screen.findPreference(getPreferenceKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||||
|
mDataContentObserver.register(mContext, mSubId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
|
||||||
|
mDataContentObserver.unRegister(mContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handlePreferenceTreeClick(Preference preference) {
|
||||||
|
if (TextUtils.equals(preference.getKey(), getPreferenceKey())) {
|
||||||
|
if (mNeedDialog) {
|
||||||
|
showDialog(mDialogType);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setChecked(boolean isChecked) {
|
||||||
|
mNeedDialog = isDialogNeeded();
|
||||||
|
|
||||||
|
if (!mNeedDialog) {
|
||||||
|
// Update data directly if we don't need dialog
|
||||||
|
MobileNetworkUtils.setMobileDataEnabled(mContext, mSubId, isChecked, false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isChecked() {
|
||||||
|
return mTelephonyManager.isDataEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(FragmentManager fragmentManager, int subId) {
|
||||||
|
mFragmentManager = fragmentManager;
|
||||||
|
mSubId = subId;
|
||||||
|
mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
boolean isDialogNeeded() {
|
||||||
|
final boolean enableData = !mTelephonyManager.isDataEnabled();
|
||||||
|
final SubscriptionInfo currentSir = mSubscriptionManager.getActiveSubscriptionInfo(
|
||||||
|
mSubId);
|
||||||
|
final SubscriptionInfo nextSir = mSubscriptionManager.getDefaultDataSubscriptionInfo();
|
||||||
|
final boolean isMultiSim = (mTelephonyManager.getSimCount() > 1);
|
||||||
|
final boolean isMultipleDataOnCapable =
|
||||||
|
(mTelephonyManager.getNumberOfModemsWithSimultaneousDataConnections() > 1);
|
||||||
|
final boolean isDefaultDataSubscription = (nextSir != null && currentSir != null
|
||||||
|
&& currentSir.getSubscriptionId() == nextSir.getSubscriptionId());
|
||||||
|
if (enableData) {
|
||||||
|
if (isMultiSim && !isMultipleDataOnCapable && !isDefaultDataSubscription) {
|
||||||
|
mDialogType = MobileDataDialogFragment.TYPE_MULTI_SIM_DIALOG;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!isMultiSim) {
|
||||||
|
mDialogType = MobileDataDialogFragment.TYPE_DISABLE_DIALOG;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showDialog(int type) {
|
||||||
|
final MobileDataDialogFragment dialogFragment = MobileDataDialogFragment.newInstance(type,
|
||||||
|
mSubId);
|
||||||
|
dialogFragment.show(mFragmentManager, DIALOG_TAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener that listens mobile data state change.
|
||||||
|
*/
|
||||||
|
public class DataContentObserver extends ContentObserver {
|
||||||
|
|
||||||
|
public DataContentObserver(Handler handler) {
|
||||||
|
super(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onChange(boolean selfChange) {
|
||||||
|
super.onChange(selfChange);
|
||||||
|
updateState(mPreference);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void register(Context context, int subId) {
|
||||||
|
Uri uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA);
|
||||||
|
if (TelephonyManager.getDefault().getSimCount() != 1) {
|
||||||
|
uri = Settings.Global.getUriFor(Settings.Global.MOBILE_DATA + subId);
|
||||||
|
}
|
||||||
|
context.getContentResolver().registerContentObserver(uri, false, this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unRegister(Context context) {
|
||||||
|
context.getContentResolver().unregisterContentObserver(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -34,6 +34,7 @@ import android.os.Message;
|
|||||||
import android.os.PersistableBundle;
|
import android.os.PersistableBundle;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
|
import android.provider.SearchIndexableResource;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.telecom.PhoneAccountHandle;
|
import android.telecom.PhoneAccountHandle;
|
||||||
import android.telecom.TelecomManager;
|
import android.telecom.TelecomManager;
|
||||||
@@ -61,8 +62,11 @@ import com.android.settings.search.BaseSearchIndexProvider;
|
|||||||
import com.android.settings.search.Indexable;
|
import com.android.settings.search.Indexable;
|
||||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||||
import com.android.settingslib.RestrictedSwitchPreference;
|
import com.android.settingslib.RestrictedSwitchPreference;
|
||||||
|
import com.android.settingslib.core.AbstractPreferenceController;
|
||||||
|
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||||
import com.android.settingslib.search.SearchIndexable;
|
import com.android.settingslib.search.SearchIndexable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -156,7 +160,6 @@ public class MobileNetworkFragment extends DashboardFragment implements
|
|||||||
private Preference mWiFiCallingPref;
|
private Preference mWiFiCallingPref;
|
||||||
private SwitchPreference mVideoCallingPref;
|
private SwitchPreference mVideoCallingPref;
|
||||||
private NetworkSelectListPreference mButtonNetworkSelect;
|
private NetworkSelectListPreference mButtonNetworkSelect;
|
||||||
private MobileDataPreference mMobileDataPref;
|
|
||||||
private DataUsagePreference mDataUsagePref;
|
private DataUsagePreference mDataUsagePref;
|
||||||
|
|
||||||
private static final String iface = "rmnet0"; //TODO: this will go away
|
private static final String iface = "rmnet0"; //TODO: this will go away
|
||||||
@@ -238,6 +241,9 @@ public class MobileNetworkFragment extends DashboardFragment implements
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceTreeClick(Preference preference) {
|
public boolean onPreferenceTreeClick(Preference preference) {
|
||||||
|
if (super.onPreferenceTreeClick(preference)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
sendMetricsEventPreferenceClicked(getPreferenceScreen(), preference);
|
sendMetricsEventPreferenceClicked(getPreferenceScreen(), preference);
|
||||||
|
|
||||||
/** TODO: Refactor and get rid of the if's using subclasses */
|
/** TODO: Refactor and get rid of the if's using subclasses */
|
||||||
@@ -298,7 +304,7 @@ public class MobileNetworkFragment extends DashboardFragment implements
|
|||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
return true;
|
return true;
|
||||||
} else if (preference == mWiFiCallingPref || preference == mVideoCallingPref
|
} else if (preference == mWiFiCallingPref || preference == mVideoCallingPref
|
||||||
|| preference == mMobileDataPref || preference == mDataUsagePref) {
|
|| preference == mDataUsagePref) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
// if the button is anything but the simple toggle preference,
|
// if the button is anything but the simple toggle preference,
|
||||||
@@ -383,6 +389,15 @@ public class MobileNetworkFragment extends DashboardFragment implements
|
|||||||
mPhoneStateListener.updateSubscriptionId(mSubId);
|
mPhoneStateListener.updateSubscriptionId(mSubId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
mSubId = getArguments().getInt(MobileSettingsActivity.KEY_SUBSCRIPTION_ID,
|
||||||
|
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
||||||
|
|
||||||
|
use(MobileDataPreferenceController.class).init(getFragmentManager(), mSubId);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle icicle) {
|
public void onCreate(Bundle icicle) {
|
||||||
Log.i(LOG_TAG, "onCreate:+");
|
Log.i(LOG_TAG, "onCreate:+");
|
||||||
@@ -407,7 +422,6 @@ public class MobileNetworkFragment extends DashboardFragment implements
|
|||||||
mCallingCategory = (PreferenceCategory) findPreference(CATEGORY_CALLING_KEY);
|
mCallingCategory = (PreferenceCategory) findPreference(CATEGORY_CALLING_KEY);
|
||||||
mWiFiCallingPref = findPreference(BUTTON_WIFI_CALLING_KEY);
|
mWiFiCallingPref = findPreference(BUTTON_WIFI_CALLING_KEY);
|
||||||
mVideoCallingPref = (SwitchPreference) findPreference(BUTTON_VIDEO_CALLING_KEY);
|
mVideoCallingPref = (SwitchPreference) findPreference(BUTTON_VIDEO_CALLING_KEY);
|
||||||
mMobileDataPref = (MobileDataPreference) findPreference(BUTTON_MOBILE_DATA_ENABLE_KEY);
|
|
||||||
mDataUsagePref = (DataUsagePreference) findPreference(BUTTON_DATA_USAGE_KEY);
|
mDataUsagePref = (DataUsagePreference) findPreference(BUTTON_DATA_USAGE_KEY);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -439,8 +453,6 @@ public class MobileNetworkFragment extends DashboardFragment implements
|
|||||||
// Initialize mActiveSubInfo
|
// Initialize mActiveSubInfo
|
||||||
int max = mSubscriptionManager.getActiveSubscriptionInfoCountMax();
|
int max = mSubscriptionManager.getActiveSubscriptionInfoCountMax();
|
||||||
mActiveSubInfos = mSubscriptionManager.getActiveSubscriptionInfoList();
|
mActiveSubInfos = mSubscriptionManager.getActiveSubscriptionInfoList();
|
||||||
mSubId = getArguments().getInt(MobileSettingsActivity.KEY_SUBSCRIPTION_ID,
|
|
||||||
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
|
||||||
|
|
||||||
updatePhone();
|
updatePhone();
|
||||||
if (hasActiveSubscriptions()) {
|
if (hasActiveSubscriptions()) {
|
||||||
@@ -490,14 +502,6 @@ public class MobileNetworkFragment extends DashboardFragment implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
if (mMobileDataPref != null) {
|
|
||||||
mMobileDataPref.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
@@ -567,17 +571,14 @@ public class MobileNetworkFragment extends DashboardFragment implements
|
|||||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
prefSet.addPreference(mMobileDataPref);
|
|
||||||
prefSet.addPreference(mButtonDataRoam);
|
prefSet.addPreference(mButtonDataRoam);
|
||||||
prefSet.addPreference(mDataUsagePref);
|
prefSet.addPreference(mDataUsagePref);
|
||||||
|
|
||||||
mMobileDataPref.setEnabled(hasActiveSubscriptions);
|
|
||||||
mButtonDataRoam.setEnabled(hasActiveSubscriptions);
|
mButtonDataRoam.setEnabled(hasActiveSubscriptions);
|
||||||
mDataUsagePref.setEnabled(hasActiveSubscriptions);
|
mDataUsagePref.setEnabled(hasActiveSubscriptions);
|
||||||
|
|
||||||
if (hasActiveSubscriptions) {
|
if (hasActiveSubscriptions) {
|
||||||
// Customized preferences needs to be initialized with subId.
|
// Customized preferences needs to be initialized with subId.
|
||||||
mMobileDataPref.initialize(phoneSubId);
|
|
||||||
mDataUsagePref.initialize(phoneSubId);
|
mDataUsagePref.initialize(phoneSubId);
|
||||||
|
|
||||||
// Initialize states of mButtonDataRoam.
|
// Initialize states of mButtonDataRoam.
|
||||||
@@ -609,8 +610,6 @@ public class MobileNetworkFragment extends DashboardFragment implements
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
prefSet.removeAll();
|
|
||||||
|
|
||||||
updateBodyBasicFields(activity, prefSet, mSubId, hasActiveSubscriptions);
|
updateBodyBasicFields(activity, prefSet, mSubId, hasActiveSubscriptions);
|
||||||
|
|
||||||
if (hasActiveSubscriptions) {
|
if (hasActiveSubscriptions) {
|
||||||
@@ -1751,8 +1750,6 @@ public class MobileNetworkFragment extends DashboardFragment implements
|
|||||||
|
|
||||||
if (preference == null) {
|
if (preference == null) {
|
||||||
return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
|
return MetricsProto.MetricsEvent.VIEW_UNKNOWN;
|
||||||
} else if (preference == mMobileDataPref) {
|
|
||||||
return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_MOBILE_DATA_TOGGLE;
|
|
||||||
} else if (preference == mButtonDataRoam) {
|
} else if (preference == mButtonDataRoam) {
|
||||||
return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_DATA_ROAMING_TOGGLE;
|
return MetricsProto.MetricsEvent.ACTION_MOBILE_NETWORK_DATA_ROAMING_TOGGLE;
|
||||||
} else if (preference == mDataUsagePref) {
|
} else if (preference == mDataUsagePref) {
|
||||||
@@ -1864,6 +1861,17 @@ public class MobileNetworkFragment extends DashboardFragment implements
|
|||||||
protected boolean isPageSearchEnabled(Context context) {
|
protected boolean isPageSearchEnabled(Context context) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
|
||||||
|
boolean enabled) {
|
||||||
|
final ArrayList<SearchIndexableResource> result = new ArrayList<>();
|
||||||
|
|
||||||
|
final SearchIndexableResource sir = new SearchIndexableResource(context);
|
||||||
|
sir.xmlResId = R.xml.network_setting_fragment;
|
||||||
|
result.add(sir);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final class SetPreferredNetworkAsyncTask extends AsyncTask<Void, Void, Boolean> {
|
private static final class SetPreferredNetworkAsyncTask extends AsyncTask<Void, Void, Boolean> {
|
||||||
|
@@ -22,13 +22,14 @@ import android.content.ContentResolver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.os.PersistableBundle;
|
import android.os.PersistableBundle;
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.telecom.PhoneAccountHandle;
|
import android.telecom.PhoneAccountHandle;
|
||||||
import android.telecom.TelecomManager;
|
import android.telecom.TelecomManager;
|
||||||
|
import android.telephony.SubscriptionInfo;
|
||||||
|
import android.telephony.SubscriptionManager;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.telephony.euicc.EuiccManager;
|
import android.telephony.euicc.EuiccManager;
|
||||||
import android.telephony.ims.feature.ImsFeature;
|
import android.telephony.ims.feature.ImsFeature;
|
||||||
@@ -170,4 +171,30 @@ public class MobileNetworkUtils {
|
|||||||
//TODO(b/114749736): get carrier config from subId
|
//TODO(b/114749736): get carrier config from subId
|
||||||
return new PersistableBundle();
|
return new PersistableBundle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether to enable data for {@code subId}, also whether to disable data for other
|
||||||
|
* subscription
|
||||||
|
*/
|
||||||
|
public static void setMobileDataEnabled(Context context, int subId, boolean enabled,
|
||||||
|
boolean disableOtherSubscriptions) {
|
||||||
|
final TelephonyManager telephonyManager = TelephonyManager.from(context)
|
||||||
|
.createForSubscriptionId(subId);
|
||||||
|
final SubscriptionManager subscriptionManager = context.getSystemService(
|
||||||
|
SubscriptionManager.class);
|
||||||
|
telephonyManager.setDataEnabled(enabled);
|
||||||
|
|
||||||
|
if (disableOtherSubscriptions) {
|
||||||
|
List<SubscriptionInfo> subInfoList =
|
||||||
|
subscriptionManager.getActiveSubscriptionInfoList();
|
||||||
|
if (subInfoList != null) {
|
||||||
|
for (SubscriptionInfo subInfo : subInfoList) {
|
||||||
|
if (subInfo.getSubscriptionId() != subId) {
|
||||||
|
TelephonyManager.from(context).createForSubscriptionId(
|
||||||
|
subInfo.getSubscriptionId()).setDataEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@@ -23,6 +23,11 @@ import android.telephony.SubscriptionManager;
|
|||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.fragment.app.FragmentTransaction;
|
||||||
|
|
||||||
import com.android.internal.util.CollectionUtils;
|
import com.android.internal.util.CollectionUtils;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.core.SettingsBaseActivity;
|
import com.android.settings.core.SettingsBaseActivity;
|
||||||
@@ -31,11 +36,6 @@ import com.google.android.material.bottomnavigation.BottomNavigationView;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.fragment.app.FragmentManager;
|
|
||||||
import androidx.fragment.app.FragmentTransaction;
|
|
||||||
|
|
||||||
public class MobileSettingsActivity extends SettingsBaseActivity {
|
public class MobileSettingsActivity extends SettingsBaseActivity {
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
@@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.mobilenetwork;
|
||||||
|
|
||||||
|
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.telephony.SubscriptionInfo;
|
||||||
|
import android.telephony.SubscriptionManager;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.fragment.app.FragmentTransaction;
|
||||||
|
import androidx.preference.SwitchPreference;
|
||||||
|
|
||||||
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
public class MobileDataPreferenceControllerTest {
|
||||||
|
private static final int SUB_ID = 2;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private FragmentManager mFragmentManager;
|
||||||
|
@Mock
|
||||||
|
private TelephonyManager mTelephonyManager;
|
||||||
|
@Mock
|
||||||
|
private TelephonyManager mInvalidTelephonyManager;
|
||||||
|
@Mock
|
||||||
|
private SubscriptionManager mSubscriptionManager;
|
||||||
|
@Mock
|
||||||
|
private SubscriptionInfo mSubscriptionInfo;
|
||||||
|
@Mock
|
||||||
|
private FragmentTransaction mFragmentTransaction;
|
||||||
|
|
||||||
|
private MobileDataPreferenceController mController;
|
||||||
|
private SwitchPreference mPreference;
|
||||||
|
private Context mContext;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
|
mContext = spy(RuntimeEnvironment.application);
|
||||||
|
doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
|
||||||
|
doReturn(mSubscriptionManager).when(mContext).getSystemService(SubscriptionManager.class);
|
||||||
|
doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID);
|
||||||
|
doReturn(mInvalidTelephonyManager).when(mTelephonyManager).createForSubscriptionId(
|
||||||
|
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
||||||
|
doReturn(mFragmentTransaction).when(mFragmentManager).beginTransaction();
|
||||||
|
|
||||||
|
mPreference = new SwitchPreference(mContext);
|
||||||
|
mController = new MobileDataPreferenceController(mContext, "mobile_data");
|
||||||
|
mController.init(mFragmentManager, SUB_ID);
|
||||||
|
mPreference.setKey(mController.getPreferenceKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getAvailabilityStatus_invalidSubscription_returnUnavailable() {
|
||||||
|
mController.init(mFragmentManager, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
||||||
|
|
||||||
|
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isDialogNeeded_disableSingleSim_returnTrue() {
|
||||||
|
doReturn(true).when(mTelephonyManager).isDataEnabled();
|
||||||
|
doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID);
|
||||||
|
doReturn(mSubscriptionInfo).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
|
||||||
|
doReturn(1).when(mTelephonyManager).getSimCount();
|
||||||
|
|
||||||
|
assertThat(mController.isDialogNeeded()).isTrue();
|
||||||
|
assertThat(mController.mDialogType).isEqualTo(MobileDataDialogFragment.TYPE_DISABLE_DIALOG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void isDialogNeeded_enableNonDefaultSimInMultiSimMode_returnTrue() {
|
||||||
|
doReturn(false).when(mTelephonyManager).isDataEnabled();
|
||||||
|
doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID);
|
||||||
|
doReturn(null).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
|
||||||
|
doReturn(2).when(mTelephonyManager).getSimCount();
|
||||||
|
doReturn(1).when(mTelephonyManager).getNumberOfModemsWithSimultaneousDataConnections();
|
||||||
|
|
||||||
|
assertThat(mController.isDialogNeeded()).isTrue();
|
||||||
|
assertThat(mController.mDialogType).isEqualTo(
|
||||||
|
MobileDataDialogFragment.TYPE_MULTI_SIM_DIALOG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void handlePreferenceTreeClick_needDialog_showDialog() {
|
||||||
|
mController.mNeedDialog = true;
|
||||||
|
|
||||||
|
mController.handlePreferenceTreeClick(mPreference);
|
||||||
|
|
||||||
|
verify(mFragmentManager).beginTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onPreferenceChange_needDialog_doNothing() {
|
||||||
|
doReturn(true).when(mTelephonyManager).isDataEnabled();
|
||||||
|
doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID);
|
||||||
|
doReturn(mSubscriptionInfo).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
|
||||||
|
doReturn(1).when(mTelephonyManager).getSimCount();
|
||||||
|
|
||||||
|
mController.onPreferenceChange(mPreference, true);
|
||||||
|
|
||||||
|
verify(mTelephonyManager, never()).setDataEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onPreferenceChange_notNeedDialog_update() {
|
||||||
|
doReturn(true).when(mTelephonyManager).isDataEnabled();
|
||||||
|
doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(SUB_ID);
|
||||||
|
doReturn(mSubscriptionInfo).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
|
||||||
|
doReturn(2).when(mTelephonyManager).getSimCount();
|
||||||
|
|
||||||
|
mController.onPreferenceChange(mPreference, true);
|
||||||
|
|
||||||
|
verify(mTelephonyManager).setDataEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.mobilenetwork;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.telephony.SubscriptionInfo;
|
||||||
|
import android.telephony.SubscriptionManager;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
|
||||||
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
public class MobileNetworkUtilsTest {
|
||||||
|
private static final int SUB_ID_1 = 1;
|
||||||
|
private static final int SUB_ID_2 = 2;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private TelephonyManager mTelephonyManager;
|
||||||
|
@Mock
|
||||||
|
private TelephonyManager mTelephonyManager2;
|
||||||
|
@Mock
|
||||||
|
private SubscriptionManager mSubscriptionManager;
|
||||||
|
@Mock
|
||||||
|
private SubscriptionInfo mSubscriptionInfo1;
|
||||||
|
@Mock
|
||||||
|
private SubscriptionInfo mSubscriptionInfo2;
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
|
mContext = spy(RuntimeEnvironment.application);
|
||||||
|
doReturn(mSubscriptionManager).when(mContext).getSystemService(SubscriptionManager.class);
|
||||||
|
doReturn(mTelephonyManager).when(mContext).getSystemService(Context.TELEPHONY_SERVICE);
|
||||||
|
doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID_1);
|
||||||
|
doReturn(mTelephonyManager2).when(mTelephonyManager).createForSubscriptionId(SUB_ID_2);
|
||||||
|
|
||||||
|
doReturn(SUB_ID_1).when(mSubscriptionInfo1).getSubscriptionId();
|
||||||
|
doReturn(SUB_ID_2).when(mSubscriptionInfo2).getSubscriptionId();
|
||||||
|
|
||||||
|
doReturn(Arrays.asList(mSubscriptionInfo1, mSubscriptionInfo2)).when(
|
||||||
|
mSubscriptionManager).getActiveSubscriptionInfoList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setMobileDataEnabled_setEnabled_enabled() {
|
||||||
|
MobileNetworkUtils.setMobileDataEnabled(mContext, SUB_ID_1, true, false);
|
||||||
|
|
||||||
|
verify(mTelephonyManager).setDataEnabled(true);
|
||||||
|
verify(mTelephonyManager2, never()).setDataEnabled(anyBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setMobileDataEnabled_setDisabled_disabled() {
|
||||||
|
MobileNetworkUtils.setMobileDataEnabled(mContext, SUB_ID_2, true, false);
|
||||||
|
|
||||||
|
verify(mTelephonyManager2).setDataEnabled(true);
|
||||||
|
verify(mTelephonyManager, never()).setDataEnabled(anyBoolean());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setMobileDataEnabled_disableOtherSubscriptions() {
|
||||||
|
MobileNetworkUtils.setMobileDataEnabled(mContext, SUB_ID_1, true, true);
|
||||||
|
|
||||||
|
verify(mTelephonyManager).setDataEnabled(true);
|
||||||
|
verify(mTelephonyManager2).setDataEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
@@ -30,6 +30,10 @@ import android.telephony.SubscriptionManager;
|
|||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.fragment.app.FragmentTransaction;
|
||||||
|
|
||||||
import com.android.internal.view.menu.ContextMenuBuilder;
|
import com.android.internal.view.menu.ContextMenuBuilder;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
@@ -46,10 +50,6 @@ import org.robolectric.RuntimeEnvironment;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.fragment.app.FragmentManager;
|
|
||||||
import androidx.fragment.app.FragmentTransaction;
|
|
||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
public class MobileSettingsActivityTest {
|
public class MobileSettingsActivityTest {
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user