--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2017 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.
+ -->
+
+<ScrollView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="@dimen/sim_content_padding">
+
+ <TextView
+ style="@style/device_info_dialog_label"
+ android:id="@+id/operator_name_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/status_operator"/>
+ <TextView
+ style="@style/device_info_dialog_value"
+ android:id="@+id/operator_name_value"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/device_info_not_available"/>
+
+ <TextView
+ style="@style/device_info_dialog_label"
+ android:id="@+id/number_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/status_number_sim_status"/>
+ <TextView
+ style="@style/device_info_dialog_value"
+ android:id="@+id/number_value"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/device_info_not_available"/>
+
+ <TextView
+ style="@style/device_info_dialog_label"
+ android:id="@+id/data_state_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/status_data_state"/>
+ <TextView
+ style="@style/device_info_dialog_value"
+ android:id="@+id/data_state_value"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/device_info_not_available"/>
+
+ <TextView
+ style="@style/device_info_dialog_label"
+ android:id="@+id/latest_area_info_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/status_latest_area_info"/>
+ <TextView
+ style="@style/device_info_dialog_value"
+ android:id="@+id/latest_area_info_value"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/device_info_not_available"/>
+
+ <TextView
+ style="@style/device_info_dialog_label"
+ android:id="@+id/service_state_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/status_service_state"/>
+ <TextView
+ style="@style/device_info_dialog_value"
+ android:id="@+id/service_state_value"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/device_info_not_available"/>
+
+ <TextView
+ style="@style/device_info_dialog_label"
+ android:id="@+id/signal_strength_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/status_signal_strength"/>
+ <TextView
+ style="@style/device_info_dialog_value"
+ android:id="@+id/signal_strength_value"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/device_info_not_available"/>
+
+ <TextView
+ style="@style/device_info_dialog_label"
+ android:id="@+id/network_type_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/status_network_type"/>
+ <TextView
+ style="@style/device_info_dialog_value"
+ android:id="@+id/network_type_value"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/device_info_not_available"/>
+
+ <TextView
+ style="@style/device_info_dialog_label"
+ android:id="@+id/roaming_state_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/status_roaming"/>
+ <TextView
+ style="@style/device_info_dialog_value"
+ android:id="@+id/roaming_state_value"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/device_info_not_available"/>
+ </LinearLayout>
+</ScrollView>
<string name="status_number" product="tablet">MDN</string>
<!-- About phone, status item title. The phone number of the current device [CHAR LIMIT=30] -->
<string name="status_number" product="default">Phone number</string>
+ <!-- About tablet, status item title. The Mobile Directory Number [CHAR LIMIT=30] -->
+ <string name="status_number_sim_status" product="tablet">MDN on SIM</string>
+ <!-- About phone, status item title. The phone number of the current device [CHAR LIMIT=30] -->
+ <string name="status_number_sim_status" product="default">Phone number on SIM</string>
<!-- About phone, status item title. The phone MIN number of the current device.-->
<string name="status_min_number">MIN</string>
<!-- About phone, status item title. The phone MSID number of the current device.-->
<string name="sim_no_inserted_msg">No SIM cards inserted</string>
<!-- SIM status title [CHAR LIMIT=40] -->
<string name="sim_status_title">SIM status</string>
+ <!-- SIM status title [CHAR LIMIT=40] -->
+ <string name="sim_status_title_sim_slot_1">SIM status (sim slot 1)</string>
+ <!-- SIM status title [CHAR LIMIT=40] -->
+ <string name="sim_status_title_sim_slot_2">SIM status (sim slot 2)</string>
<!-- Title for call back. [CHAR LIMIT=60] -->
<string name="sim_call_back_title">Call back from default SIM</string>
<!-- Title for outgoing back. [CHAR LIMIT=60] -->
<item name="android:textSize">@dimen/search_bar_text_size</item>
</style>
+ <style name="device_info_dialog_label">
+ <item name="android:textAppearance">@android:style/TextAppearance.Material.Body1</item>
+ <item name="android:textColor">?android:attr/textColorSecondary</item>
+ </style>
+
+ <style name="device_info_dialog_value">
+ <item name="android:textAppearance">@android:style/TextAppearance.Material.Body2</item>
+ <item name="android:paddingBottom">24dp</item>
+ </style>
+
</resources>
android:title="@string/status_number"
android:summary="@string/summary_placeholder"/>
- <!-- SIM status -->
+ <!-- SIM status Sim Slot 1 -->
<Preference
- android:key="sim_status"
+ android:key="sim_status_sim_1"
android:title="@string/sim_status_title"
android:summary="@string/summary_placeholder"/>
+ <!-- SIM status Sim Slot 2-->
+ <Preference
+ android:key="sim_status_sim_2"
+ android:title="@string/sim_status_title_sim_slot_2"
+ android:summary="@string/summary_placeholder"/>
+
+
<!-- Model & hardware -->
<Preference
android:key="device_model"
import com.android.settings.deviceinfo.RegulatoryInfoPreferenceController;
import com.android.settings.deviceinfo.SafetyInfoPreferenceController;
import com.android.settings.deviceinfo.SecurityPatchPreferenceController;
+import com.android.settings.deviceinfo.simstatus.SimStatusDualSimPreferenceController;
+import com.android.settings.deviceinfo.simstatus.SimStatusPreferenceControllerV2;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settingslib.core.AbstractPreferenceController;
// Phone number
- // SIM status
+ controllers.add(new SimStatusPreferenceControllerV2(context, fragment));
+
+ controllers.add(new SimStatusDualSimPreferenceController(context, fragment));
controllers.add(new DeviceModelPreferenceController(context, fragment));
* # Operator info (area update info cell broadcast)
* # Signal Strength
*
+ * deprecated in favor of {@link com.android.settings.deviceinfo.simstatus.SimStatusDialogFragment}
*/
+@Deprecated
public class SimStatus extends SettingsPreferenceFragment {
private static final String TAG = "SimStatus";
import android.content.Context;
import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.deviceinfo.simstatus.SimStatusPreferenceControllerV2;
import com.android.settingslib.deviceinfo.AbstractSimStatusImeiInfoPreferenceController;
+/**
+ * deprecated in favor of {@link SimStatusPreferenceControllerV2}
+ */
+@Deprecated
public class SimStatusPreferenceController extends AbstractSimStatusImeiInfoPreferenceController
implements PreferenceControllerMixin {
--- /dev/null
+/*
+ * Copyright (C) 2017 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.deviceinfo.simstatus;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+
+import com.android.settings.R;
+import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settingslib.deviceinfo.AbstractSimStatusImeiInfoPreferenceController;
+
+import java.util.List;
+
+public abstract class AbstractSimStatusPreferenceController extends
+ AbstractSimStatusImeiInfoPreferenceController implements PreferenceControllerMixin {
+
+ protected final boolean mIsMultiSim;
+ protected final TelephonyManager mTelephonyManager;
+ private final SubscriptionManager mSubscriptionManager;
+ private final Fragment mFragment;
+
+ private Preference mPreference;
+
+ public AbstractSimStatusPreferenceController(Context context, Fragment fragment) {
+ super(context);
+
+ mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ mSubscriptionManager = (SubscriptionManager) context.getSystemService(
+ Context.TELEPHONY_SUBSCRIPTION_SERVICE);
+ mFragment = fragment;
+ mIsMultiSim = mTelephonyManager.getPhoneCount() > 1;
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ mPreference = screen.findPreference(getPreferenceKey());
+ if (mPreference == null) {
+ return;
+ }
+
+ mPreference.setTitle(getPreferenceTitle());
+ mPreference.setSummary(getCarrierName());
+ }
+
+ @Override
+ public boolean handlePreferenceTreeClick(Preference preference) {
+ if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) {
+ return false;
+ }
+
+ SimStatusDialogFragment.show(mFragment, getSimSlot(), getPreferenceTitle());
+ return true;
+ }
+
+ /**
+ * @return The preference title for the displayed preference.
+ */
+ protected abstract String getPreferenceTitle();
+
+ /**
+ * @return The sim slot to retrieve sim status information about.
+ */
+ protected abstract int getSimSlot();
+
+ private CharSequence getCarrierName() {
+ final List<SubscriptionInfo> subscriptionInfoList =
+ mSubscriptionManager.getActiveSubscriptionInfoList();
+ if (subscriptionInfoList != null) {
+ for (SubscriptionInfo info : subscriptionInfoList) {
+ if (info.getSimSlotIndex() == getSimSlot()) {
+ return info.getCarrierName();
+ }
+ }
+ }
+ return mContext.getText(R.string.device_info_not_available);
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 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.deviceinfo.simstatus;
+
+import static android.content.Context.TELEPHONY_SERVICE;
+
+import android.Manifest;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.support.annotation.NonNull;
+import android.support.annotation.VisibleForTesting;
+import android.telephony.CellBroadcastMessage;
+import android.telephony.PhoneStateListener;
+import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.settings.R;
+import com.android.settingslib.DeviceInfoUtils;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+import com.android.settingslib.core.lifecycle.LifecycleObserver;
+import com.android.settingslib.core.lifecycle.events.OnPause;
+import com.android.settingslib.core.lifecycle.events.OnResume;
+
+import java.util.List;
+
+public class SimStatusDialogController implements LifecycleObserver, OnResume, OnPause {
+
+ private final static String TAG = "SimStatusDialogCtrl";
+
+ @VisibleForTesting
+ final static int NETWORK_PROVIDER_VALUE_ID = R.id.operator_name_value;
+ @VisibleForTesting
+ final static int PHONE_NUMBER_VALUE_ID = R.id.number_value;
+ @VisibleForTesting
+ final static int CELLULAR_NETWORK_STATE = R.id.data_state_value;
+ @VisibleForTesting
+ final static int OPERATOR_INFO_LABEL_ID = R.id.latest_area_info_label;
+ @VisibleForTesting
+ final static int OPERATOR_INFO_VALUE_ID = R.id.latest_area_info_value;
+ @VisibleForTesting
+ final static int SERVICE_STATE_VALUE_ID = R.id.service_state_value;
+ @VisibleForTesting
+ final static int SIGNAL_STRENGTH_VALUE_ID = R.id.signal_strength_value;
+ @VisibleForTesting
+ final static int CELLULAR_NETWORK_TYPE_VALUE_ID = R.id.network_type_value;
+ @VisibleForTesting
+ final static int ROAMING_INFO_VALUE_ID = R.id.roaming_state_value;
+
+ private final static String CB_AREA_INFO_RECEIVED_ACTION =
+ "com.android.cellbroadcastreceiver.CB_AREA_INFO_RECEIVED";
+ private final static String GET_LATEST_CB_AREA_INFO_ACTION =
+ "com.android.cellbroadcastreceiver.GET_LATEST_CB_AREA_INFO";
+ private final static String CELL_BROADCAST_RECEIVER_APP = "com.android.cellbroadcastreceiver";
+
+ private final SimStatusDialogFragment mDialog;
+ private final SubscriptionInfo mSubscriptionInfo;
+ private final TelephonyManager mTelephonyManager;
+ private final Resources mRes;
+ private final Context mContext;
+
+ private boolean mShowLatestAreaInfo;
+
+ private final BroadcastReceiver mAreaInfoReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (TextUtils.equals(action, CB_AREA_INFO_RECEIVED_ACTION)) {
+ final Bundle extras = intent.getExtras();
+ if (extras == null) {
+ return;
+ }
+ final CellBroadcastMessage cbMessage = (CellBroadcastMessage) extras.get("message");
+ if (cbMessage != null
+ && mSubscriptionInfo.getSubscriptionId() == cbMessage.getSubId()) {
+ final String latestAreaInfo = cbMessage.getMessageBody();
+ mDialog.setText(OPERATOR_INFO_VALUE_ID, latestAreaInfo);
+ }
+ }
+ }
+ };
+
+
+ private PhoneStateListener mPhoneStateListener;
+
+ public SimStatusDialogController(@NonNull SimStatusDialogFragment dialog, Lifecycle lifecycle,
+ int slotId) {
+ mDialog = dialog;
+ mContext = dialog.getContext();
+ mSubscriptionInfo = getPhoneSubscriptionInfo(slotId);
+ mTelephonyManager = (TelephonyManager) mContext.getSystemService(
+ TELEPHONY_SERVICE);
+ mRes = mContext.getResources();
+
+ if (lifecycle != null) {
+ lifecycle.addObserver(this);
+ }
+ }
+
+ public void initialize() {
+ if (mSubscriptionInfo == null) {
+ return;
+ }
+
+ mPhoneStateListener = getPhoneStateListener();
+
+ final ServiceState serviceState = getCurrentServiceState();
+ updateNetworkProvider(serviceState);
+ updatePhoneNumber();
+ updateLatestAreaInfo();
+ updateServiceState(serviceState);
+ updateSignalStrength(getSignalStrength());
+ updateNetworkType();
+ updateRoamingStatus(serviceState);
+ }
+
+ @Override
+ public void onResume() {
+ if (mSubscriptionInfo == null) {
+ return;
+ }
+
+ mTelephonyManager.listen(mPhoneStateListener,
+ PhoneStateListener.LISTEN_DATA_CONNECTION_STATE
+ | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS
+ | PhoneStateListener.LISTEN_SERVICE_STATE);
+
+ if (mShowLatestAreaInfo) {
+ mContext.registerReceiver(mAreaInfoReceiver,
+ new IntentFilter(CB_AREA_INFO_RECEIVED_ACTION),
+ Manifest.permission.RECEIVE_EMERGENCY_BROADCAST, null /* scheduler */);
+ // Ask CellBroadcastReceiver to broadcast the latest area info received
+ final Intent getLatestIntent = new Intent(GET_LATEST_CB_AREA_INFO_ACTION);
+ getLatestIntent.setPackage(CELL_BROADCAST_RECEIVER_APP);
+ mContext.sendBroadcastAsUser(getLatestIntent, UserHandle.ALL,
+ Manifest.permission.RECEIVE_EMERGENCY_BROADCAST);
+ }
+ }
+
+ @Override
+ public void onPause() {
+ if (mSubscriptionInfo == null) {
+ return;
+ }
+
+ mTelephonyManager.listen(mPhoneStateListener,
+ PhoneStateListener.LISTEN_NONE);
+
+ if (mShowLatestAreaInfo) {
+ mContext.unregisterReceiver(mAreaInfoReceiver);
+ }
+ }
+
+ private void updateNetworkProvider(ServiceState serviceState) {
+ mDialog.setText(NETWORK_PROVIDER_VALUE_ID, serviceState.getOperatorAlphaLong());
+ }
+
+ private void updatePhoneNumber() {
+ // If formattedNumber is null or empty, it'll display as "Unknown".
+ mDialog.setText(PHONE_NUMBER_VALUE_ID, getPhoneNumber());
+ }
+
+ private void updateDataState(int state) {
+ String networkStateValue;
+
+ switch (state) {
+ case TelephonyManager.DATA_CONNECTED:
+ networkStateValue = mRes.getString(R.string.radioInfo_data_connected);
+ break;
+ case TelephonyManager.DATA_SUSPENDED:
+ networkStateValue = mRes.getString(R.string.radioInfo_data_suspended);
+ break;
+ case TelephonyManager.DATA_CONNECTING:
+ networkStateValue = mRes.getString(R.string.radioInfo_data_connecting);
+ break;
+ case TelephonyManager.DATA_DISCONNECTED:
+ networkStateValue = mRes.getString(R.string.radioInfo_data_disconnected);
+ break;
+ default:
+ networkStateValue = mRes.getString(R.string.radioInfo_unknown);
+ break;
+ }
+
+ mDialog.setText(CELLULAR_NETWORK_STATE, networkStateValue);
+ }
+
+
+ private void updateLatestAreaInfo() {
+ mShowLatestAreaInfo = Resources.getSystem().getBoolean(
+ com.android.internal.R.bool.config_showAreaUpdateInfoSettings)
+ && mTelephonyManager.getPhoneType() != TelephonyManager.PHONE_TYPE_CDMA;
+
+ if (!mShowLatestAreaInfo) {
+ mDialog.removeSettingFromScreen(OPERATOR_INFO_LABEL_ID);
+ mDialog.removeSettingFromScreen(OPERATOR_INFO_VALUE_ID);
+ }
+ }
+
+ private void updateServiceState(ServiceState serviceState) {
+ final int state = serviceState.getState();
+ if (state == ServiceState.STATE_OUT_OF_SERVICE || state == ServiceState.STATE_POWER_OFF) {
+ resetSignalStrength();
+ }
+
+ String serviceStateValue;
+
+ switch (state) {
+ case ServiceState.STATE_IN_SERVICE:
+ serviceStateValue = mRes.getString(R.string.radioInfo_service_in);
+ break;
+ case ServiceState.STATE_OUT_OF_SERVICE:
+ case ServiceState.STATE_EMERGENCY_ONLY:
+ // Set summary string of service state to radioInfo_service_out when
+ // service state is both STATE_OUT_OF_SERVICE & STATE_EMERGENCY_ONLY
+ serviceStateValue = mRes.getString(R.string.radioInfo_service_out);
+ break;
+ case ServiceState.STATE_POWER_OFF:
+ serviceStateValue = mRes.getString(R.string.radioInfo_service_off);
+ break;
+ default:
+ serviceStateValue = mRes.getString(R.string.radioInfo_unknown);
+ break;
+ }
+
+ mDialog.setText(SERVICE_STATE_VALUE_ID, serviceStateValue);
+ }
+
+ private void updateSignalStrength(SignalStrength signalStrength) {
+ final int state = getCurrentServiceState().getState();
+
+ if ((ServiceState.STATE_OUT_OF_SERVICE == state) ||
+ (ServiceState.STATE_POWER_OFF == state)) {
+ return;
+ }
+
+ int signalDbm = getDbm(signalStrength);
+ int signalAsu = getAsuLevel(signalStrength);
+
+ if (signalDbm == -1) {
+ signalDbm = 0;
+ }
+
+ if (signalAsu == -1) {
+ signalAsu = 0;
+ }
+
+ mDialog.setText(SIGNAL_STRENGTH_VALUE_ID, mRes.getString(R.string.sim_signal_strength,
+ signalDbm, signalAsu));
+ }
+
+ private void resetSignalStrength() {
+ mDialog.setText(SIGNAL_STRENGTH_VALUE_ID, "0");
+ }
+
+ private void updateNetworkType() {
+ // Whether EDGE, UMTS, etc...
+ String networktype = null;
+ final int subId = mSubscriptionInfo.getSubscriptionId();
+ final int actualDataNetworkType = mTelephonyManager.getDataNetworkType(subId);
+ final int actualVoiceNetworkType = mTelephonyManager.getVoiceNetworkType(subId);
+ if (TelephonyManager.NETWORK_TYPE_UNKNOWN != actualDataNetworkType) {
+ networktype = mTelephonyManager.getNetworkTypeName(actualDataNetworkType);
+ } else if (TelephonyManager.NETWORK_TYPE_UNKNOWN != actualVoiceNetworkType) {
+ networktype = mTelephonyManager.getNetworkTypeName(actualVoiceNetworkType);
+ }
+
+ boolean show4GForLTE = false;
+ try {
+ final Context con = mContext.createPackageContext(
+ "com.android.systemui", 0 /* flags */);
+ final int id = con.getResources().getIdentifier("config_show4GForLTE",
+ "bool" /* default type */, "com.android.systemui" /* default package */);
+ show4GForLTE = con.getResources().getBoolean(id);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG, "NameNotFoundException for show4GFotLTE");
+ }
+
+ if (TextUtils.equals(networktype, "LTE") && show4GForLTE) {
+ networktype = "4G";
+ }
+ mDialog.setText(CELLULAR_NETWORK_TYPE_VALUE_ID, networktype);
+ }
+
+ private void updateRoamingStatus(ServiceState serviceState) {
+ if (serviceState.getRoaming()) {
+ mDialog.setText(ROAMING_INFO_VALUE_ID, mRes.getString(R.string.radioInfo_roaming_in));
+ } else {
+ mDialog.setText(ROAMING_INFO_VALUE_ID, mRes.getString(R.string.radioInfo_roaming_not));
+ }
+ }
+
+ private SubscriptionInfo getPhoneSubscriptionInfo(int slotId) {
+ final List<SubscriptionInfo> subscriptionInfoList = SubscriptionManager.from(
+ mContext).getActiveSubscriptionInfoList();
+ if (subscriptionInfoList != null && subscriptionInfoList.size() > slotId) {
+ return subscriptionInfoList.get(slotId);
+ } else {
+ return null;
+ }
+ }
+
+ @VisibleForTesting
+ ServiceState getCurrentServiceState() {
+ return mTelephonyManager.getServiceStateForSubscriber(
+ mSubscriptionInfo.getSubscriptionId());
+ }
+
+ @VisibleForTesting
+ int getDbm(SignalStrength signalStrength) {
+ return signalStrength.getDbm();
+ }
+
+ @VisibleForTesting
+ int getAsuLevel(SignalStrength signalStrength) {
+ return signalStrength.getAsuLevel();
+ }
+
+ @VisibleForTesting
+ PhoneStateListener getPhoneStateListener() {
+ return new PhoneStateListener(
+ mSubscriptionInfo.getSubscriptionId()) {
+ @Override
+ public void onDataConnectionStateChanged(int state) {
+ updateDataState(state);
+ updateNetworkType();
+ }
+
+ @Override
+ public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+ updateSignalStrength(signalStrength);
+ }
+
+ @Override
+ public void onServiceStateChanged(ServiceState serviceState) {
+ updateNetworkProvider(serviceState);
+ updateServiceState(serviceState);
+ updateRoamingStatus(serviceState);
+ }
+ };
+ }
+
+ @VisibleForTesting
+ String getPhoneNumber() {
+ return DeviceInfoUtils.getFormattedPhoneNumber(mContext, mSubscriptionInfo);
+ }
+
+ @VisibleForTesting
+ SignalStrength getSignalStrength() {
+ return mTelephonyManager.getSignalStrength();
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 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.deviceinfo.simstatus;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+
+public class SimStatusDialogFragment extends InstrumentedDialogFragment {
+
+ private static final String SIM_SLOT_BUNDLE_KEY = "arg_key_sim_slot";
+ private static final String DIALOG_TITLE_BUNDLE_KEY = "arg_key_dialog_title";
+
+ private static final String TAG = "SimStatusDialog";
+
+ private View mRootView;
+ private SimStatusDialogController mController;
+
+ @Override
+ public int getMetricsCategory() {
+ return MetricsProto.MetricsEvent.DIALOG_SIM_STATUS;
+ }
+
+ public static void show(Fragment host, int slotId, String dialogTitle) {
+ final FragmentManager manager = host.getChildFragmentManager();
+ if (manager.findFragmentByTag(TAG) == null) {
+ final Bundle bundle = new Bundle();
+ bundle.putInt(SIM_SLOT_BUNDLE_KEY, slotId);
+ bundle.putString(DIALOG_TITLE_BUNDLE_KEY, dialogTitle);
+ final SimStatusDialogFragment dialog =
+ new SimStatusDialogFragment();
+ dialog.setArguments(bundle);
+ dialog.show(manager, TAG);
+ }
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final Bundle bundle = getArguments();
+ final int slotId = bundle.getInt(SIM_SLOT_BUNDLE_KEY);
+ final String dialogTitle = bundle.getString(DIALOG_TITLE_BUNDLE_KEY);
+ mController = new SimStatusDialogController(this, mLifecycle, slotId);
+ final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
+ .setTitle(dialogTitle)
+ .setPositiveButton(android.R.string.ok, null /* onClickListener */);
+ mRootView = LayoutInflater.from(builder.getContext())
+ .inflate(R.layout.dialog_sim_status, null /* parent */);
+ mController.initialize();
+ return builder.setView(mRootView).create();
+ }
+
+ public void removeSettingFromScreen(int viewId) {
+ final View view = mRootView.findViewById(viewId);
+ if (view != null) {
+ view.setVisibility(View.GONE);
+ }
+ }
+
+ public void setText(int viewId, CharSequence text) {
+ final TextView textView = mRootView.findViewById(viewId);
+ if (TextUtils.isEmpty(text)) {
+ text = getResources().getString(R.string.device_info_default);
+ }
+ if (textView != null) {
+ textView.setText(text);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 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.deviceinfo.simstatus;
+
+import android.app.Fragment;
+import android.content.Context;
+
+import com.android.settings.R;
+
+public class SimStatusDualSimPreferenceController extends AbstractSimStatusPreferenceController {
+
+ private static final int SIM_SLOT = 1;
+ private static final String SIM_STATUS_DUAL_SIM_KEY = "sim_status_sim_2";
+
+ public SimStatusDualSimPreferenceController(Context context, Fragment fragment) {
+ super(context, fragment);
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return super.isAvailable() && mIsMultiSim;
+ }
+
+ @Override
+ protected String getPreferenceTitle() {
+ return mContext.getResources().getString(R.string.sim_status_title_sim_slot_2);
+ }
+
+ @Override
+ protected int getSimSlot() {
+ return SIM_SLOT;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return SIM_STATUS_DUAL_SIM_KEY;
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 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.deviceinfo.simstatus;
+
+import android.app.Fragment;
+import android.content.Context;
+
+import com.android.settings.R;
+
+public class SimStatusPreferenceControllerV2 extends AbstractSimStatusPreferenceController {
+
+ public static final int SIM_SLOT = 0;
+
+ private static final String KEY_SIM_1_STATUS = "sim_status_sim_1";
+
+ public SimStatusPreferenceControllerV2(Context context, Fragment fragment) {
+ super(context, fragment);
+ }
+
+ @Override
+ protected String getPreferenceTitle() {
+ return mIsMultiSim ? mContext.getResources().getString(R.string.sim_status_title_sim_slot_1)
+ : mContext.getResources().getString(R.string.sim_status_title);
+ }
+
+ @Override
+ protected int getSimSlot() {
+ return SIM_SLOT;
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return KEY_SIM_1_STATUS;
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 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.deviceinfo.simstatus;
+
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.Fragment;
+import android.app.FragmentManager;
+import android.content.Context;
+import android.os.UserManager;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class AbstractSimStatusPreferenceControllerTest {
+
+ @Mock
+ private Preference mPreference;
+ @Mock
+ private PreferenceScreen mScreen;
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private Fragment mFragment;
+
+ private Context mContext;
+ private AbstractSimStatusPreferenceControllerImpl mController;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
+ doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
+ mController = new AbstractSimStatusPreferenceControllerImpl(mContext, mFragment);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+ when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
+ }
+
+ @Test
+ public void displayPreference_shouldSetTitleAndSummary() {
+ mController.displayPreference(mScreen);
+
+ verify(mPreference).setTitle(mController.getPreferenceTitle());
+ verify(mPreference).setSummary(anyString());
+ }
+
+ @Test
+ public void handlePreferenceTreeClick_shouldStartDialogFragment() {
+ when(mFragment.getChildFragmentManager()).thenReturn(
+ mock(FragmentManager.class, Answers.RETURNS_DEEP_STUBS));
+ when(mPreference.getTitle()).thenReturn("foo");
+ mController.displayPreference(mScreen);
+
+ mController.handlePreferenceTreeClick(mPreference);
+
+ verify(mFragment).getChildFragmentManager();
+ }
+
+ public class AbstractSimStatusPreferenceControllerImpl extends
+ AbstractSimStatusPreferenceController {
+
+ public AbstractSimStatusPreferenceControllerImpl(Context context, Fragment fragment) {
+ super(context, fragment);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return "foo";
+ }
+
+ @Override
+ protected String getPreferenceTitle() {
+ return "bar";
+ }
+
+ @Override
+ protected int getSimSlot() {
+ return 0;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 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.deviceinfo.simstatus;
+
+import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController
+ .CELLULAR_NETWORK_TYPE_VALUE_ID;
+import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController
+ .NETWORK_PROVIDER_VALUE_ID;
+import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController
+ .OPERATOR_INFO_LABEL_ID;
+import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController
+ .OPERATOR_INFO_VALUE_ID;
+import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController
+ .PHONE_NUMBER_VALUE_ID;
+import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController
+ .ROAMING_INFO_VALUE_ID;
+import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController
+ .SERVICE_STATE_VALUE_ID;
+import static com.android.settings.deviceinfo.simstatus.SimStatusDialogController
+ .SIGNAL_STRENGTH_VALUE_ID;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+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.PhoneStateListener;
+import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
+import android.telephony.SubscriptionInfo;
+import android.telephony.TelephonyManager;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+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 org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class SimStatusDialogControllerTest {
+
+ @Mock
+ private SimStatusDialogFragment mDialog;
+ @Mock
+ private TelephonyManager mTelephonyManager;
+ @Mock
+ private SubscriptionInfo mSubscriptionInfo;
+ @Mock
+ private ServiceState mServiceState;
+ @Mock
+ private PhoneStateListener mPhoneStateListener;
+ @Mock
+ private SignalStrength mSignalStrength;
+
+
+ private SimStatusDialogController mController;
+ private Context mContext;
+
+ @Before
+ public void setup() {
+ MockitoAnnotations.initMocks(this);
+ mContext = RuntimeEnvironment.application;
+ when(mDialog.getContext()).thenReturn(mContext);
+ mController = spy(
+ new SimStatusDialogController(mDialog, new Lifecycle(), 0 /* phone id */));
+ doReturn(mServiceState).when(mController).getCurrentServiceState();
+ doReturn(0).when(mController).getDbm(any());
+ doReturn(0).when(mController).getAsuLevel(any());
+ doReturn(mPhoneStateListener).when(mController).getPhoneStateListener();
+ doReturn("").when(mController).getPhoneNumber();
+ doReturn(mSignalStrength).when(mController).getSignalStrength();
+ ReflectionHelpers.setField(mController, "mTelephonyManager", mTelephonyManager);
+ ReflectionHelpers.setField(mController, "mSubscriptionInfo", mSubscriptionInfo);
+ }
+
+ @Test
+ public void initialize_updateNetworkProviderWithFoobarCarrier_shouldUpdateCarrierWithFoobar() {
+ final String carrierName = "foobar";
+ when(mServiceState.getOperatorAlphaLong()).thenReturn(carrierName);
+
+ mController.initialize();
+
+ verify(mDialog).setText(NETWORK_PROVIDER_VALUE_ID, carrierName);
+ }
+
+ @Test
+ public void initialize_updatePhoneNumberWith1111111111_shouldUpdatePhoneNumber() {
+ final String phoneNumber = "1111111111";
+ doReturn(phoneNumber).when(mController).getPhoneNumber();
+
+ mController.initialize();
+
+ verify(mDialog).setText(PHONE_NUMBER_VALUE_ID, phoneNumber);
+ }
+
+ @Test
+ public void initialize_updateLatestAreaInfoWithCdmaPhone_shouldRemoveOperatorInfoSetting() {
+ when(mTelephonyManager.getPhoneType()).thenReturn(TelephonyManager.PHONE_TYPE_CDMA);
+
+ mController.initialize();
+
+ verify(mDialog).removeSettingFromScreen(OPERATOR_INFO_LABEL_ID);
+ verify(mDialog).removeSettingFromScreen(OPERATOR_INFO_VALUE_ID);
+ }
+
+ @Test
+ public void initialize_updateServiceStateWithInService_shouldUpdateTextToBeCInService() {
+ when(mServiceState.getState()).thenReturn(ServiceState.STATE_IN_SERVICE);
+
+ mController.initialize();
+
+ final String inServiceText = mContext.getResources().getString(
+ R.string.radioInfo_service_in);
+ verify(mDialog).setText(SERVICE_STATE_VALUE_ID, inServiceText);
+ }
+
+ @Test
+ public void initialize_updateDataStateWithPowerOff_shouldUpdateSettingAndResetSignalStrength() {
+ when(mServiceState.getState()).thenReturn(ServiceState.STATE_POWER_OFF);
+
+ mController.initialize();
+
+ final String offServiceText = mContext.getResources().getString(
+ R.string.radioInfo_service_off);
+ verify(mDialog).setText(SERVICE_STATE_VALUE_ID, offServiceText);
+ verify(mDialog).setText(SIGNAL_STRENGTH_VALUE_ID, "0");
+ }
+
+ @Test
+ public void initialize_updateSignalStrengthWith50_shouldUpdateSignalStrengthTo50() {
+ final int signalDbm = 50;
+ final int signalAsu = 50;
+ doReturn(signalDbm).when(mController).getDbm(mSignalStrength);
+ doReturn(signalAsu).when(mController).getAsuLevel(mSignalStrength);
+
+ mController.initialize();
+
+ final String signalStrengthString = mContext.getResources().getString(
+ R.string.sim_signal_strength, signalDbm, signalAsu);
+ verify(mDialog).setText(SIGNAL_STRENGTH_VALUE_ID, signalStrengthString);
+ }
+
+ @Test
+ public void initialize_updateNetworkTypeWithEdge_shouldUpdateSettingToEdge() {
+ when(mTelephonyManager.getDataNetworkType(anyInt())).thenReturn(
+ TelephonyManager.NETWORK_TYPE_EDGE);
+
+ mController.initialize();
+
+ verify(mDialog).setText(CELLULAR_NETWORK_TYPE_VALUE_ID,
+ TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_EDGE));
+ }
+
+ @Test
+ public void initialize_updateRoamingStatusIsRoaming_shouldSetSettingToRoaming() {
+ when(mServiceState.getRoaming()).thenReturn(true);
+
+ mController.initialize();
+
+ final String roamingOnString = mContext.getResources().getString(
+ R.string.radioInfo_roaming_in);
+ verify(mDialog).setText(ROAMING_INFO_VALUE_ID, roamingOnString);
+ }
+
+ @Test
+ public void initialize_updateRoamingStatusNotRoaming_shouldSetSettingToRoamingOff() {
+ when(mServiceState.getRoaming()).thenReturn(false);
+
+ mController.initialize();
+
+ final String roamingOffString = mContext.getResources().getString(
+ R.string.radioInfo_roaming_not);
+ verify(mDialog).setText(ROAMING_INFO_VALUE_ID, roamingOffString);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 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.deviceinfo.simstatus;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.os.UserManager;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.telephony.TelephonyManager;
+
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+import com.google.common.truth.Truth;
+
+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 org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class SimStatusDualSimPreferenceControllerTest {
+
+ @Mock
+ private Preference mPreference;
+ @Mock
+ private PreferenceScreen mScreen;
+ @Mock
+ private TelephonyManager mTelephonyManager;
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private ConnectivityManager mConnectivityManager;
+ @Mock
+ private Fragment mFragment;
+
+ private Context mContext;
+ private SimStatusDualSimPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
+ doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
+ doReturn(mConnectivityManager).when(mContext).getSystemService(ConnectivityManager.class);
+ when(mUserManager.isAdminUser()).thenReturn(true);
+ when(mConnectivityManager.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(
+ true);
+ mController = new SimStatusDualSimPreferenceController(mContext, mFragment);
+ ReflectionHelpers.setField(mController, "mTelephonyManager", mTelephonyManager);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+ when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
+ }
+
+ @Test
+ public void isAvailable_multiSim_shouldBeTrue() {
+ ReflectionHelpers.setField(mController, "mIsMultiSim", true);
+
+ Truth.assertThat(mController.isAvailable()).isTrue();
+ }
+
+ @Test
+ public void isAvailable_notMultiSim_shouldBeFalse() {
+ ReflectionHelpers.setField(mController, "mIsMultiSim", false);
+
+ Truth.assertThat(mController.isAvailable()).isFalse();
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) 2017 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.deviceinfo.simstatus;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.os.UserManager;
+import android.support.v7.preference.Preference;
+import android.support.v7.preference.PreferenceScreen;
+import android.telephony.TelephonyManager;
+
+import com.android.settings.R;
+import com.android.settings.TestConfig;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+
+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 org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+public class SimStatusPreferenceControllerV2Test {
+
+ @Mock
+ private Preference mPreference;
+ @Mock
+ private PreferenceScreen mScreen;
+ @Mock
+ private TelephonyManager mTelephonyManager;
+ @Mock
+ private UserManager mUserManager;
+ @Mock
+ private Fragment mFragment;
+
+ private Context mContext;
+ private SimStatusPreferenceControllerV2 mController;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mContext = spy(RuntimeEnvironment.application);
+ doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
+ mController = new SimStatusPreferenceControllerV2(mContext, mFragment);
+ ReflectionHelpers.setField(mController, "mTelephonyManager", mTelephonyManager);
+ when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
+ when(mPreference.getKey()).thenReturn(mController.getPreferenceKey());
+ }
+
+ @Test
+ public void getPreferenceTitle_noMultiSim_shouldReturnSingleSimString() {
+ ReflectionHelpers.setField(mController, "mIsMultiSim", false);
+
+ assertThat(mController.getPreferenceTitle()).isEqualTo(mContext.getResources().getString(
+ R.string.sim_status_title));
+ }
+
+ @Test
+ public void getPreferenceTitle_multiSim_shouldReturnMultiSimString() {
+ ReflectionHelpers.setField(mController, "mIsMultiSim", true);
+
+ assertThat(mController.getPreferenceTitle()).isEqualTo(mContext.getResources().getString(
+ R.string.sim_status_title_sim_slot_1));
+ }
+}