Merge "Add mms preference and controller" into qt-dev

This commit is contained in:
Lei Yu
2019-04-22 17:55:34 +00:00
committed by Android (Google) Code Review
8 changed files with 318 additions and 37 deletions

View File

@@ -6994,6 +6994,10 @@
<string name="preferred_network_type_title">Preferred network type</string>
<!-- Preferred network type summary. [CHAR LIMIT=100] -->
<string name="preferred_network_type_summary">LTE (recommended)</string>
<!-- Title of multimedia messaging service settings. [CHAR LIMIT=50] -->
<string name="mms_message_title">MMS messages</string>
<!-- Summary of multimedia messaging service settings. [CHAR LIMIT=100] -->
<string name="mms_message_summary">Send &amp; receive when mobile data is off</string>
<!-- Work SIM title. [CHAR LIMIT=50] -->
<string name="work_sim_title">Work SIM</string>

View File

@@ -73,6 +73,12 @@
android:title="@string/billing_cycle"
settings:controller="com.android.settings.datausage.BillingCyclePreferenceController" />
<SwitchPreference
android:key="mms_message"
android:title="@string/mms_message_title"
android:summary="@string/mms_message_summary"
settings:controller="com.android.settings.network.telephony.MmsMessagePreferenceController" />
<SwitchPreference
android:key="enhanced_4g_lte"
android:title="@string/enhanced_4g_lte_mode_title"

View File

@@ -0,0 +1,72 @@
/*
* 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;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
import android.provider.Settings;
import android.telephony.TelephonyManager;
/**
* {@link ContentObserver} to listen to update of mobile data change
*/
public class MobileDataContentObserver extends ContentObserver {
private OnMobileDataChangedListener mListener;
public MobileDataContentObserver(Handler handler) {
super(handler);
}
public static Uri getObservableUri(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);
}
return uri;
}
public void setOnMobileDataChangedListener(OnMobileDataChangedListener lsn) {
mListener = lsn;
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
if (mListener != null) {
mListener.onMobileDataChanged();
}
}
public void register(Context context, int subId) {
final Uri uri = getObservableUri(subId);
context.getContentResolver().registerContentObserver(uri, false, this);
}
public void unRegister(Context context) {
context.getContentResolver().unregisterContentObserver(this);
}
/**
* Listener for update of mobile data(ON vs OFF)
*/
public interface OnMobileDataChangedListener {
void onMobileDataChanged();
}
}

View File

