--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<PreferenceScreen
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:settings="http://schemas.android.com/apk/res-auto"
+ android:key="mobile_network_pref_screen"
+ settings:initialExpandedChildrenCount="5">
+
+ <com.android.settings.datausage.DataUsageSummaryPreference
+ android:key="status_header"
+ android:visibility="gone"
+ android:selectable="false" />
+
+ <Preference
+ android:key="cdma_lte_data_service_key"
+ android:title="@string/cdma_lte_data_service"
+ settings:controller="com.android.settings.network.telephony.DataServiceSetupPreferenceController">
+ </Preference>
+
+ <SwitchPreference
+ android:key="mobile_data_enable"
+ android:title="@string/mobile_data_settings_title"
+ android:summary="@string/mobile_data_settings_summary"
+ settings:controller="com.android.settings.network.telephony.MobileDataPreferenceController"/>
+
+ <com.android.settingslib.RestrictedSwitchPreference
+ android:key="button_roaming_key"
+ android:title="@string/roaming"
+ android:persistent="false"
+ android:summaryOn="@string/roaming_enable"
+ android:summaryOff="@string/roaming_disable"
+ settings:userRestriction="no_data_roaming"
+ settings:controller="com.android.settings.network.telephony.RoamingPreferenceController"/>
+
+ <Preference
+ android:key="data_usage_summary"
+ android:title="@string/mobile_data_usage_title"
+ settings:controller="com.android.settings.network.telephony.DataUsagePreferenceController"/>
+
+ <SwitchPreference
+ android:key="enhanced_4g_lte"
+ android:title="@string/enhanced_4g_lte_mode_title"
+ android:persistent="false"
+ android:summary="@string/enhanced_4g_lte_mode_summary"
+ settings:controller="com.android.settings.network.telephony.Enhanced4gLtePreferenceController"/>
+
+ <ListPreference
+ android:key="preferred_network_mode_key"
+ android:title="@string/preferred_network_mode_title"
+ android:summary="@string/preferred_network_mode_summary"
+ android:entries="@array/preferred_network_mode_choices"
+ android:entryValues="@array/preferred_network_mode_values"
+ android:dialogTitle="@string/preferred_network_mode_dialogtitle"
+ settings:controller="com.android.settings.network.telephony.PreferredNetworkModePreferenceController"/>
+
+ <ListPreference
+ android:key="enabled_networks_key"
+ android:title="@string/preferred_network_mode_title"
+ android:summary="@string/preferred_network_mode_summary"
+ android:entries="@array/enabled_networks_choices"
+ android:entryValues="@array/enabled_networks_values"
+ android:dialogTitle="@string/preferred_network_mode_dialogtitle"
+ settings:controller="com.android.settings.network.telephony.EnabledNetworkModePreferenceController"/>
+
+ <Preference
+ android:key="carrier_settings_euicc_key"
+ android:title="@string/carrier_settings_euicc"
+ settings:controller="com.android.settings.network.telephony.EuiccPreferenceController" />
+
+ <PreferenceCategory
+ android:key="calling_category"
+ android:title="@string/call_category">
+
+ <PreferenceScreen
+ android:key="wifi_calling_key"
+ android:title="@string/wifi_calling_settings_title"
+ settings:controller="com.android.settings.network.telephony.WifiCallingPreferenceController" >
+ <intent android:action="android.intent.action.MAIN"
+ android:targetPackage="com.android.settings"
+ android:targetClass="com.android.settings.Settings$WifiCallingSettingsActivity">
+ <extra android:name="show_drawer_menu" android:value="true" />
+ </intent>
+ </PreferenceScreen>
+
+ <SwitchPreference
+ android:key="video_calling_key"
+ android:title="@string/video_calling_settings_title"
+ android:persistent="true"
+ settings:controller="com.android.settings.network.telephony.VideoCallingPreferenceController" />
+
+ </PreferenceCategory>
+
+ <com.android.settings.network.telephony.cdma.CdmaListPreference
+ android:key="cdma_system_select_key"
+ android:title="@string/cdma_system_select_title"
+ android:summary="@string/cdma_system_select_summary"
+ android:entries="@array/cdma_system_select_choices"
+ android:entryValues="@array/cdma_system_select_values"
+ android:dialogTitle="@string/cdma_system_select_dialogtitle"
+ settings:controller="com.android.settings.network.telephony.cdma.CdmaSystemSelectPreferenceController"/>
+
+ <com.android.settings.network.telephony.cdma.CdmaListPreference
+ android:key="cdma_subscription_key"
+ android:title="@string/cdma_subscription_title"
+ android:summary="@string/cdma_subscription_summary"
+ android:entries="@array/cdma_subscription_choices"
+ android:entryValues="@array/cdma_subscription_values"
+ android:dialogTitle="@string/cdma_subscription_dialogtitle"
+ settings:controller="com.android.settings.network.telephony.cdma.CdmaSubscriptionPreferenceController"/>
+
+ <PreferenceCategory
+ android:key="network_operators_category_key"
+ android:title="@string/network_operator_category"
+ settings:controller="com.android.settings.widget.PreferenceCategoryController">
+
+ <SwitchPreference
+ android:key="auto_select_key"
+ android:title="@string/select_automatically"
+ settings:controller="com.android.settings.network.telephony.gsm.AutoSelectPreferenceController"/>
+
+ <Preference
+ android:key="choose_network_key"
+ android:title="@string/choose_network_title"
+ android:fragment="com.android.phone.NetworkSelectSetting"
+ settings:controller="com.android.settings.network.telephony.gsm.OpenNetworkSelectPagePreferenceController"/>
+ </PreferenceCategory>
+
+ <!--We want separate APN setting from reset of settings because we want user to change it with caution-->
+ <com.android.settingslib.RestrictedPreference
+ android:key="telephony_apn_key"
+ android:persistent="false"
+ android:title="@string/mobile_network_apn_title"
+ settings:allowDividerAbove="true"
+ settings:controller="com.android.settings.network.telephony.ApnPreferenceController"/>
+
+ <Preference
+ android:key="carrier_settings_key"
+ android:title="@string/carrier_settings_title"
+ settings:controller="com.android.settings.network.telephony.CarrierPreferenceController">
+ </Preference>
+
+</PreferenceScreen>
final Activity activity = getActivity();
final ArrayList<AbstractPreferenceController> controllers = new ArrayList<>();
mSummaryController =
- new DataUsageSummaryPreferenceController(activity, getSettingsLifecycle(), this);
+ new DataUsageSummaryPreferenceController(activity, getSettingsLifecycle(), this,
+ DataUsageUtils.getDefaultSubscriptionId(activity));
controllers.add(mSummaryController);
getSettingsLifecycle().addObserver(mSummaryController);
return controllers;
import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
+import androidx.preference.PreferenceFragmentCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.android.internal.util.CollectionUtils;
import java.util.List;
/**
- * This is the controller for the top of the data usage screen that retrieves carrier data from the
- * new subscriptions framework API if available. The controller reads subscription information from
- * the framework and falls back to legacy usage data if none are available.
+ * This is the controller for a data usage header that retrieves carrier data from the new
+ * subscriptions framework API if available. The controller reads subscription information from the
+ * framework and falls back to legacy usage data if none are available.
*/
public class DataUsageSummaryPreferenceController extends BasePreferenceController
implements PreferenceControllerMixin, LifecycleObserver, OnStart {
private final Activity mActivity;
private final EntityHeaderController mEntityHeaderController;
private final Lifecycle mLifecycle;
- private final DataUsageSummary mDataUsageSummary;
+ private final PreferenceFragmentCompat mFragment;
private final DataUsageController mDataUsageController;
private final DataUsageInfoController mDataInfoController;
private final NetworkTemplate mDefaultTemplate;
private long mCycleStart;
/** The ending time of the billing cycle in ms since the epoch */
private long mCycleEnd;
+ /** The subscription that we should show usage for. */
+ private int mSubscriptionId;
private Intent mManageSubscriptionIntent;
public DataUsageSummaryPreferenceController(Activity activity,
- Lifecycle lifecycle, DataUsageSummary dataUsageSummary) {
+ Lifecycle lifecycle, PreferenceFragmentCompat fragment, int subscriptionId) {
super(activity, KEY);
mActivity = activity;
mEntityHeaderController = EntityHeaderController.newInstance(activity,
- dataUsageSummary, null);
+ fragment, null);
mLifecycle = lifecycle;
- mDataUsageSummary = dataUsageSummary;
+ mFragment = fragment;
+ mSubscriptionId = subscriptionId;
- final int defaultSubId = DataUsageUtils.getDefaultSubscriptionId(activity);
- mDefaultTemplate = DataUsageUtils.getDefaultTemplate(activity, defaultSubId);
- NetworkPolicyManager policyManager = NetworkPolicyManager.from(activity);
+ mDefaultTemplate = DataUsageUtils.getDefaultTemplate(activity, mSubscriptionId);
+ NetworkPolicyManager policyManager = activity.getSystemService(NetworkPolicyManager.class);
mPolicyEditor = new NetworkPolicyEditor(policyManager);
mHasMobileData = DataUsageUtils.hasMobileData(activity)
- && defaultSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ && mSubscriptionId != SubscriptionManager.INVALID_SUBSCRIPTION_ID;
mDataUsageController = new DataUsageController(activity);
+ mDataUsageController.setSubscriptionId(mSubscriptionId);
mDataInfoController = new DataUsageInfoController();
if (mHasMobileData) {
Activity activity,
Lifecycle lifecycle,
EntityHeaderController entityHeaderController,
- DataUsageSummary dataUsageSummary) {
+ PreferenceFragmentCompat fragment,
+ int subscriptionId) {
super(activity, KEY);
mDataUsageController = dataUsageController;
mDataInfoController = dataInfoController;
mActivity = activity;
mLifecycle = lifecycle;
mEntityHeaderController = entityHeaderController;
- mDataUsageSummary = dataUsageSummary;
+ mFragment = fragment;
+ mSubscriptionId = subscriptionId;
}
@Override
public void onStart() {
- RecyclerView view = mDataUsageSummary.getListView();
+ RecyclerView view = mFragment.getListView();
mEntityHeaderController.setRecyclerView(view, mLifecycle);
mEntityHeaderController.styleActionBar(mActivity);
}
mCycleEnd = info.cycleEnd;
mSnapshotTime = -1L;
- final int defaultSubId = SubscriptionManager.getDefaultSubscriptionId();
- final SubscriptionInfo subInfo = mSubscriptionManager.getDefaultDataSubscriptionInfo();
+ SubscriptionInfo subInfo = mSubscriptionManager.getActiveSubscriptionInfo(mSubscriptionId);
+ if (subInfo == null) {
+ subInfo = mSubscriptionManager.getAllSubscriptionInfoList().stream().filter(
+ i -> i.getSubscriptionId() == mSubscriptionId).findFirst().orElse(null);
+ }
if (subInfo != null && mHasMobileData) {
mCarrierName = subInfo.getCarrierName();
- List<SubscriptionPlan> plans = mSubscriptionManager.getSubscriptionPlans(defaultSubId);
- final SubscriptionPlan primaryPlan = getPrimaryPlan(mSubscriptionManager, defaultSubId);
+ List<SubscriptionPlan> plans = mSubscriptionManager.getSubscriptionPlans(
+ mSubscriptionId);
+ final SubscriptionPlan primaryPlan = getPrimaryPlan(mSubscriptionManager,
+ mSubscriptionId);
+
if (primaryPlan != null) {
mDataplanCount = plans.size();
mDataplanSize = primaryPlan.getDataLimitBytes();
}
}
mManageSubscriptionIntent =
- mSubscriptionManager.createManageSubscriptionIntent(defaultSubId);
- Log.i(TAG, "Have " + mDataplanCount + " plans, dflt sub-id " + defaultSubId
+ mSubscriptionManager.createManageSubscriptionIntent(mSubscriptionId);
+ Log.i(TAG, "Have " + mDataplanCount + " plans, dflt sub-id " + mSubscriptionId
+ ", intent " + mManageSubscriptionIntent);
}
import com.android.internal.telephony.TelephonyIntents;
import com.android.settings.R;
+import com.android.settings.core.FeatureFlags;
import com.android.settings.dashboard.RestrictedDashboardFragment;
+import com.android.settings.datausage.DataUsageSummaryPreferenceController;
+import com.android.settings.development.featureflags.FeatureFlagPersistent;
import com.android.settings.network.telephony.cdma.CdmaSubscriptionPreferenceController;
import com.android.settings.network.telephony.cdma.CdmaSystemSelectPreferenceController;
import com.android.settings.network.telephony.gsm.AutoSelectPreferenceController;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.widget.PreferenceCategoryController;
+import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.search.SearchIndexable;
import java.util.ArrayList;
}
@Override
- public void onAttach(Context context) {
- super.onAttach(context);
-
+ protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
mSubId = getArguments().getInt(Settings.EXTRA_SUB_ID,
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+ if (FeatureFlagPersistent.isEnabled(getContext(), FeatureFlags.NETWORK_INTERNET_V2) &&
+ mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+ return Arrays.asList(
+ new DataUsageSummaryPreferenceController(getActivity(), getSettingsLifecycle(),
+ this, mSubId));
+ }
+ return Arrays.asList();
+ }
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+
use(MobileDataPreferenceController.class).init(getFragmentManager(), mSubId);
use(RoamingPreferenceController.class).init(getFragmentManager(), mSubId);
use(ApnPreferenceController.class).init(mSubId);
@Override
protected int getPreferenceScreenResId() {
- return R.xml.mobile_network_settings;
+ if (FeatureFlagPersistent.isEnabled(getContext(), FeatureFlags.NETWORK_INTERNET_V2)) {
+ return R.xml.mobile_network_settings_v2;
+ } else {
+ return R.xml.mobile_network_settings;
+ }
}
@Override
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkTemplate;
-import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import androidx.fragment.app.FragmentActivity;
+import androidx.preference.PreferenceFragmentCompat;
import androidx.recyclerview.widget.RecyclerView;
import com.android.internal.logging.nano.MetricsProto;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private EntityHeaderController mHeaderController;
@Mock
- private DataUsageSummary mDataUsageSummary;
+ private PreferenceFragmentCompat mPreferenceFragment;
@Mock
private TelephonyManager mTelephonyManager;
@Mock
private FragmentActivity mActivity;
private Context mContext;
private DataUsageSummaryPreferenceController mController;
+ private int mDefaultSubscriptionId;
@Before
public void setUp() {
.thenReturn(mConnectivityManager);
when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY);
when(mConnectivityManager.isNetworkSupported(TYPE_WIFI)).thenReturn(false);
+ mDefaultSubscriptionId = 1234;
mController = new DataUsageSummaryPreferenceController(
mDataUsageController,
mDataInfoController,
R.string.cell_data_template,
true,
null,
- mActivity, null, null, null);
+ mActivity, null, null, null, mDefaultSubscriptionId);
}
@After
R.string.cell_data_template,
true,
mSubscriptionManager,
- mActivity, null, null, null);
-
- final SubscriptionInfo subInfo = new SubscriptionInfo(0, "123456", 0, "name", "carrier",
- 0, 0, "number", 0, null, "123", "456", "ZX", false, null, null);
- when(mSubscriptionManager.getDefaultDataSubscriptionInfo()).thenReturn(subInfo);
+ mActivity, null, null, null, mDefaultSubscriptionId);
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
R.string.cell_data_template,
true,
mSubscriptionManager,
- mActivity, null, null, null);
+ mActivity, null, null, null, mDefaultSubscriptionId);
when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_ABSENT);
when(mConnectivityManager.isNetworkSupported(TYPE_WIFI)).thenReturn(false);
R.string.cell_data_template,
true,
mSubscriptionManager,
- mActivity, null, null, null);
+ mActivity, null, null, null, mDefaultSubscriptionId);
when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_ABSENT);
when(mConnectivityManager.isNetworkSupported(TYPE_WIFI)).thenReturn(true);
R.string.cell_data_template,
true,
mSubscriptionManager,
- mActivity, mLifecycle, mHeaderController, mDataUsageSummary);
+ mActivity, mLifecycle, mHeaderController, mPreferenceFragment,
+ mDefaultSubscriptionId);
- when(mDataUsageSummary.getListView()).thenReturn(recyclerView);
+ when(mPreferenceFragment.getListView()).thenReturn(recyclerView);
mController.onStart();
--- /dev/null
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network.telephony;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.app.usage.NetworkStatsManager;
+import android.content.Context;
+import android.net.NetworkPolicyManager;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.telephony.TelephonyManager;
+
+import com.android.settings.core.FeatureFlags;
+import com.android.settings.datausage.DataUsageSummaryPreferenceController;
+import com.android.settings.development.featureflags.FeatureFlagPersistent;
+import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
+import com.android.settings.widget.EntityHeaderController;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import java.util.List;
+
+import androidx.fragment.app.FragmentActivity;
+
+@RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowEntityHeaderController.class)
+public class MobileNetworkSettingsTest {
+ @Mock
+ private TelephonyManager mTelephonyManager;
+ @Mock
+ private NetworkStatsManager mNetworkStatsManager;
+ @Mock
+ private NetworkPolicyManager mNetworkPolicyManager;
+ @Mock
+ private FragmentActivity mActivity;
+
+ private Context mContext;
+ private MobileNetworkSettings mFragment;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
+ when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
+ when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager);
+ when(mContext.getSystemService(NetworkStatsManager.class)).thenReturn(mNetworkStatsManager);
+ ShadowEntityHeaderController.setUseMock(mock(EntityHeaderController.class));
+
+ mFragment = spy(new MobileNetworkSettings());
+ final Bundle args = new Bundle();
+ final int subscriptionId = 1234;
+ args.putInt(Settings.EXTRA_SUB_ID, subscriptionId);
+ mFragment.setArguments(args);
+ when(mFragment.getActivity()).thenReturn(mActivity);
+ when(mActivity.getSystemService(NetworkPolicyManager.class)).thenReturn(
+ mNetworkPolicyManager);
+ }
+
+ @Test
+ public void onAttach_noCrash() {
+ mFragment.onAttach(mContext);
+ }
+
+ @Test
+ public void createPreferenceControllers_noV2Flag_noDataUsageSummaryController() {
+ final List<AbstractPreferenceController> controllers =
+ mFragment.createPreferenceControllers(mContext);
+ assertThat(controllers.stream().filter(
+ c -> c.getClass().equals(DataUsageSummaryPreferenceController.class))
+ .count())
+ .isEqualTo(0);
+ }
+
+ @Test
+ public void createPreferenceControllers_v2Flag_createsDataUsageSummaryController() {
+ FeatureFlagPersistent.setEnabled(mContext, FeatureFlags.NETWORK_INTERNET_V2, true);
+
+ final List<AbstractPreferenceController> controllers =
+ mFragment.createPreferenceControllers(mContext);
+ assertThat(controllers.stream().filter(
+ c -> c.getClass().equals(DataUsageSummaryPreferenceController.class))
+ .count())
+ .isEqualTo(1);
+ }
+}