Merge "[Provider mode] Display network type on mobile data preference."
This commit is contained in:
@@ -20,6 +20,8 @@ import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE;
|
||||
import static androidx.lifecycle.Lifecycle.Event.ON_RESUME;
|
||||
|
||||
import static com.android.settings.network.telephony.MobileNetworkUtils.NO_CELL_DATA_TYPE_ICON;
|
||||
import static com.android.settingslib.mobile.MobileMappings.getIconKey;
|
||||
import static com.android.settingslib.mobile.MobileMappings.mapIconSets;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
@@ -31,6 +33,7 @@ import android.telephony.ServiceState;
|
||||
import android.telephony.SignalStrength;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyDisplayInfo;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.ArraySet;
|
||||
|
||||
@@ -49,9 +52,12 @@ import com.android.settings.network.telephony.DataConnectivityListener;
|
||||
import com.android.settings.network.telephony.MobileNetworkActivity;
|
||||
import com.android.settings.network.telephony.MobileNetworkUtils;
|
||||
import com.android.settings.network.telephony.SignalStrengthListener;
|
||||
import com.android.settings.network.telephony.TelephonyDisplayInfoListener;
|
||||
import com.android.settings.widget.GearPreference;
|
||||
import com.android.settings.wifi.WifiPickerTrackerHelper;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.mobile.MobileMappings;
|
||||
import com.android.settingslib.mobile.MobileMappings.Config;
|
||||
import com.android.settingslib.net.SignalStrengthUtil;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -73,7 +79,7 @@ import java.util.Set;
|
||||
public class SubscriptionsPreferenceController extends AbstractPreferenceController implements
|
||||
LifecycleObserver, SubscriptionsChangeListener.SubscriptionsChangeListenerClient,
|
||||
MobileDataEnabledListener.Client, DataConnectivityListener.Client,
|
||||
SignalStrengthListener.Callback {
|
||||
SignalStrengthListener.Callback, TelephonyDisplayInfoListener.Callback {
|
||||
private static final String TAG = "SubscriptionsPrefCntrlr";
|
||||
|
||||
private UpdateListener mUpdateListener;
|
||||
@@ -85,6 +91,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
||||
private MobileDataEnabledListener mDataEnabledListener;
|
||||
private DataConnectivityListener mConnectivityListener;
|
||||
private SignalStrengthListener mSignalStrengthListener;
|
||||
private TelephonyDisplayInfoListener mTelephonyDisplayInfoListener;
|
||||
private WifiPickerTrackerHelper mWifiPickerTrackerHelper;
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -93,6 +100,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
final String action = intent.getAction();
|
||||
if (action.equals(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)) {
|
||||
mConfig = mSubsPrefCtrlInjector.getConfig(mContext);
|
||||
update();
|
||||
}
|
||||
}
|
||||
@@ -102,8 +110,12 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
||||
private Map<Integer, Preference> mSubscriptionPreferences;
|
||||
private int mStartOrder;
|
||||
private GearPreference mSubsGearPref;
|
||||
|
||||
private Config mConfig = null;
|
||||
private SubsPrefCtrlInjector mSubsPrefCtrlInjector;
|
||||
private TelephonyDisplayInfo mTelephonyDisplayInfo =
|
||||
new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_UNKNOWN,
|
||||
TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE);
|
||||
|
||||
/**
|
||||
* This interface lets a parent of this class know that some change happened - this could
|
||||
* either be because overall availability changed, or because we've added/removed/updated some
|
||||
@@ -140,8 +152,10 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
||||
mDataEnabledListener = new MobileDataEnabledListener(context, this);
|
||||
mConnectivityListener = new DataConnectivityListener(context, this);
|
||||
mSignalStrengthListener = new SignalStrengthListener(context, this);
|
||||
mTelephonyDisplayInfoListener = new TelephonyDisplayInfoListener(context, this);
|
||||
lifecycle.addObserver(this);
|
||||
mSubsPrefCtrlInjector = createSubsPrefCtrlInjector();
|
||||
mConfig = mSubsPrefCtrlInjector.getConfig(mContext);
|
||||
}
|
||||
|
||||
private void registerDataSubscriptionChangedReceiver() {
|
||||
@@ -163,6 +177,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
||||
mDataEnabledListener.start(mSubsPrefCtrlInjector.getDefaultDataSubscriptionId());
|
||||
mConnectivityListener.start();
|
||||
mSignalStrengthListener.resume();
|
||||
mTelephonyDisplayInfoListener.resume();
|
||||
registerDataSubscriptionChangedReceiver();
|
||||
update();
|
||||
}
|
||||
@@ -173,6 +188,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
||||
mDataEnabledListener.stop();
|
||||
mConnectivityListener.stop();
|
||||
mSignalStrengthListener.pause();
|
||||
mTelephonyDisplayInfoListener.pause();
|
||||
unRegisterDataSubscriptionChangedReceiver();
|
||||
}
|
||||
|
||||
@@ -196,6 +212,7 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
||||
|
||||
mSubscriptionPreferences.clear();
|
||||
mSignalStrengthListener.updateSubscriptionIds(Collections.emptySet());
|
||||
mTelephonyDisplayInfoListener.updateSubscriptionIds(Collections.emptySet());
|
||||
mUpdateListener.onChildrenUpdated();
|
||||
return;
|
||||
}
|
||||
@@ -226,22 +243,23 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
||||
|
||||
mSubsGearPref.setTitle(subInfo.getDisplayName());
|
||||
mSubsGearPref.setOrder(mStartOrder);
|
||||
//TODO(b/176141828) Wait for api provided by system ui.
|
||||
mSubsGearPref.setSummary(getMobilePreferenceSummary());
|
||||
mSubsGearPref.setSummary(getMobilePreferenceSummary(subInfo.getSubscriptionId()));
|
||||
mSubsGearPref.setIcon(getIcon(subInfo.getSubscriptionId()));
|
||||
mPreferenceGroup.addPreference(mSubsGearPref);
|
||||
|
||||
final Set<Integer> activeDataSubIds = new ArraySet<>();
|
||||
activeDataSubIds.add(subInfo.getSubscriptionId());
|
||||
mSignalStrengthListener.updateSubscriptionIds(activeDataSubIds);
|
||||
mTelephonyDisplayInfoListener.updateSubscriptionIds(activeDataSubIds);
|
||||
mUpdateListener.onChildrenUpdated();
|
||||
}
|
||||
|
||||
private String getMobilePreferenceSummary() {
|
||||
//TODO(b/176141828) Waiting for the api provided by system UI.
|
||||
String result = "5G";
|
||||
if (MobileNetworkUtils.activeNetworkIsCellular(mContext)) {
|
||||
result = "Active, " + result;
|
||||
private String getMobilePreferenceSummary(int subId) {
|
||||
String result = mSubsPrefCtrlInjector.getNetworkType(
|
||||
mContext, mConfig, mTelephonyDisplayInfo, subId);
|
||||
if (!result.isEmpty() && mSubsPrefCtrlInjector.isActiveCellularNetwork(mContext)) {
|
||||
result = mContext.getString(R.string.preference_summary_default_combination,
|
||||
mContext.getString(R.string.mobile_data_connection_active), result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -462,6 +480,12 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
||||
update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTelephonyDisplayInfoChanged(TelephonyDisplayInfo telephonyDisplayInfo) {
|
||||
mTelephonyDisplayInfo = telephonyDisplayInfo;
|
||||
update();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean canSubscriptionBeDisplayed(Context context, int subId) {
|
||||
return (SubscriptionUtil.getAvailableSubscription(context,
|
||||
@@ -534,6 +558,24 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
|
||||
return Utils.isProviderModelEnabled(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get config for carrier customization.
|
||||
*/
|
||||
public Config getConfig(Context context) {
|
||||
return MobileMappings.Config.readConfig(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current mobile network type.
|
||||
*/
|
||||
public String getNetworkType(Context context, Config config,
|
||||
TelephonyDisplayInfo telephonyDisplayInfo, int subId) {
|
||||
String iconKey = getIconKey(telephonyDisplayInfo);
|
||||
int resId = mapIconSets(config).get(iconKey).dataContentDescription;
|
||||
return resId != 0
|
||||
? SubscriptionManager.getResourcesForSubId(context, subId).getString(resId) : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get signal icon with different signal level.
|
||||
*/
|
||||
|
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.android.settings.network.telephony;
|
||||
|
||||
import android.content.Context;
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.TelephonyDisplayInfo;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Help to listen telephony display info change to subscriptions.
|
||||
* TODO(b/177647571): unit test is needed.
|
||||
*/
|
||||
public class TelephonyDisplayInfoListener {
|
||||
|
||||
private TelephonyManager mBaseTelephonyManager;
|
||||
private Callback mCallback;
|
||||
private Map<Integer, PhoneStateListener> mListeners;
|
||||
|
||||
private TelephonyDisplayInfo mTelephonyDisplayInfo =
|
||||
new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_UNKNOWN,
|
||||
TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE);
|
||||
/**
|
||||
* Interface of callback and to use notify TelephonyDisplayInfo change.
|
||||
*/
|
||||
public interface Callback {
|
||||
/**
|
||||
* Used to notify TelephonyDisplayInfo change.
|
||||
*/
|
||||
void onTelephonyDisplayInfoChanged(TelephonyDisplayInfo telephonyDisplayInfo);
|
||||
}
|
||||
|
||||
public TelephonyDisplayInfoListener(Context context, Callback callback) {
|
||||
mBaseTelephonyManager = context.getSystemService(TelephonyManager.class);
|
||||
mCallback = callback;
|
||||
mListeners = new HashMap<>();
|
||||
}
|
||||
/**
|
||||
* Get TelephonyDisplayInfo.
|
||||
*/
|
||||
public TelephonyDisplayInfo getTelephonyDisplayInfo() {
|
||||
return mTelephonyDisplayInfo;
|
||||
}
|
||||
|
||||
/** Resumes listening telephony display info changes to the set of ids from the last call to
|
||||
* {@link #updateSubscriptionIds(Set)} */
|
||||
public void resume() {
|
||||
for (int subId : mListeners.keySet()) {
|
||||
startListening(subId);
|
||||
}
|
||||
}
|
||||
|
||||
/** Pauses listening for telephony display info changes */
|
||||
public void pause() {
|
||||
for (int subId : mListeners.keySet()) {
|
||||
stopListening(subId);
|
||||
}
|
||||
}
|
||||
|
||||
/** Updates the set of ids we want to be listening for, beginning to listen for any new ids and
|
||||
* stopping listening for any ids not contained in the new set */
|
||||
public void updateSubscriptionIds(Set<Integer> ids) {
|
||||
Set<Integer> currentIds = new ArraySet<>(mListeners.keySet());
|
||||
for (int idToRemove : Sets.difference(currentIds, ids)) {
|
||||
stopListening(idToRemove);
|
||||
mListeners.remove(idToRemove);
|
||||
}
|
||||
for (int idToAdd : Sets.difference(ids, currentIds)) {
|
||||
PhoneStateListener listener = new PhoneStateListener() {
|
||||
@Override
|
||||
public void onDisplayInfoChanged(TelephonyDisplayInfo telephonyDisplayInfo) {
|
||||
mTelephonyDisplayInfo = telephonyDisplayInfo;
|
||||
mCallback.onTelephonyDisplayInfoChanged(telephonyDisplayInfo);
|
||||
}
|
||||
};
|
||||
mListeners.put(idToAdd, listener);
|
||||
startListening(idToAdd);
|
||||
}
|
||||
}
|
||||
|
||||
private void startListening(int subId) {
|
||||
TelephonyManager mgr = mBaseTelephonyManager.createForSubscriptionId(subId);
|
||||
mgr.listen(mListeners.get(subId), PhoneStateListener.LISTEN_DISPLAY_INFO_CHANGED);
|
||||
}
|
||||
|
||||
private void stopListening(int subId) {
|
||||
TelephonyManager mgr = mBaseTelephonyManager.createForSubscriptionId(subId);
|
||||
mgr.listen(mListeners.get(subId), PhoneStateListener.LISTEN_NONE);
|
||||
}
|
||||
}
|
@@ -45,6 +45,7 @@ import android.telephony.ServiceState;
|
||||
import android.telephony.SignalStrength;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyDisplayInfo;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
@@ -62,6 +63,7 @@ import com.android.settings.network.SubscriptionsPreferenceController.SubsPrefCt
|
||||
import com.android.settings.testutils.ResourcesUtils;
|
||||
import com.android.settings.wifi.WifiPickerTrackerHelper;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.mobile.MobileMappings;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
@@ -102,7 +104,6 @@ public class SubscriptionsPreferenceControllerTest {
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
private PreferenceManager mPreferenceManager;
|
||||
private NetworkCapabilities mNetworkCapabilities;
|
||||
|
||||
private FakeSubscriptionsPreferenceController mController;
|
||||
private static SubsPrefCtrlInjector sInjector;
|
||||
|
||||
@@ -134,6 +135,7 @@ public class SubscriptionsPreferenceControllerTest {
|
||||
|
||||
mOnChildUpdatedCount = 0;
|
||||
mUpdateListener = () -> mOnChildUpdatedCount++;
|
||||
|
||||
sInjector = spy(new SubsPrefCtrlInjector());
|
||||
initializeMethod(true, 1, 1, 1, false, false);
|
||||
mController = new FakeSubscriptionsPreferenceController(mContext, mLifecycle,
|
||||
@@ -408,6 +410,45 @@ public class SubscriptionsPreferenceControllerTest {
|
||||
assertThat(mPreferenceCategory.getPreference(0).getTitle()).isEqualTo("sub1");
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void displayPreference_providerAndHasMultiSimAndActive_connectedAndRat() {
|
||||
final String expectedSummary = "Connected / 5G";
|
||||
final String networkType = "5G";
|
||||
final List<SubscriptionInfo> sub = setupMockSubscriptions(2);
|
||||
doReturn(true).when(sInjector).isProviderModelEnabled(mContext);
|
||||
doReturn(sub.get(0)).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
|
||||
setupGetIconConditions(sub.get(0).getSubscriptionId(), true, true,
|
||||
TelephonyManager.DATA_CONNECTED, ServiceState.STATE_IN_SERVICE);
|
||||
doReturn(mock(MobileMappings.Config.class)).when(sInjector).getConfig(mContext);
|
||||
doReturn(networkType)
|
||||
.when(sInjector).getNetworkType(any(), any(), any(), anyInt());
|
||||
|
||||
mController.onResume();
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
|
||||
assertThat(mPreferenceCategory.getPreference(0).getSummary()).isEqualTo(expectedSummary);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void displayPreference_providerAndHasMultiSimAndNotActive_showRatOnly() {
|
||||
final String expectedSummary = "5G";
|
||||
final String networkType = "5G";
|
||||
final List<SubscriptionInfo> sub = setupMockSubscriptions(2);
|
||||
doReturn(true).when(sInjector).isProviderModelEnabled(mContext);
|
||||
doReturn(sub.get(0)).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
|
||||
setupGetIconConditions(sub.get(0).getSubscriptionId(), false, true,
|
||||
TelephonyManager.DATA_CONNECTED, ServiceState.STATE_IN_SERVICE);
|
||||
doReturn(networkType)
|
||||
.when(sInjector).getNetworkType(any(), any(), any(), anyInt());
|
||||
|
||||
mController.onResume();
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
|
||||
assertThat(mPreferenceCategory.getPreference(0).getSummary()).isEqualTo(expectedSummary);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void displayPreference_providerAndNoSim_noPreference() {
|
||||
@@ -420,6 +461,54 @@ public class SubscriptionsPreferenceControllerTest {
|
||||
assertThat(mPreferenceCategory.getPreferenceCount()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void onTelephonyDisplayInfoChanged_providerAndHasMultiSimAndActive_connectedAndRat() {
|
||||
final String expectedSummary = "Connected / LTE";
|
||||
final String networkType = "LTE";
|
||||
final List<SubscriptionInfo> sub = setupMockSubscriptions(2);
|
||||
final TelephonyDisplayInfo telephonyDisplayInfo =
|
||||
new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_UNKNOWN,
|
||||
TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE);
|
||||
doReturn(true).when(sInjector).isProviderModelEnabled(mContext);
|
||||
doReturn(sub.get(0)).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
|
||||
setupGetIconConditions(sub.get(0).getSubscriptionId(), true, true,
|
||||
TelephonyManager.DATA_CONNECTED, ServiceState.STATE_IN_SERVICE);
|
||||
doReturn(mock(MobileMappings.Config.class)).when(sInjector).getConfig(mContext);
|
||||
doReturn(networkType)
|
||||
.when(sInjector).getNetworkType(any(), any(), any(), anyInt());
|
||||
|
||||
mController.onResume();
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
mController.onTelephonyDisplayInfoChanged(telephonyDisplayInfo);
|
||||
|
||||
assertThat(mPreferenceCategory.getPreference(0).getSummary()).isEqualTo(expectedSummary);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void onTelephonyDisplayInfoChanged_providerAndHasMultiSimAndNotActive_showRat() {
|
||||
final String expectedSummary = "LTE";
|
||||
final String networkType = "LTE";
|
||||
final List<SubscriptionInfo> sub = setupMockSubscriptions(2);
|
||||
final TelephonyDisplayInfo telephonyDisplayInfo =
|
||||
new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_UNKNOWN,
|
||||
TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE);
|
||||
doReturn(true).when(sInjector).isProviderModelEnabled(mContext);
|
||||
doReturn(sub.get(0)).when(mSubscriptionManager).getDefaultDataSubscriptionInfo();
|
||||
setupGetIconConditions(sub.get(0).getSubscriptionId(), false, true,
|
||||
TelephonyManager.DATA_CONNECTED, ServiceState.STATE_IN_SERVICE);
|
||||
doReturn(mock(MobileMappings.Config.class)).when(sInjector).getConfig(mContext);
|
||||
doReturn(networkType)
|
||||
.when(sInjector).getNetworkType(any(), any(), any(), anyInt());
|
||||
|
||||
mController.onResume();
|
||||
mController.displayPreference(mPreferenceScreen);
|
||||
mController.onTelephonyDisplayInfoChanged(telephonyDisplayInfo);
|
||||
|
||||
assertThat(mPreferenceCategory.getPreference(0).getSummary()).isEqualTo(expectedSummary);
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void onAirplaneModeChanged_providerAndHasSim_noPreference() {
|
||||
|
Reference in New Issue
Block a user