diff --git a/AndroidManifest.xml b/AndroidManifest.xml index bc832efcd87..1ffdba16ac2 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -111,13 +111,9 @@ - - - - - @@ -126,6 +122,12 @@ android:label="@string/settings_label_launcher" android:theme="@style/Theme.Settings.Home" android:launchMode="singleTask"> + + + + + - + android:exported="false" /> - - + android:exported="true" /> diff --git a/res/layout/fingerprint_rename_dialog.xml b/res/layout/fingerprint_rename_dialog.xml index 99cfa718d0e..2da84ca9876 100644 --- a/res/layout/fingerprint_rename_dialog.xml +++ b/res/layout/fingerprint_rename_dialog.xml @@ -35,7 +35,7 @@ android:clipChildren="false" android:clipToPadding="false" /> - See more See less + + + + %1$d device connected + %1$d devices connected + + + No connected devices diff --git a/res/xml/tts_settings.xml b/res/xml/tts_settings.xml index 4a2415477ee..e76cdb78046 100644 --- a/res/xml/tts_settings.xml +++ b/res/xml/tts_settings.xml @@ -20,21 +20,17 @@ android:key="tts_settings_screen" android:title="@string/tts_settings_title"> - + - - - - - + diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java index 8881fc2f56c..8ed368ca490 100644 --- a/src/com/android/settings/SettingsActivity.java +++ b/src/com/android/settings/SettingsActivity.java @@ -16,8 +16,6 @@ package com.android.settings; -import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO; - import android.app.ActionBar; import android.app.ActivityManager; import android.content.BroadcastReceiver; @@ -248,10 +246,8 @@ public class SettingsActivity extends SettingsBaseActivity // Getting Intent properties can only be done after the super.onCreate(...) final String initialFragmentName = intent.getStringExtra(EXTRA_SHOW_FRAGMENT); - final ComponentName cn = intent.getComponent(); - final String className = cn.getClassName(); - - mIsShowingDashboard = className.equals(Settings.class.getName()); + mIsShowingDashboard = TextUtils.equals( + SettingsActivity.class.getName(), intent.getComponent().getClassName()); // This is a "Sub Settings" when: // - this is a real SubSettings diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java index c3bd043c78d..2e67ec3e48f 100644 --- a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java +++ b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java @@ -55,6 +55,7 @@ import com.android.settings.core.instrumentation.InstrumentedDialogFragment; import com.android.settings.password.ChooseLockGeneric; import com.android.settings.password.ChooseLockSettingsHelper; import com.android.settings.utils.AnnotationSpan; +import com.android.settings.widget.ImeAwareEditText; import com.android.settingslib.HelpUtils; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; @@ -708,11 +709,7 @@ public class FingerprintSettings extends SubSettings { public static class RenameDialog extends InstrumentedDialogFragment { private Fingerprint mFp; - private EditText mDialogTextField; - private String mFingerName; - private Boolean mTextHadFocus; - private int mTextSelectionStart; - private int mTextSelectionEnd; + private ImeAwareEditText mDialogTextField; private AlertDialog mAlertDialog; private boolean mDeleteInProgress; @@ -723,11 +720,17 @@ public class FingerprintSettings extends SubSettings { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { mFp = getArguments().getParcelable("fingerprint"); + final String fingerName; + final int textSelectionStart; + final int textSelectionEnd; if (savedInstanceState != null) { - mFingerName = savedInstanceState.getString("fingerName"); - mTextHadFocus = savedInstanceState.getBoolean("textHadFocus"); - mTextSelectionStart = savedInstanceState.getInt("startSelection"); - mTextSelectionEnd = savedInstanceState.getInt("endSelection"); + fingerName = savedInstanceState.getString("fingerName"); + textSelectionStart = savedInstanceState.getInt("startSelection", -1); + textSelectionEnd = savedInstanceState.getInt("endSelection", -1); + } else { + fingerName = null; + textSelectionStart = -1; + textSelectionEnd = -1; } mAlertDialog = new AlertDialog.Builder(getActivity()) .setView(R.layout.fingerprint_rename_dialog) @@ -756,26 +759,21 @@ public class FingerprintSettings extends SubSettings { mAlertDialog.setOnShowListener(new DialogInterface.OnShowListener() { @Override public void onShow(DialogInterface dialog) { - mDialogTextField = (EditText) mAlertDialog.findViewById( - R.id.fingerprint_rename_field); - CharSequence name = mFingerName == null ? mFp.getName() : mFingerName; + mDialogTextField = mAlertDialog.findViewById(R.id.fingerprint_rename_field); + CharSequence name = fingerName == null ? mFp.getName() : fingerName; mDialogTextField.setText(name); - if (mTextHadFocus == null) { - mDialogTextField.selectAll(); + if (textSelectionStart != -1 && textSelectionEnd != -1) { + mDialogTextField.setSelection(textSelectionStart, textSelectionEnd); } else { - mDialogTextField.setSelection(mTextSelectionStart, mTextSelectionEnd); + mDialogTextField.selectAll(); } if (mDeleteInProgress) { mAlertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setEnabled(false); } mDialogTextField.requestFocus(); + mDialogTextField.scheduleShowSoftInput(); } }); - if (mTextHadFocus == null || mTextHadFocus) { - // Request the IME - mAlertDialog.getWindow().setSoftInputMode( - WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); - } return mAlertDialog; } @@ -791,7 +789,6 @@ public class FingerprintSettings extends SubSettings { super.onSaveInstanceState(outState); if (mDialogTextField != null) { outState.putString("fingerName", mDialogTextField.getText().toString()); - outState.putBoolean("textHadFocus", mDialogTextField.hasFocus()); outState.putInt("startSelection", mDialogTextField.getSelectionStart()); outState.putInt("endSelection", mDialogTextField.getSelectionEnd()); } diff --git a/src/com/android/settings/dashboard/DashboardFragment.java b/src/com/android/settings/dashboard/DashboardFragment.java index be59ca11c70..0cda9eef411 100644 --- a/src/com/android/settings/dashboard/DashboardFragment.java +++ b/src/com/android/settings/dashboard/DashboardFragment.java @@ -321,6 +321,12 @@ public abstract class DashboardFragment extends SettingsPreferenceFragment displayResourceTiles(); refreshDashboardTiles(TAG); + + final Activity activity = getActivity(); + if (activity != null) { + Log.d(TAG, "All preferences added, reporting fully drawn"); + activity.reportFullyDrawn(); + } } /** diff --git a/src/com/android/settings/homepage/SettingsHomepageActivity.java b/src/com/android/settings/homepage/SettingsHomepageActivity.java index b3d1aa43ff5..c10543dab6d 100644 --- a/src/com/android/settings/homepage/SettingsHomepageActivity.java +++ b/src/com/android/settings/homepage/SettingsHomepageActivity.java @@ -16,7 +16,6 @@ package com.android.settings.homepage; -import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.FeatureFlagUtils; @@ -27,6 +26,7 @@ import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentTransaction; import com.android.settings.R; +import com.android.settings.SettingsActivity; import com.android.settings.core.FeatureFlags; import com.android.settings.core.SettingsBaseActivity; import com.android.settings.homepage.contextualcards.ContextualCardsFragment; @@ -38,9 +38,8 @@ public class SettingsHomepageActivity extends SettingsBaseActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - if (!isDynamicHomepageEnabled(this)) { - final Intent settings = new Intent(); - settings.setAction("android.settings.SETTINGS"); + if (!FeatureFlagUtils.isEnabled(this, FeatureFlags.DYNAMIC_HOMEPAGE)) { + final Intent settings = new Intent(this, SettingsActivity.class); startActivity(settings); finish(); return; @@ -56,10 +55,6 @@ public class SettingsHomepageActivity extends SettingsBaseActivity { showFragment(new TopLevelSettings(), R.id.main_content); } - public static boolean isDynamicHomepageEnabled(Context context) { - return FeatureFlagUtils.isEnabled(context, FeatureFlags.DYNAMIC_HOMEPAGE); - } - private void showFragment(Fragment fragment, int id) { final FragmentManager fragmentManager = getSupportFragmentManager(); final FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); diff --git a/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java b/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java index 572c36dc15b..36c0a118023 100644 --- a/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java +++ b/src/com/android/settings/homepage/contextualcards/SettingsContextualCardProvider.java @@ -25,6 +25,7 @@ import com.android.settings.homepage.contextualcards.deviceinfo.DataUsageSlice; import com.android.settings.homepage.contextualcards.deviceinfo.DeviceInfoSlice; import com.android.settings.homepage.contextualcards.deviceinfo.EmergencyInfoSlice; import com.android.settings.homepage.contextualcards.deviceinfo.StorageSlice; +import com.android.settings.homepage.contextualcards.slices.ConnectedDeviceSlice; import com.android.settings.intelligence.ContextualCardProto.ContextualCard; import com.android.settings.intelligence.ContextualCardProto.ContextualCardList; import com.android.settings.wifi.WifiSlice; @@ -69,6 +70,11 @@ public class SettingsContextualCardProvider extends ContextualCardProvider { .setSliceUri(BatterySlice.BATTERY_CARD_URI.toSafeString()) .setCardName(BatterySlice.PATH_BATTERY_INFO) .build(); + final ContextualCard connectedDeviceCard = + ContextualCard.newBuilder() + .setSliceUri(ConnectedDeviceSlice.CONNECTED_DEVICE_URI.toString()) + .setCardName(ConnectedDeviceSlice.PATH_CONNECTED_DEVICE) + .build(); final ContextualCardList cards = ContextualCardList.newBuilder() .addCard(wifiCard) .addCard(dataUsageCard) @@ -76,6 +82,7 @@ public class SettingsContextualCardProvider extends ContextualCardProvider { .addCard(storageInfoCard) .addCard(emergencyInfoCard) .addCard(batteryInfoCard) + .addCard(connectedDeviceCard) .build(); return cards; diff --git a/src/com/android/settings/homepage/contextualcards/slices/ConnectedDeviceSlice.java b/src/com/android/settings/homepage/contextualcards/slices/ConnectedDeviceSlice.java new file mode 100644 index 00000000000..83a6af5d972 --- /dev/null +++ b/src/com/android/settings/homepage/contextualcards/slices/ConnectedDeviceSlice.java @@ -0,0 +1,286 @@ +/* + * 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.homepage.contextualcards.slices; + +import android.app.PendingIntent; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.Bitmap.Config; +import android.graphics.Canvas; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Bundle; +import android.util.ArrayMap; +import android.util.Log; +import android.util.Pair; + +import androidx.core.graphics.drawable.IconCompat; +import androidx.slice.Slice; +import androidx.slice.builders.ListBuilder; +import androidx.slice.builders.SliceAction; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.logging.nano.MetricsProto; +import com.android.settings.R; +import com.android.settings.SubSettings; +import com.android.settings.Utils; +import com.android.settings.bluetooth.BluetoothDeviceDetailsFragment; +import com.android.settings.connecteddevice.ConnectedDeviceDashboardFragment; +import com.android.settings.core.SubSettingLauncher; +import com.android.settings.slices.CustomSliceable; +import com.android.settings.slices.SettingsSliceProvider; +import com.android.settings.slices.SliceBuilderUtils; +import com.android.settingslib.bluetooth.BluetoothUtils; +import com.android.settingslib.bluetooth.CachedBluetoothDevice; +import com.android.settingslib.bluetooth.LocalBluetoothManager; +import com.android.settingslib.core.instrumentation.Instrumentable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; + +/** + * TODO(b/114807655): Contextual Home Page - Connected Device + * + * Show connected device info if one is currently connected. UI for connected device should + * match Connected Devices > Currently Connected Devices + * + * This Slice will show multiple currently connected devices, which includes: + * 1) Bluetooth. + * 2) Docks. + * ... + * TODO Other device types are under checking to support, will update later. + */ +public class ConnectedDeviceSlice implements CustomSliceable { + + /** + * The path denotes the unique name of Connected device Slice. + */ + public static final String PATH_CONNECTED_DEVICE = "connected_device"; + + /** + * Backing Uri for Connected device Slice. + */ + public static final Uri CONNECTED_DEVICE_URI = new Uri.Builder() + .scheme(ContentResolver.SCHEME_CONTENT) + .authority(SettingsSliceProvider.SLICE_AUTHORITY) + .appendPath(PATH_CONNECTED_DEVICE) + .build(); + + /** + * To sort the Bluetooth devices by {@link CachedBluetoothDevice}. + * Refer compareTo method from {@link com.android.settings.bluetooth.BluetoothDevicePreference}. + */ + private static final Comparator COMPARATOR + = Comparator.naturalOrder(); + + private static final int DEFAULT_EXPANDED_ROW_COUNT = 4; + + private static final String TAG = "ConnectedDeviceSlice"; + + private final Context mContext; + + public ConnectedDeviceSlice(Context context) { + mContext = context; + } + + private static Bitmap getBitmapFromVectorDrawable(Drawable VectorDrawable) { + final Bitmap bitmap = Bitmap.createBitmap(VectorDrawable.getIntrinsicWidth(), + VectorDrawable.getIntrinsicHeight(), Config.ARGB_8888); + final Canvas canvas = new Canvas(bitmap); + + VectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); + VectorDrawable.draw(canvas); + + return bitmap; + } + + @Override + public Uri getUri() { + return CONNECTED_DEVICE_URI; + } + + /** + * Return a Connected Device Slice bound to {@link #CONNECTED_DEVICE_URI}. + */ + @Override + public Slice getSlice() { + final IconCompat icon = IconCompat.createWithResource(mContext, + R.drawable.ic_homepage_connected_device); + final CharSequence title = mContext.getText(R.string.connected_devices_dashboard_title); + final CharSequence titleNoConnectedDevices = mContext.getText( + R.string.no_connected_devices); + final PendingIntent primaryActionIntent = PendingIntent.getActivity(mContext, 0, + getIntent(), 0); + final SliceAction primarySliceAction = new SliceAction(primaryActionIntent, icon, + title); + final ListBuilder listBuilder = + new ListBuilder(mContext, CONNECTED_DEVICE_URI, ListBuilder.INFINITY) + .setAccentColor(Utils.getColorAccentDefaultColor(mContext)); + + // Get row builders by connected devices, e.g. Bluetooth. + // TODO Add other type connected devices, e.g. Docks. + final List rows = getBluetoothRowBuilder(primarySliceAction); + + // Return a header with IsError flag, if no connected devices. + if (rows.isEmpty()) { + return listBuilder.setHeader(new ListBuilder.HeaderBuilder() + .setTitle(titleNoConnectedDevices) + .setPrimaryAction(primarySliceAction)) + .setIsError(true) + .build(); + } + + // According the number of connected devices to set sub title of header. + listBuilder.setHeader(new ListBuilder.HeaderBuilder() + .setTitle(title) + .setSubtitle(getSubTitle(rows.size())) + .setPrimaryAction(primarySliceAction)); + + // Add rows. + for (ListBuilder.RowBuilder rowBuilder : rows) { + listBuilder.addRow(rowBuilder); + } + + // Only show "see more" button when the number of data row is more than or equal to 4. + // TODO(b/118465996): SHOW MORE button won't work properly when having two data rows + if (rows.size() >= DEFAULT_EXPANDED_ROW_COUNT) { + listBuilder.setSeeMoreAction(primaryActionIntent); + } + + return listBuilder.build(); + } + + @Override + public Intent getIntent() { + final String screenTitle = mContext.getText(R.string.connected_devices_dashboard_title) + .toString(); + final Uri contentUri = new Uri.Builder().appendPath(PATH_CONNECTED_DEVICE).build(); + + return SliceBuilderUtils.buildSearchResultPageIntent(mContext, + ConnectedDeviceDashboardFragment.class.getName(), PATH_CONNECTED_DEVICE, + screenTitle, + MetricsProto.MetricsEvent.SLICE) + .setClassName(mContext.getPackageName(), SubSettings.class.getName()) + .setData(contentUri); + } + + @Override + public void onNotifyChange(Intent intent) { + } + + @VisibleForTesting + List getBluetoothConnectedDevices() { + final List connectedBluetoothList = new ArrayList<>(); + + // If Bluetooth is disable, skip to get the bluetooth devices. + if (!BluetoothAdapter.getDefaultAdapter().isEnabled()) { + Log.d(TAG, "Cannot get Bluetooth connected devices, Bluetooth is disabled."); + return connectedBluetoothList; + } + + // Get the Bluetooth devices from LocalBluetoothManager. + final LocalBluetoothManager bluetoothManager = + com.android.settings.bluetooth.Utils.getLocalBtManager(mContext); + if (bluetoothManager == null) { + Log.d(TAG, "Cannot get Bluetooth connected devices, Bluetooth is not supported."); + return connectedBluetoothList; + } + final Collection cachedDevices = + bluetoothManager.getCachedDeviceManager().getCachedDevicesCopy(); + + // Get all connected Bluetooth devices and use Map to filter duplicated Bluetooth. + final Map connectedBluetoothMap = new ArrayMap<>(); + for (CachedBluetoothDevice device : cachedDevices) { + if (device.isConnected() && !connectedBluetoothMap.containsKey(device.getDevice())) { + connectedBluetoothMap.put(device.getDevice(), device); + } + } + + // Sort connected Bluetooth devices. + connectedBluetoothList.addAll(connectedBluetoothMap.values()); + Collections.sort(connectedBluetoothList, COMPARATOR); + + return connectedBluetoothList; + } + + @VisibleForTesting + PendingIntent getBluetoothDetailIntent(CachedBluetoothDevice device) { + final Bundle args = new Bundle(); + args.putString(BluetoothDeviceDetailsFragment.KEY_DEVICE_ADDRESS, + device.getDevice().getAddress()); + final SubSettingLauncher subSettingLauncher = new SubSettingLauncher(mContext); + subSettingLauncher.setDestination(BluetoothDeviceDetailsFragment.class.getName()) + .setArguments(args) + .setTitleRes(R.string.device_details_title) + .setSourceMetricsCategory(Instrumentable.METRICS_CATEGORY_UNKNOWN); + + // The requestCode should be unique, use the hashcode of device as request code. + return PendingIntent + .getActivity(mContext, device.hashCode() /* requestCode */, + subSettingLauncher.toIntent(), + 0 /* flags */); + } + + @VisibleForTesting + IconCompat getConnectedDeviceIcon(CachedBluetoothDevice device) { + final Pair pair = BluetoothUtils + .getBtClassDrawableWithDescription(mContext, device); + + if (pair.first != null) { + return IconCompat.createWithBitmap(getBitmapFromVectorDrawable(pair.first)); + } else { + return IconCompat.createWithResource(mContext, R.drawable.ic_homepage_connected_device); + } + } + + private List getBluetoothRowBuilder(SliceAction primarySliceAction) { + final List bluetoothRows = new ArrayList<>(); + + // According Bluetooth connected device to create row builders. + final List bluetoothDevices = getBluetoothConnectedDevices(); + for (CachedBluetoothDevice bluetoothDevice : bluetoothDevices) { + bluetoothRows.add(new ListBuilder.RowBuilder() + .setTitleItem(getConnectedDeviceIcon(bluetoothDevice), ListBuilder.ICON_IMAGE) + .setTitle(bluetoothDevice.getName()) + .setSubtitle(bluetoothDevice.getConnectionSummary()) + .setPrimaryAction(primarySliceAction) + .addEndItem(buildBluetoothDetailDeepLinkAction(bluetoothDevice))); + } + + return bluetoothRows; + } + + private SliceAction buildBluetoothDetailDeepLinkAction(CachedBluetoothDevice bluetoothDevice) { + return new SliceAction( + getBluetoothDetailIntent(bluetoothDevice), + IconCompat.createWithResource(mContext, R.drawable.ic_settings), + bluetoothDevice.getName()); + } + + private CharSequence getSubTitle(int deviceCount) { + return mContext.getResources().getQuantityString(R.plurals.show_connected_devices, + deviceCount, deviceCount); + } +} \ No newline at end of file diff --git a/src/com/android/settings/network/telephony/MobileNetworkUtils.java b/src/com/android/settings/network/telephony/MobileNetworkUtils.java index b43cd3a1a24..f3973829cc2 100644 --- a/src/com/android/settings/network/telephony/MobileNetworkUtils.java +++ b/src/com/android/settings/network/telephony/MobileNetworkUtils.java @@ -30,7 +30,6 @@ import android.provider.Settings; import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; import android.telephony.CarrierConfigManager; -import android.telephony.ServiceState; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; @@ -213,11 +212,6 @@ public class MobileNetworkUtils { || (!esimIgnoredDevice && enabledEsimUiByDefault && inEsimSupportedCountries)); } - public static PersistableBundle getCarrierConfigBySubId(int mSubId) { - //TODO(b/114749736): get carrier config from subId - return new PersistableBundle(); - } - /** * Set whether to enable data for {@code subId}, also whether to disable data for other * subscription @@ -253,9 +247,17 @@ public class MobileNetworkUtils { } final TelephonyManager telephonyManager = TelephonyManager.from(context) .createForSubscriptionId(subId); + final PersistableBundle carrierConfig = context.getSystemService( + CarrierConfigManager.class).getConfigForSubId(subId); + if (telephonyManager.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) { return true; + } else if (carrierConfig != null + && !carrierConfig.getBoolean( + CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL) + && carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL)) { + return true; } if (isWorldMode(context, subId)) { @@ -312,7 +314,10 @@ public class MobileNetworkUtils { if (telephonyManager.getPhoneType() == PhoneConstants.PHONE_TYPE_GSM) { return true; - } else if (carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL)) { + } else if (carrierConfig != null + && !carrierConfig.getBoolean( + CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL) + && carrierConfig.getBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL)) { return true; } diff --git a/src/com/android/settings/network/telephony/cdma/CdmaSystemSelectPreferenceController.java b/src/com/android/settings/network/telephony/cdma/CdmaSystemSelectPreferenceController.java index 4119c64e59c..5f259f85982 100644 --- a/src/com/android/settings/network/telephony/cdma/CdmaSystemSelectPreferenceController.java +++ b/src/com/android/settings/network/telephony/cdma/CdmaSystemSelectPreferenceController.java @@ -23,6 +23,8 @@ import android.telephony.TelephonyManager; import androidx.preference.ListPreference; import androidx.preference.Preference; +import com.android.internal.telephony.Phone; + /** * Preference controller for "System Select" */ @@ -47,6 +49,12 @@ public class CdmaSystemSelectPreferenceController extends CdmaBasePreferenceCont resetCdmaRoamingModeToDefault(); } } + final int settingsNetworkMode = Settings.Global.getInt( + mContext.getContentResolver(), + Settings.Global.PREFERRED_NETWORK_MODE + mSubId, + Phone.PREFERRED_NT_MODE); + listPreference.setEnabled( + settingsNetworkMode != TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA); } @Override diff --git a/src/com/android/settings/slices/CustomSliceManager.java b/src/com/android/settings/slices/CustomSliceManager.java index 4658d2a0b98..556c69817b3 100644 --- a/src/com/android/settings/slices/CustomSliceManager.java +++ b/src/com/android/settings/slices/CustomSliceManager.java @@ -24,6 +24,7 @@ import com.android.settings.homepage.contextualcards.deviceinfo.BatterySlice; import com.android.settings.homepage.contextualcards.deviceinfo.DataUsageSlice; import com.android.settings.homepage.contextualcards.deviceinfo.DeviceInfoSlice; import com.android.settings.homepage.contextualcards.deviceinfo.StorageSlice; +import com.android.settings.homepage.contextualcards.slices.ConnectedDeviceSlice; import com.android.settings.wifi.WifiSlice; import java.util.Map; @@ -103,5 +104,6 @@ public class CustomSliceManager { mUriMap.put(DeviceInfoSlice.DEVICE_INFO_CARD_URI, DeviceInfoSlice.class); mUriMap.put(StorageSlice.STORAGE_CARD_URI, StorageSlice.class); mUriMap.put(BatterySlice.BATTERY_CARD_URI, BatterySlice.class); + mUriMap.put(ConnectedDeviceSlice.CONNECTED_DEVICE_URI, ConnectedDeviceSlice.class); } } diff --git a/src/com/android/settings/tts/TextToSpeechSettings.java b/src/com/android/settings/tts/TextToSpeechSettings.java index 0f10d28572c..866e5a8000b 100644 --- a/src/com/android/settings/tts/TextToSpeechSettings.java +++ b/src/com/android/settings/tts/TextToSpeechSettings.java @@ -147,12 +147,7 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment * screen for the first time (as opposed to when a user changes his choice * of engine). */ - private final TextToSpeech.OnInitListener mInitListener = new TextToSpeech.OnInitListener() { - @Override - public void onInit(int status) { - onInitEngine(status); - } - }; + private final TextToSpeech.OnInitListener mInitListener = this::onInitEngine; @Override public int getMetricsCategory() { @@ -215,6 +210,11 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment @Override public void onResume() { super.onResume(); + // We tend to change the summary contents of our widgets, which at higher text sizes causes + // them to resize, which results in the recyclerview smoothly animating them at inopportune + // times. Disable the animation so widgets snap to their positions rather than sliding + // around while the user is interacting with it. + getListView().getItemAnimator().setMoveDuration(0); if (mTts == null || mCurrentDefaultLocale == null) { return; @@ -323,7 +323,6 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment if (mCurrentEngine != null) { EngineInfo info = mEnginesHelper.getEngineInfo(mCurrentEngine); - Preference mEnginePreference = findPreference(KEY_TTS_ENGINE_PREFERENCE); ((GearPreference) mEnginePreference).setOnGearClickListener(this); mEnginePreference.setSummary(info.label); @@ -365,14 +364,7 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment if (status == TextToSpeech.SUCCESS) { if (DBG) Log.d(TAG, "TTS engine for settings screen initialized."); checkDefaultLocale(); - getActivity() - .runOnUiThread( - new Runnable() { - @Override - public void run() { - mLocalePreference.setEnabled(true); - } - }); + getActivity().runOnUiThread(() -> mLocalePreference.setEnabled(true)); } else { if (DBG) { Log.d(TAG, @@ -516,14 +508,7 @@ public class TextToSpeechSettings extends SettingsPreferenceFragment } // Sort it - Collections.sort( - entryPairs, - new Comparator>() { - @Override - public int compare(Pair lhs, Pair rhs) { - return lhs.first.compareToIgnoreCase(rhs.first); - } - }); + Collections.sort(entryPairs, (lhs, rhs) -> lhs.first.compareToIgnoreCase(rhs.first)); // Get two arrays out of one of pairs mSelectedLocaleIndex = 0; // Will point to the R.string.tts_lang_use_system value diff --git a/tests/robotests/src/com/android/settings/SettingsActivityTest.java b/tests/robotests/src/com/android/settings/SettingsActivityTest.java index 409512eb140..af25f4835df 100644 --- a/tests/robotests/src/com/android/settings/SettingsActivityTest.java +++ b/tests/robotests/src/com/android/settings/SettingsActivityTest.java @@ -71,10 +71,9 @@ public class SettingsActivityTest { @Test public void onCreate_deviceNotProvisioned_shouldDisableSearch() { Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 0); - final Intent intent = new Intent(mContext, Settings.class); - final SettingsActivity activity = - Robolectric.buildActivity(SettingsActivity.class, intent).create( - Bundle.EMPTY).get(); + final SettingsActivity activity = Robolectric.buildActivity(SettingsActivity.class) + .create(Bundle.EMPTY) + .get(); assertThat(activity.findViewById(R.id.search_bar).getVisibility()) .isEqualTo(View.INVISIBLE); @@ -83,10 +82,9 @@ public class SettingsActivityTest { @Test public void onCreate_deviceProvisioned_shouldEnableSearch() { Global.putInt(mContext.getContentResolver(), Global.DEVICE_PROVISIONED, 1); - final Intent intent = new Intent(mContext, Settings.class); - final SettingsActivity activity = - Robolectric.buildActivity(SettingsActivity.class, intent).create( - Bundle.EMPTY).get(); + final SettingsActivity activity = Robolectric.buildActivity(SettingsActivity.class) + .create(Bundle.EMPTY) + .get(); assertThat(activity.findViewById(R.id.search_bar).getVisibility()).isEqualTo(View.VISIBLE); } diff --git a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java new file mode 100644 index 00000000000..f1228194d49 --- /dev/null +++ b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java @@ -0,0 +1,47 @@ +/* + * 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.homepage; + +import static com.google.common.truth.Truth.assertThat; + +import android.util.FeatureFlagUtils; + +import com.android.settings.SettingsActivity; +import com.android.settings.core.FeatureFlags; +import com.android.settings.testutils.SettingsRobolectricTestRunner; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.Robolectric; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.Shadows; +import org.robolectric.shadows.ShadowActivity; + +@RunWith(SettingsRobolectricTestRunner.class) +public class SettingsHomepageActivityTest { + + @Test + public void launch_featureFlagOff_shouldRedirectToSettingsActivity() { + FeatureFlagUtils.setEnabled(RuntimeEnvironment.application, FeatureFlags.DYNAMIC_HOMEPAGE, + false); + + final ShadowActivity shadowActivity = Shadows.shadowOf( + Robolectric.setupActivity(SettingsHomepageActivity.class)); + assertThat(shadowActivity.getNextStartedActivity().getComponent().getClassName()) + .isEqualTo(SettingsActivity.class.getName()); + } +} diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/ConnectedDeviceSliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/ConnectedDeviceSliceTest.java new file mode 100644 index 00000000000..23da1272b5c --- /dev/null +++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/ConnectedDeviceSliceTest.java @@ -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.homepage.contextualcards.slices; + +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; + +import androidx.core.graphics.drawable.IconCompat; +import androidx.slice.Slice; +import androidx.slice.SliceItem; +import androidx.slice.SliceProvider; +import androidx.slice.widget.SliceLiveData; + +import com.android.settings.R; +import com.android.settings.testutils.SettingsRobolectricTestRunner; +import com.android.settings.testutils.SliceTester; +import com.android.settingslib.bluetooth.CachedBluetoothDevice; + +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.ArrayList; +import java.util.List; + +@RunWith(SettingsRobolectricTestRunner.class) +public class ConnectedDeviceSliceTest { + + @Mock + private CachedBluetoothDevice mCachedBluetoothDevice; + + private List mCachedDevices = new ArrayList(); + private Context mContext; + private ConnectedDeviceSlice mConnectedDeviceSlice; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = RuntimeEnvironment.application; + + // Set-up specs for SliceMetadata. + SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS); + + mConnectedDeviceSlice = spy(new ConnectedDeviceSlice(mContext)); + } + + @Test + public void getSlice_hasConnectedDevices_shouldBeCorrectSliceContent() { + final String title = "BluetoothTitle"; + final String summary = "BluetoothSummary"; + final IconCompat icon = IconCompat.createWithResource(mContext, + R.drawable.ic_homepage_connected_device); + final PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, + new Intent("test action"), 0); + doReturn(title).when(mCachedBluetoothDevice).getName(); + doReturn(summary).when(mCachedBluetoothDevice).getConnectionSummary(); + mCachedDevices.add(mCachedBluetoothDevice); + doReturn(mCachedDevices).when(mConnectedDeviceSlice).getBluetoothConnectedDevices(); + doReturn(icon).when(mConnectedDeviceSlice).getConnectedDeviceIcon(any()); + doReturn(pendingIntent).when(mConnectedDeviceSlice).getBluetoothDetailIntent(any()); + final Slice slice = mConnectedDeviceSlice.getSlice(); + + final List sliceItems = slice.getItems(); + SliceTester.assertTitle(sliceItems, title); + } + + @Test + public void getSlice_hasNoConnectedDevices_shouldReturnCorrectHeader() { + final List connectedBluetoothList = new ArrayList<>(); + doReturn(connectedBluetoothList).when(mConnectedDeviceSlice).getBluetoothConnectedDevices(); + final Slice slice = mConnectedDeviceSlice.getSlice(); + + final List sliceItems = slice.getItems(); + SliceTester.assertTitle(sliceItems, mContext.getString(R.string.no_connected_devices)); + } +} \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkUtilsTest.java b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkUtilsTest.java index c03fb71d466..676c9f4f23d 100644 --- a/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkUtilsTest.java +++ b/tests/robotests/src/com/android/settings/network/telephony/MobileNetworkUtilsTest.java @@ -21,18 +21,20 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.nullable; -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 static org.mockito.Mockito.when; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.os.PersistableBundle; import android.provider.Settings; import android.telecom.PhoneAccountHandle; +import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; @@ -75,27 +77,35 @@ public class MobileNetworkUtilsTest { private ComponentName mComponentName; @Mock private ResolveInfo mResolveInfo; + @Mock + private CarrierConfigManager mCarrierConfigManager; private Context mContext; + private PersistableBundle mCarrierConfig; @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(mPackageManager).when(mContext).getPackageManager(); - doReturn(mComponentName).when(mPhoneAccountHandle).getComponentName(); - doReturn(PACKAGE_NAME).when(mComponentName).getPackageName(); + when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager); + when(mContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager); + when(mTelephonyManager.createForSubscriptionId(SUB_ID_1)).thenReturn(mTelephonyManager); + when(mTelephonyManager.createForSubscriptionId(SUB_ID_2)).thenReturn(mTelephonyManager2); + when(mContext.getPackageManager()).thenReturn(mPackageManager); + when(mPhoneAccountHandle.getComponentName()).thenReturn(mComponentName); + when(mComponentName.getPackageName()).thenReturn(PACKAGE_NAME); + when(mContext.getSystemService(CarrierConfigManager.class)).thenReturn( + mCarrierConfigManager); - doReturn(SUB_ID_1).when(mSubscriptionInfo1).getSubscriptionId(); - doReturn(SUB_ID_2).when(mSubscriptionInfo2).getSubscriptionId(); + mCarrierConfig = new PersistableBundle(); + when(mCarrierConfigManager.getConfigForSubId(SUB_ID_1)).thenReturn(mCarrierConfig); - doReturn(Arrays.asList(mSubscriptionInfo1, mSubscriptionInfo2)).when( - mSubscriptionManager).getActiveSubscriptionInfoList(); + when(mSubscriptionInfo1.getSubscriptionId()).thenReturn(SUB_ID_1); + when(mSubscriptionInfo2.getSubscriptionId()).thenReturn(SUB_ID_2); + + when(mSubscriptionManager.getActiveSubscriptionInfoList()).thenReturn( + Arrays.asList(mSubscriptionInfo1, mSubscriptionInfo2)); } @Test @@ -129,8 +139,8 @@ public class MobileNetworkUtilsTest { @Test public void buildConfigureIntent_noActivityHandleIntent_returnNull() { - doReturn(new ArrayList()).when(mPackageManager).queryIntentActivities( - nullable(Intent.class), anyInt()); + when(mPackageManager.queryIntentActivities(nullable(Intent.class), anyInt())) + .thenReturn(new ArrayList<>()); assertThat(MobileNetworkUtils.buildPhoneAccountConfigureIntent(mContext, mPhoneAccountHandle)).isNull(); @@ -138,8 +148,8 @@ public class MobileNetworkUtilsTest { @Test public void buildConfigureIntent_hasActivityHandleIntent_returnIntent() { - doReturn(Arrays.asList(mResolveInfo)).when(mPackageManager).queryIntentActivities( - nullable(Intent.class), anyInt()); + when(mPackageManager.queryIntentActivities(nullable(Intent.class), anyInt())) + .thenReturn(Arrays.asList(mResolveInfo)); assertThat(MobileNetworkUtils.buildPhoneAccountConfigureIntent(mContext, mPhoneAccountHandle)).isNotNull(); @@ -147,19 +157,29 @@ public class MobileNetworkUtilsTest { @Test public void isCdmaOptions_phoneTypeCdma_returnTrue() { - doReturn(PhoneConstants.PHONE_TYPE_CDMA).when(mTelephonyManager).getPhoneType(); + when(mTelephonyManager.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_CDMA); assertThat(MobileNetworkUtils.isCdmaOptions(mContext, SUB_ID_1)).isTrue(); } @Test public void isCdmaOptions_worldModeWithGsmWcdma_returnTrue() { - doReturn(PhoneConstants.PHONE_TYPE_GSM).when(mTelephonyManager).getPhoneType(); - doReturn("true").when(mContext).getString(R.string.config_world_mode); + when(mTelephonyManager.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_GSM); + when(mContext.getString(R.string.config_world_mode)).thenReturn("true"); Settings.Global.putInt(mContext.getContentResolver(), android.provider.Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID_1, TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA); assertThat(MobileNetworkUtils.isCdmaOptions(mContext, SUB_ID_1)).isTrue(); } + + @Test + public void isCdmaOptions_carrierWorldModeWithoutHideCarrier_returnTrue() { + when(mTelephonyManager.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_GSM); + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_HIDE_CARRIER_NETWORK_SETTINGS_BOOL, + false); + mCarrierConfig.putBoolean(CarrierConfigManager.KEY_WORLD_PHONE_BOOL, true); + + assertThat(MobileNetworkUtils.isCdmaOptions(mContext, SUB_ID_1)).isTrue(); + } } diff --git a/tests/robotests/src/com/android/settings/network/telephony/cdma/CdmaSubscriptionPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/cdma/CdmaSubscriptionPreferenceControllerTest.java index c938948a403..4044b6caf98 100644 --- a/tests/robotests/src/com/android/settings/network/telephony/cdma/CdmaSubscriptionPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/network/telephony/cdma/CdmaSubscriptionPreferenceControllerTest.java @@ -21,10 +21,13 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; import android.content.Context; +import android.os.PersistableBundle; import android.os.SystemProperties; import android.provider.Settings; +import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; @@ -53,9 +56,12 @@ public class CdmaSubscriptionPreferenceControllerTest { private TelephonyManager mInvalidTelephonyManager; @Mock private SubscriptionManager mSubscriptionManager; + @Mock + private CarrierConfigManager mCarrierConfigManager; private CdmaSubscriptionPreferenceController mController; private ListPreference mPreference; + private PersistableBundle mCarrierConfig; private Context mContext; @Before @@ -68,6 +74,10 @@ public class CdmaSubscriptionPreferenceControllerTest { doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID); doReturn(mInvalidTelephonyManager).when(mTelephonyManager).createForSubscriptionId( SubscriptionManager.INVALID_SUBSCRIPTION_ID); + doReturn(mCarrierConfigManager).when(mContext).getSystemService(CarrierConfigManager.class); + + mCarrierConfig = new PersistableBundle(); + when(mCarrierConfigManager.getConfigForSubId(SUB_ID)).thenReturn(mCarrierConfig); mPreference = new ListPreference(mContext); mController = new CdmaSubscriptionPreferenceController(mContext, "mobile_data"); diff --git a/tests/robotests/src/com/android/settings/network/telephony/cdma/CdmaSystemSelectPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/network/telephony/cdma/CdmaSystemSelectPreferenceControllerTest.java index 204623728ca..f00afc97bbc 100644 --- a/tests/robotests/src/com/android/settings/network/telephony/cdma/CdmaSystemSelectPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/network/telephony/cdma/CdmaSystemSelectPreferenceControllerTest.java @@ -21,9 +21,12 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; import android.content.Context; +import android.os.PersistableBundle; import android.provider.Settings; +import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; @@ -51,9 +54,12 @@ public class CdmaSystemSelectPreferenceControllerTest { private TelephonyManager mInvalidTelephonyManager; @Mock private SubscriptionManager mSubscriptionManager; + @Mock + private CarrierConfigManager mCarrierConfigManager; private CdmaSystemSelectPreferenceController mController; private ListPreference mPreference; + private PersistableBundle mCarrierConfig; private Context mContext; @Before @@ -67,6 +73,12 @@ public class CdmaSystemSelectPreferenceControllerTest { doReturn(mInvalidTelephonyManager).when(mTelephonyManager).createForSubscriptionId( SubscriptionManager.INVALID_SUBSCRIPTION_ID); + doReturn(mCarrierConfigManager).when(mContext).getSystemService(CarrierConfigManager.class); + + mCarrierConfig = new PersistableBundle(); + when(mCarrierConfigManager.getConfigForSubId(SUB_ID)).thenReturn(mCarrierConfig); + + mPreference = new ListPreference(mContext); mController = new CdmaSystemSelectPreferenceController(mContext, "mobile_data"); mController.init(mPreferenceManager, SUB_ID); @@ -101,6 +113,20 @@ public class CdmaSystemSelectPreferenceControllerTest { Integer.toString(TelephonyManager.CDMA_ROAMING_MODE_HOME)); } + @Test + public void updateState_LteGSMWcdma_disabled() { + doReturn(TelephonyManager.CDMA_ROAMING_MODE_HOME).when( + mTelephonyManager).getCdmaRoamingMode(); + Settings.Global.putInt(mContext.getContentResolver(), + Settings.Global.PREFERRED_NETWORK_MODE + SUB_ID, + TelephonyManager.NETWORK_MODE_LTE_GSM_WCDMA); + + mController.updateState(mPreference); + + assertThat(mPreference.isEnabled()).isFalse(); + } + + @Test public void updateState_stateOther_resetToDefault() { Settings.Global.putInt(mContext.getContentResolver(),