Convert dataDuringCall to autoDataSWitch

The feature is enabled via
TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH. The feature only
applies to non-DDS. If enabled, we automatically switch to the non-DDS for data traffic when it has better availability than the DDS.

The UI change are(as required by b/247880971):
1. data during call is replaced by auto data switch, and moved under
   mobile data toggle.
2. Network & internet and Internet page now show the currently active
   subscription, instead of the defalut subscription. If the currently
   active sub is not the default, it's reflected in summary as
   "temporarily".

Test: manual
Bug: 244064524
Change-Id: Ica1eba99cee0d4af528d58f1c7bd1439400bfa66
This commit is contained in:
Ling Ma
2022-09-15 11:15:47 -07:00
parent 981458c8ac
commit 4e7f783906
9 changed files with 106 additions and 32 deletions

View File

@@ -6840,12 +6840,12 @@
<!-- Title of a preference for whether to allow data during calls that is shown when mobile
data is turned off. This is needed for some multi-SIM scenarios, because the SIM that is
default for data might not be available during a phone call. [CHAR LIMIT=60] -->
<string name="data_during_calls_title">Data during calls</string>
<string name="auto_data_switch_title">Switch mobile data automatically</string>
<!-- Title of a preference for whether to allow data during calls that is shown when mobile
data is turned off. This is needed for some multi-SIM scenarios, because the SIM that is
default for data might not be available during a phone call. [CHAR LIMIT=NONE] -->
<string name="data_during_calls_summary">
Allow this SIM to be used for mobile data only during calls
<string name="auto_data_switch_summary">
Temporarily use this network when it has better availability for calls and internet
</string>
<!-- Work SIM title. [CHAR LIMIT=50] -->
@@ -11389,6 +11389,12 @@
<!-- Provider Model:
Summary indicating that a SIM has an active mobile data connection [CHAR LIMIT=50] -->
<string name="mobile_data_connection_active">Connected</string>
<!-- Provider Model:
Summary indicating that a SIM has an active mobile data connection [CHAR LIMIT=50] -->
<string name="mobile_data_temp_connection_active">Temporarily connected</string>
<!-- Provider Model:
Summary indicating that a SIM is temporarily connected to mobile data [CHAR LIMIT=50] -->
<string name="mobile_data_temp_using">Temporarily using <xliff:g id="subName" example="Google Fi">%1$s</xliff:g></string>
<!-- Provider Model:
Summary indicating that a active SIM and no network available [CHAR LIMIT=50] -->
<string name="mobile_data_no_connection">No connection</string>

View File

@@ -59,6 +59,12 @@
settings:controller="com.android.settings.network.telephony.MobileDataPreferenceController"
settings:allowDividerAbove="true"/>
<SwitchPreference
android:key="auto_data_switch"
android:title="@string/auto_data_switch_title"
android:summary="@string/auto_data_switch_summary"
settings:controller="com.android.settings.network.telephony.AutoDataSwitchPreferenceController"/>
<com.android.settingslib.RestrictedSwitchPreference
android:key="button_roaming_key"
android:title="@string/roaming"
@@ -96,12 +102,6 @@
android:summary="@string/mms_message_summary"
settings:controller="com.android.settings.network.telephony.MmsMessagePreferenceController"/>
<SwitchPreference
android:key="data_during_calls"
android:title="@string/data_during_calls_title"
android:summary="@string/data_during_calls_summary"
settings:controller="com.android.settings.network.telephony.DataDuringCallsPreferenceController"/>
<SwitchPreference
android:key="enhanced_4g_lte"
android:title="@string/enhanced_4g_lte_mode_title"

View File

@@ -192,11 +192,22 @@ public class InternetPreferenceController extends AbstractPreferenceController i
if (subscriptionManager == null) {
return;
}
SubscriptionInfo subInfo = subscriptionManager.getDefaultDataSubscriptionInfo();
SubscriptionInfo subInfo = subscriptionManager.getActiveSubscriptionInfo(
SubscriptionManager.getActiveDataSubscriptionId());
SubscriptionInfo defaultSubInfo = subscriptionManager.getDefaultDataSubscriptionInfo();
subInfo = subscriptionManager.isSubscriptionVisible(subInfo) ? subInfo : defaultSubInfo;
if (subInfo == null) {
return;
}
mPreference.setSummary(SubscriptionUtil.getUniqueSubscriptionDisplayName(
subInfo, mContext));
CharSequence summary;
if (subInfo.equals(defaultSubInfo)) {
// DDS is active
summary = SubscriptionUtil.getUniqueSubscriptionDisplayName(subInfo, mContext);
} else {
summary = mContext.getString(
R.string.mobile_data_temp_using,
SubscriptionUtil.getUniqueSubscriptionDisplayName(subInfo, mContext));
}
mPreference.setSummary(summary);
}
}

View File