@@ -0,0 +1,106 @@
/*
* 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 android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
import android.util.Log;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import com.android.settings.network.MobileDataContentObserver;
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 MmsMessagePreferenceController extends TelephonyTogglePreferenceController implements
LifecycleObserver, OnStart, OnStop {
private TelephonyManager mTelephonyManager;
private SubscriptionManager mSubscriptionManager;
private MobileDataContentObserver mMobileDataContentObserver;
private SwitchPreference mPreference;
public MmsMessagePreferenceController(Context context, String key) {
super(context, key);
mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
mMobileDataContentObserver = new MobileDataContentObserver(
new Handler(Looper.getMainLooper()));
mMobileDataContentObserver.setOnMobileDataChangedListener(()->updateState(mPreference));
}
@Override
public int getAvailabilityStatus(int subId) {
final TelephonyManager telephonyManager = TelephonyManager
.from(mContext).createForSubscriptionId(subId);
return (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
&& !telephonyManager.isDataEnabled()
&& telephonyManager.isApnMetered(ApnSetting.TYPE_MMS))
? AVAILABLE
: CONDITIONALLY_UNAVAILABLE;
}
@Override
public void onStart() {
if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
mMobileDataContentObserver.register(mContext, mSubId);
}
}
@Override
public void onStop() {
if (mSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
mMobileDataContentObserver.unRegister(mContext);
}
}
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
}
@Override
public void updateState(Preference preference) {
super.updateState(preference);
preference.setVisible(isAvailable());
((SwitchPreference) preference).setChecked(isChecked());
}
public void init(int subId) {
mSubId = subId;
mTelephonyManager = TelephonyManager.from(mContext).createForSubscriptionId(mSubId);
}
@Override
public boolean setChecked(boolean isChecked) {
return mSubscriptionManager.setAlwaysAllowMmsData(mSubId, isChecked);
}
@Override
public boolean isChecked() {
return mTelephonyManager.isDataEnabledForApn(ApnSetting.TYPE_MMS);
}
}

View File

@@ -27,6 +27,7 @@ import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import com.android.settings.network.MobileDataContentObserver;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
@@ -48,7 +49,7 @@ public class MobileDataPreferenceController extends TelephonyTogglePreferenceCon
private SwitchPreference mPreference;
private TelephonyManager mTelephonyManager;
private SubscriptionManager mSubscriptionManager;
private DataContentObserver mDataContentObserver;
private MobileDataContentObserver mDataContentObserver;
private FragmentManager mFragmentManager;
@VisibleForTesting
int mDialogType;
@@ -58,7 +59,8 @@ public class MobileDataPreferenceController extends TelephonyTogglePreferenceCon
public MobileDataPreferenceController(Context context, String key) {
super(context, key);
mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
mDataContentObserver = new DataContentObserver(new Handler(Looper.getMainLooper()));
mDataContentObserver = new MobileDataContentObserver(new Handler(Looper.getMainLooper()));
mDataContentObserver.setOnMobileDataChangedListener(()-> updateState(mPreference));
}
@Override
@@ -129,14 +131,6 @@ public class MobileDataPreferenceController extends TelephonyTogglePreferenceCon
return info != null && info.isOpportunistic();
}
public static Uri getObservableUri(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);
}
return uri;
}
public void init(FragmentManager fragmentManager, int subId) {
mFragmentManager = fragmentManager;
mSubId = subId;
@@ -170,30 +164,4 @@ public class MobileDataPreferenceController extends TelephonyTogglePreferenceCon
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) {
final Uri uri = getObservableUri(subId);
context.getContentResolver().registerContentObserver(uri, false, this);
}
public void unRegister(Context context) {
context.getContentResolver().unregisterContentObserver(this);
}
}
}

View File

@@ -39,6 +39,7 @@ import androidx.slice.builders.SliceAction;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.network.AirplaneModePreferenceController;
import com.android.settings.network.MobileDataContentObserver;
import com.android.settings.slices.CustomSliceRegistry;
import com.android.settings.slices.CustomSliceable;
import com.android.settings.slices.SliceBackgroundWorker;
@@ -267,7 +268,7 @@ public class MobileDataSlice implements CustomSliceable {
}
public void register(Context context, int subId) {
final Uri uri = MobileDataPreferenceController.getObservableUri(subId);
final Uri uri = MobileDataContentObserver.getObservableUri(subId);
context.getContentResolver().registerContentObserver(uri, false, this);
}

View File

@@ -136,6 +136,7 @@ public class MobileNetworkSettings extends RestrictedDashboardFragment {
use(MobileNetworkSwitchController.class).init(getLifecycle(), mSubId);
use(CarrierSettingsVersionPreferenceController.class).init(mSubId);
use(BillingCyclePreferenceController.class).init(mSubId);
use(MmsMessagePreferenceController.class).init(mSubId);
}
use(MobileDataPreferenceController.class).init(getFragmentManager(), mSubId);
use(RoamingPreferenceController.class).init(getFragmentManager(), mSubId);

View File

@@ -0,0 +1,123 @@
/*
* 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.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
import androidx.preference.SwitchPreference;
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 org.robolectric.shadows.ShadowSubscriptionManager;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = ShadowSubscriptionManager.class)
public class MmsMessagePreferenceControllerTest {
private static final int SUB_ID = 2;
@Mock
private TelephonyManager mTelephonyManager;
@Mock
private SubscriptionManager mSubscriptionManager;
private MmsMessagePreferenceController mController;
private SwitchPreference mPreference;
private Context mContext;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application);
when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager);
when(mTelephonyManager.createForSubscriptionId(SUB_ID)).thenReturn(mTelephonyManager);
mPreference = new SwitchPreference(mContext);
mController = new MmsMessagePreferenceController(mContext, "mms_message");
ShadowSubscriptionManager.setDefaultDataSubscriptionId(SUB_ID);
mController.init(SUB_ID);
mPreference.setKey(mController.getPreferenceKey());
}
@Test
public void getAvailabilityStatus_invalidSubscription_returnUnavailable() {
mController.init(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
public void getAvailabilityStatus_mobileDataOn_returnUnavailable() {
when(mTelephonyManager.isDataEnabled()).thenReturn(true);
assertThat(mController.getAvailabilityStatus(SUB_ID)).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
public void getAvailabilityStatus_meteredOff_returnUnavailable() {
when(mTelephonyManager.isApnMetered(ApnSetting.TYPE_MMS)).thenReturn(false);
assertThat(mController.getAvailabilityStatus(SUB_ID)).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
public void getAvailabilityStatus_mobileDataOffWithValidSubId_returnAvailable() {
mController.init(SUB_ID);
when(mTelephonyManager.isDataEnabled()).thenReturn(false);
when(mTelephonyManager.isApnMetered(ApnSetting.TYPE_MMS)).thenReturn(true);
assertThat(mController.getAvailabilityStatus(SUB_ID)).isEqualTo(AVAILABLE);
}
@Test
public void isChecked_returnDataFromTelephonyManager() {
when(mTelephonyManager.isDataEnabledForApn(ApnSetting.TYPE_MMS)).thenReturn(false);
assertThat(mController.isChecked()).isFalse();
when(mTelephonyManager.isDataEnabledForApn(ApnSetting.TYPE_MMS)).thenReturn(true);
assertThat(mController.isChecked()).isTrue();
}
@Test
public void setChecked_setDataIntoSubscriptionManager() {
mController.setChecked(true);
verify(mSubscriptionManager).setAlwaysAllowMmsData(SUB_ID, true);
mController.setChecked(false);
verify(mSubscriptionManager).setAlwaysAllowMmsData(SUB_ID, false);
}
}