@@ -220,7 +220,11 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
return;
}
SubscriptionInfo subInfo = mSubscriptionManager.getDefaultDataSubscriptionInfo();
// Prefer using the currently active sub
SubscriptionInfo subInfoCandidate = mSubscriptionManager.getActiveSubscriptionInfo(
SubscriptionManager.getActiveDataSubscriptionId());
SubscriptionInfo subInfo = mSubscriptionManager.isSubscriptionVisible(subInfoCandidate)
? subInfoCandidate : mSubscriptionManager.getDefaultDataSubscriptionInfo();
if (subInfo == null) {
mPreferenceGroup.removeAll();
return;
@@ -255,9 +259,17 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
mUpdateListener.onChildrenUpdated();
}
/**@return {@code true} if subId is the default data sub. **/
private boolean isDds(int subId) {
return mSubscriptionManager.getDefaultDataSubscriptionInfo() != null
&& mSubscriptionManager.getDefaultDataSubscriptionInfo().getSubscriptionId()
== subId;
}
private CharSequence getMobilePreferenceSummary(int subId) {
final TelephonyManager tmForSubId = mTelephonyManager.createForSubscriptionId(subId);
if (!tmForSubId.isDataEnabled()) {
boolean isDds = isDds(subId);
if (!tmForSubId.isDataEnabled() && isDds) {
return mContext.getString(R.string.mobile_data_off_summary);
}
final ServiceState serviceState = tmForSubId.getServiceState();
@@ -275,10 +287,12 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
mContext, mConfig, mTelephonyDisplayInfo, subId, isCarrierNetworkActive);
if (mSubsPrefCtrlInjector.isActiveCellularNetwork(mContext) || isCarrierNetworkActive) {
if (result.isEmpty()) {
result = mContext.getString(R.string.mobile_data_connection_active);
result = mContext.getString(isDds ? R.string.mobile_data_connection_active
: R.string.mobile_data_temp_connection_active);
} else {
result = mContext.getString(R.string.preference_summary_default_combination,
mContext.getString(R.string.mobile_data_connection_active), result);
mContext.getString(isDds ? R.string.mobile_data_connection_active
: R.string.mobile_data_temp_connection_active), result);
}
} else if (!isDataInService) {
result = mContext.getString(R.string.mobile_data_no_connection);
@@ -316,9 +330,12 @@ public class SubscriptionsPreferenceController extends AbstractPreferenceControl
final boolean isVoiceInService = (serviceState == null)
? false
: (serviceState.getState() == ServiceState.STATE_IN_SERVICE);
final boolean isDataEnabled = tmForSubId.isDataEnabled()
// non-Dds but auto data switch feature is enabled
|| (!isDds(subId) && tmForSubId.isMobileDataPolicyEnabled(
TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH));
if (isDataInService || isVoiceInService || isCarrierNetworkActive) {
icon = mSubsPrefCtrlInjector.getIcon(mContext, level, numLevels,
!tmForSubId.isDataEnabled());
icon = mSubsPrefCtrlInjector.getIcon(mContext, level, numLevels, !isDataEnabled);
}
final boolean isActiveCellularNetwork =

View File

@@ -11,7 +11,7 @@
* 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
* limitations under the License.
*/
package com.android.settings.network.telephony;
@@ -36,7 +36,17 @@ import com.android.settings.datausage.DataUsageUtils;
import com.android.settings.network.MobileDataContentObserver;
import com.android.settings.network.SubscriptionsChangeListener;
public class DataDuringCallsPreferenceController extends TelephonyTogglePreferenceController
/**
* Controls whether switch mobile data to the non-default SIM if the non-default SIM has better
* availability.
*
* This is used for temporarily allowing data on the non-default data SIM when on-default SIM
* has better availability on DSDS devices, where better availability means strong
* signal/connectivity.
* If this feature is enabled, data will be temporarily enabled on the non-default data SIM,
* including during any voice calls.
*/
public class AutoDataSwitchPreferenceController extends TelephonyTogglePreferenceController
implements LifecycleObserver,
SubscriptionsChangeListener.SubscriptionsChangeListenerClient {
@@ -46,7 +56,7 @@ public class DataDuringCallsPreferenceController extends TelephonyTogglePreferen
private MobileDataContentObserver mMobileDataContentObserver;
private PreferenceScreen mScreen;
public DataDuringCallsPreferenceController(Context context,
public AutoDataSwitchPreferenceController(Context context,
String preferenceKey) {
super(context, preferenceKey);
}
@@ -90,13 +100,13 @@ public class DataDuringCallsPreferenceController extends TelephonyTogglePreferen
@Override
public boolean isChecked() {
return mManager.isMobileDataPolicyEnabled(
TelephonyManager.MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL);
TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH);
}
@Override
public boolean setChecked(boolean isChecked) {
mManager.setMobileDataPolicyEnabled(
TelephonyManager.MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL,
TelephonyManager.MOBILE_DATA_POLICY_AUTO_DATA_SWITCH,
isChecked);
return true;
}

View File

@@ -180,7 +180,7 @@ public class MobileNetworkSettings extends AbstractMobileNetworkSettings {
use(CarrierSettingsVersionPreferenceController.class).init(mSubId);
use(BillingCyclePreferenceController.class).init(mSubId);
use(MmsMessagePreferenceController.class).init(mSubId);
use(DataDuringCallsPreferenceController.class).init(mSubId);
use(AutoDataSwitchPreferenceController.class).init(mSubId);
use(DisabledSubscriptionController.class).init(mSubId);
use(DeleteSimProfilePreferenceController.class).init(mSubId, this,
REQUEST_CODE_DELETE_SUBSCRIPTION);

View File

@@ -2,7 +2,7 @@ com.android.settings.accessibility.AccessibilitySlicePreferenceController
com.android.settings.core.TogglePreferenceControllerTest$FakeToggle
com.android.settings.biometrics.face.FaceSettingsAttentionPreferenceController
com.android.settings.network.telephony.MmsMessagePreferenceController
com.android.settings.network.telephony.DataDuringCallsPreferenceController
com.android.settings.network.telephony.AutoDataSwitchPreferenceController
com.android.settings.network.telephony.Enhanced4gBasePreferenceController
com.android.settings.testutils.FakeToggleController
com.android.settings.testutils.FakeSliderController

View File

@@ -11,7 +11,7 @@
* 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
* limitations under the License.
*/
package com.android.settings.network.telephony;
@@ -47,7 +47,7 @@ import org.robolectric.shadows.ShadowSubscriptionManager;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowSubscriptionManager.class)
public class DataDuringCallsPreferenceControllerTest {
public class AutoDataSwitchPreferenceControllerTest {
private static final String PREF_KEY = "pref_key";
private static final int SUB_ID_1 = 111;
private static final int SUB_ID_2 = 222;
@@ -59,7 +59,7 @@ public class DataDuringCallsPreferenceControllerTest {
private Context mContext;
private SwitchPreference mSwitchPreference;
private DataDuringCallsPreferenceController mController;
private AutoDataSwitchPreferenceController mController;
@Before
public void setUp() {
@@ -69,9 +69,11 @@ public class DataDuringCallsPreferenceControllerTest {
when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager);
mSwitchPreference = new SwitchPreference(mContext);
when(mPreferenceScreen.findPreference(PREF_KEY)).thenReturn(mSwitchPreference);
mController = new DataDuringCallsPreferenceController(mContext, PREF_KEY) {
mController = new AutoDataSwitchPreferenceController(mContext, PREF_KEY) {
@Override
protected boolean hasMobileData() { return true; }
protected boolean hasMobileData() {
return true;
}
};
mController.init(SUB_ID_1);
}
@@ -79,8 +81,8 @@ public class DataDuringCallsPreferenceControllerTest {
@Test
public void getAvailabilityStatus_noInit_notAvailable() {
ShadowSubscriptionManager.setDefaultDataSubscriptionId(SUB_ID_1);
DataDuringCallsPreferenceController controller =
new DataDuringCallsPreferenceController(mContext, PREF_KEY);
AutoDataSwitchPreferenceController controller =
new AutoDataSwitchPreferenceController(mContext, PREF_KEY);
// note that we purposely don't call init first on the controller
assertThat(controller.getAvailabilityStatus(INVALID_SUBSCRIPTION_ID)).isEqualTo(

View File

@@ -22,6 +22,7 @@ import static com.android.settings.network.InternetUpdater.INTERNET_WIFI;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
@@ -37,6 +38,7 @@ import android.net.NetworkScoreManager;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.Looper;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import androidx.lifecycle.Lifecycle;
@@ -46,6 +48,8 @@ import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.testutils.ResourcesUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -145,7 +149,31 @@ public class InternetPreferenceControllerTest {
final SubscriptionManager subscriptionManager = mock(SubscriptionManager.class);
when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(subscriptionManager);
when(subscriptionManager.getDefaultDataSubscriptionInfo()).thenReturn(null);
when(subscriptionManager.getActiveSubscriptionInfo(anyInt())).thenReturn(null);
mController.updateCellularSummary();
}
@Test
public void updateCellularSummary_getActiveSubscriptionInfo_cbrs() {
mController.displayPreference(mScreen);
final SubscriptionManager subscriptionManager = mock(SubscriptionManager.class);
final SubscriptionInfo defaultSubInfo = mock(SubscriptionInfo.class);
final SubscriptionInfo activeSubInfo = mock(SubscriptionInfo.class);
final String expectedSummary =
ResourcesUtils.getResourcesString(mContext, "mobile_data_temp_using", "");
when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(subscriptionManager);
when(subscriptionManager.getDefaultDataSubscriptionInfo()).thenReturn(defaultSubInfo);
when(subscriptionManager.getActiveSubscriptionInfo(anyInt())).thenReturn(activeSubInfo);
when(subscriptionManager.isSubscriptionVisible(activeSubInfo)).thenReturn(false);
mController.updateCellularSummary();
assertThat(mPreference.getSummary()).isEqualTo("");
when(subscriptionManager.isSubscriptionVisible(activeSubInfo)).thenReturn(true);
mController.updateCellularSummary();
assertThat(mPreference.getSummary()).isEqualTo(expectedSummary);
}
}