From: Jan Nordqvist Date: Mon, 26 Mar 2018 22:29:44 +0000 (-0700) Subject: Fall back to Wi-Fi data display in data usage screen with no SIM. X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=9eb43ddddf23194ac97706642d43092a39279d02;p=android-x86%2Fpackages-apps-Settings.git Fall back to Wi-Fi data display in data usage screen with no SIM. Bug: 70950124 Test: manual Test: make RunSettingsRoboTests Change-Id: I06bf78e54119819be87e15baca7e5b6a241958cb --- diff --git a/res/values/strings.xml b/res/values/strings.xml index 7507de2dee..1e65b3779d 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -8710,6 +8710,9 @@ %1$s of data used + + ^1 used on Wi\u2011Fi + Off for 1 app @@ -8947,7 +8950,7 @@ App data usage - Wi-Fi data usage + Wi\u2011Fi data usage Ethernet data usage @@ -9040,6 +9043,9 @@ Primary data + + Wi\u2011Fi data + ^1 used @@ -9079,6 +9085,9 @@ View plan + + View details + Data Saver diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java index bf4da66359..95a039ba63 100644 --- a/src/com/android/settings/SettingsPreferenceFragment.java +++ b/src/com/android/settings/SettingsPreferenceFragment.java @@ -375,7 +375,8 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF return mPreferenceCache != null ? mPreferenceCache.size() : 0; } - protected boolean removePreference(String key) { + @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED) + public boolean removePreference(String key) { return removePreference(getPreferenceScreen(), key); } diff --git a/src/com/android/settings/datausage/DataUsageBaseFragment.java b/src/com/android/settings/datausage/DataUsageBaseFragment.java index 344f2b88d7..e9c73ff8cc 100644 --- a/src/com/android/settings/datausage/DataUsageBaseFragment.java +++ b/src/com/android/settings/datausage/DataUsageBaseFragment.java @@ -48,13 +48,14 @@ public abstract class DataUsageBaseFragment extends DashboardFragment { @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); - final Context context = getActivity(); + Context context = getContext(); services.mNetworkService = INetworkManagementService.Stub.asInterface( ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE)); services.mStatsService = INetworkStatsService.Stub.asInterface( ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); - services.mPolicyManager = NetworkPolicyManager.from(context); + services.mPolicyManager = (NetworkPolicyManager)context + .getSystemService(Context.NETWORK_POLICY_SERVICE); services.mPolicyEditor = new NetworkPolicyEditor(services.mPolicyManager); @@ -100,6 +101,7 @@ public abstract class DataUsageBaseFragment extends DashboardFragment { /** * Test if device has an ethernet network connection. + * TODO(b/77590489): Remove this method when DataUsageSummaryLegacy is deprecated. */ public boolean hasEthernet(Context context) { if (DataUsageUtils.TEST_RADIOS) { diff --git a/src/com/android/settings/datausage/DataUsageSummary.java b/src/com/android/settings/datausage/DataUsageSummary.java index b0877872b2..02e626888a 100644 --- a/src/com/android/settings/datausage/DataUsageSummary.java +++ b/src/com/android/settings/datausage/DataUsageSummary.java @@ -14,6 +14,7 @@ package com.android.settings.datausage; +import android.util.Log; import android.app.Activity; import android.content.ComponentName; import android.content.Context; @@ -87,8 +88,7 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); - - final Context context = getContext(); + Context context = getContext(); boolean hasMobileData = DataUsageUtils.hasMobileData(context); @@ -102,18 +102,21 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable if (!hasMobileData || !isAdmin()) { removePreference(KEY_RESTRICT_BACKGROUND); } + boolean hasWifiRadio = DataUsageUtils.hasWifiRadio(context); if (hasMobileData) { - SubscriptionInfo subInfo - = services.mSubscriptionManager.getDefaultDataSubscriptionInfo(); - if (subInfo != null) { - addMobileSection(subInfo.getSubscriptionId()); + addMobileSection(defaultSubId); + if (DataUsageUtils.hasSim(context) && hasWifiRadio) { + // If the device has a SIM installed, the data usage section shows usage for mobile, + // and the WiFi section is added if there is a WiFi radio - legacy behavior. + addWifiSection(); } - } - boolean hasWifiRadio = DataUsageUtils.hasWifiRadio(context); - if (hasWifiRadio) { + // Do not add the WiFi section if either there is no WiFi radio (obviously) or if no + // SIM is installed. In the latter case the data usage section will show WiFi usage and + // there should be no explicit WiFi section added. + } else if (hasWifiRadio) { addWifiSection(); } - if (hasEthernet(context)) { + if (DataUsageUtils.hasEthernet(context)) { addEthernetSection(); } setHasOptionsMenu(true); @@ -163,7 +166,8 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable return controllers; } - private void addMobileSection(int subId) { + @VisibleForTesting + void addMobileSection(int subId) { addMobileSection(subId, null); } @@ -178,7 +182,8 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable } } - private void addWifiSection() { + @VisibleForTesting + void addWifiSection() { TemplatePreferenceCategory category = (TemplatePreferenceCategory) inflatePreferences(R.xml.data_usage_wifi); category.setTemplate(NetworkTemplate.buildTemplateWifiWildcard(), 0, services); @@ -291,17 +296,25 @@ public class DataUsageSummary extends DataUsageBaseFragment implements Indexable @Override public void setListening(boolean listening) { if (listening) { - TelephonyManager telephonyManager = (TelephonyManager) mActivity - .getSystemService(Context.TELEPHONY_SERVICE); - final int simState = telephonyManager.getSimState(); - // Note that pulling the SIM card returns UNKNOWN, not ABSENT. - if (simState == TelephonyManager.SIM_STATE_ABSENT - || simState == TelephonyManager.SIM_STATE_UNKNOWN) { - mSummaryLoader.setSummary(this, null); - } else { + if (DataUsageUtils.hasSim(mActivity)) { mSummaryLoader.setSummary(this, mActivity.getString(R.string.data_usage_summary_format, formatUsedData())); + } else { + final DataUsageController.DataUsageInfo info = + mDataController + .getDataUsageInfo(NetworkTemplate.buildTemplateWifiWildcard()); + + if (info == null) { + mSummaryLoader.setSummary(this, null); + } else { + final CharSequence wifiFormat = mActivity + .getText(R.string.data_usage_wifi_format); + final CharSequence sizeText = + Formatter.formatFileSize(mActivity, info.usageLevel); + mSummaryLoader.setSummary(this, + TextUtils.expandTemplate(wifiFormat, sizeText)); + } } } } diff --git a/src/com/android/settings/datausage/DataUsageSummaryPreference.java b/src/com/android/settings/datausage/DataUsageSummaryPreference.java index 1e90282d1b..8fee1b43d7 100644 --- a/src/com/android/settings/datausage/DataUsageSummaryPreference.java +++ b/src/com/android/settings/datausage/DataUsageSummaryPreference.java @@ -20,6 +20,8 @@ import android.annotation.AttrRes; import android.content.Context; import android.content.Intent; import android.graphics.Typeface; +import android.net.NetworkTemplate; +import android.os.Bundle; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceViewHolder; import android.text.Spannable; @@ -34,7 +36,10 @@ import android.widget.ProgressBar; import android.widget.TextView; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; +import com.android.settings.core.SubSettingLauncher; +import com.android.settingslib.AppItem; import com.android.settingslib.Utils; import com.android.settingslib.utils.StringUtil; @@ -83,6 +88,10 @@ public class DataUsageSummaryPreference extends Preference { /** The number of bytes used since the start of the cycle. */ private long mDataplanUse; + /** WiFi only mode */ + private boolean mWifiMode; + private String mUsagePeriod; + public DataUsageSummaryPreference(Context context, AttributeSet attrs) { super(context, attrs); setLayoutResource(R.layout.data_usage_summary_preference); @@ -130,6 +139,12 @@ public class DataUsageSummaryPreference extends Preference { notifyChanged(); } + void setWifiMode(boolean isWifiMode, String usagePeriod) { + mWifiMode = isWifiMode; + mUsagePeriod = usagePeriod; + notifyChanged(); + } + @Override public void onBindViewHolder(PreferenceViewHolder holder) { super.onBindViewHolder(holder); @@ -149,28 +164,52 @@ public class DataUsageSummaryPreference extends Preference { updateDataUsageLabels(holder); TextView usageTitle = (TextView) holder.findViewById(R.id.usage_title); - usageTitle.setVisibility(mNumPlans > 1 ? View.VISIBLE : View.GONE); - - updateCycleTimeText(holder); - + TextView carrierInfo = (TextView) holder.findViewById(R.id.carrier_and_update); + Button launchButton = (Button) holder.findViewById(R.id.launch_mdp_app_button); + TextView limitInfo = (TextView) holder.findViewById(R.id.data_limits); - updateCarrierInfo((TextView) holder.findViewById(R.id.carrier_and_update)); + if (mWifiMode) { + usageTitle.setText(R.string.data_usage_wifi_title); + usageTitle.setVisibility(View.VISIBLE); + TextView cycleTime = (TextView) holder.findViewById(R.id.cycle_left_time); + cycleTime.setText(mUsagePeriod); + carrierInfo.setVisibility(View.GONE); + limitInfo.setVisibility(View.GONE); - Button launchButton = (Button) holder.findViewById(R.id.launch_mdp_app_button); - launchButton.setOnClickListener((view) -> { - getContext().sendBroadcast(mLaunchIntent); - }); - if (mLaunchIntent != null) { + launchButton.setOnClickListener((view) -> { + launchWifiDataUsage(getContext()); + }); + launchButton.setText(R.string.launch_wifi_text); launchButton.setVisibility(View.VISIBLE); } else { - launchButton.setVisibility(View.GONE); + usageTitle.setVisibility(mNumPlans > 1 ? View.VISIBLE : View.GONE); + updateCycleTimeText(holder); + updateCarrierInfo(carrierInfo); + if (mLaunchIntent != null) { + launchButton.setOnClickListener((view) -> { + getContext().sendBroadcast(mLaunchIntent); + }); + launchButton.setVisibility(View.VISIBLE); + } else { + launchButton.setVisibility(View.GONE); + } + limitInfo.setVisibility( + TextUtils.isEmpty(mLimitInfoText) ? View.GONE : View.VISIBLE); + limitInfo.setText(mLimitInfoText); } - - TextView limitInfo = (TextView) holder.findViewById(R.id.data_limits); - limitInfo.setVisibility(TextUtils.isEmpty(mLimitInfoText) ? View.GONE : View.VISIBLE); - limitInfo.setText(mLimitInfoText); } + private static void launchWifiDataUsage(Context context) { + final Bundle args = new Bundle(1); + args.putParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE, + NetworkTemplate.buildTemplateWifiWildcard()); + final SubSettingLauncher launcher = new SubSettingLauncher(context) + .setArguments(args) + .setDestination(DataUsageList.class.getName()) + .setSourceMetricsCategory(MetricsProto.MetricsEvent.VIEW_UNKNOWN); + launcher.setTitle(context.getString(R.string.wifi_data_usage)); + launcher.launch(); + } private void updateDataUsageLabels(PreferenceViewHolder holder) { TextView usageNumberField = (TextView) holder.findViewById(R.id.data_usage_view); diff --git a/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java b/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java index 55e7392966..752d6fa088 100644 --- a/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java +++ b/src/com/android/settings/datausage/DataUsageSummaryPreferenceController.java @@ -27,6 +27,7 @@ import android.support.v7.preference.Preference; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.SubscriptionPlan; +import android.telephony.TelephonyManager; import android.text.BidiFormatter; import android.text.Spannable; import android.text.SpannableString; @@ -183,17 +184,35 @@ public class DataUsageSummaryPreferenceController extends BasePreferenceControll @Override public int getAvailabilityStatus() { - return mSubscriptionManager.getDefaultDataSubscriptionInfo() != null - ? AVAILABLE : DISABLED_UNSUPPORTED; + return DataUsageUtils.hasSim(mActivity) + || DataUsageUtils.hasWifiRadio(mContext) ? AVAILABLE : DISABLED_UNSUPPORTED; } @Override public void updateState(Preference preference) { DataUsageSummaryPreference summaryPreference = (DataUsageSummaryPreference) preference; - DataUsageController.DataUsageInfo info = mDataUsageController.getDataUsageInfo( - mDefaultTemplate); - mDataInfoController.updateDataLimit(info, mPolicyEditor.getPolicy(mDefaultTemplate)); + final DataUsageController.DataUsageInfo info; + if (DataUsageUtils.hasSim(mActivity)) { + info = mDataUsageController.getDataUsageInfo(mDefaultTemplate); + mDataInfoController.updateDataLimit(info, mPolicyEditor.getPolicy(mDefaultTemplate)); + summaryPreference.setWifiMode(/* isWifiMode */ false, /* usagePeriod */ null); + } else { + info = mDataUsageController.getDataUsageInfo( + NetworkTemplate.buildTemplateWifiWildcard()); + summaryPreference.setWifiMode(/* isWifiMode */ true, /* usagePeriod */ info.period); + summaryPreference.setLimitInfo(null); + summaryPreference.setUsageNumbers(info.usageLevel, + /* dataPlanSize */ -1L, + /* hasMobileData */ true); + summaryPreference.setChartEnabled(false); + summaryPreference.setUsageInfo(info.cycleEnd, + /* snapshotTime */ -1L, + /* carrierName */ null, + /* numPlans */ 0, + /* launchIntent */ null); + return; + } if (mSubscriptionManager != null) { refreshDataplanInfo(info); diff --git a/src/com/android/settings/datausage/DataUsageUtils.java b/src/com/android/settings/datausage/DataUsageUtils.java index af2d257b4b..9c830470a7 100644 --- a/src/com/android/settings/datausage/DataUsageUtils.java +++ b/src/com/android/settings/datausage/DataUsageUtils.java @@ -14,11 +14,17 @@ package com.android.settings.datausage; +import static android.net.ConnectivityManager.TYPE_ETHERNET; import static android.net.ConnectivityManager.TYPE_WIFI; import android.content.Context; import android.net.ConnectivityManager; +import android.net.INetworkStatsService; +import android.net.INetworkStatsSession; import android.net.NetworkTemplate; +import android.net.TrafficStats; +import android.os.RemoteException; +import android.os.ServiceManager; import android.os.SystemProperties; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; @@ -31,11 +37,45 @@ import java.util.List; public final class DataUsageUtils { static final boolean TEST_RADIOS = false; static final String TEST_RADIOS_PROP = "test.radios"; + private static final String ETHERNET = "ethernet"; private DataUsageUtils() { } /** + * Test if device has an ethernet network connection. + */ + public static boolean hasEthernet(Context context) { + if (DataUsageUtils.TEST_RADIOS) { + return SystemProperties.get(DataUsageUtils.TEST_RADIOS_PROP).contains(ETHERNET); + } + + final ConnectivityManager conn = ConnectivityManager.from(context); + final boolean hasEthernet = conn.isNetworkSupported(ConnectivityManager.TYPE_ETHERNET); + + final long ethernetBytes; + try { + INetworkStatsService statsService = INetworkStatsService.Stub.asInterface( + ServiceManager.getService(Context.NETWORK_STATS_SERVICE)); + + INetworkStatsSession statsSession = statsService.openSession(); + if (statsSession != null) { + ethernetBytes = statsSession.getSummaryForNetwork( + NetworkTemplate.buildTemplateEthernet(), Long.MIN_VALUE, Long.MAX_VALUE) + .getTotalBytes(); + TrafficStats.closeQuietly(statsSession); + } else { + ethernetBytes = 0; + } + } catch (RemoteException e) { + throw new RuntimeException(e); + } + + // only show ethernet when both hardware present and traffic has occurred + return hasEthernet && ethernetBytes > 0; + } + + /** * Returns whether device has mobile data. * TODO: This is the opposite to Utils.isWifiOnly(), it should be refactored into 1 method. */ @@ -53,10 +93,19 @@ public final class DataUsageUtils { return SystemProperties.get(TEST_RADIOS_PROP).contains("wifi"); } - ConnectivityManager connectivityManager = ConnectivityManager.from(context); + ConnectivityManager connectivityManager = + context.getSystemService(ConnectivityManager.class); return connectivityManager != null && connectivityManager.isNetworkSupported(TYPE_WIFI); } + public static boolean hasSim(Context context) { + TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class); + final int simState = telephonyManager.getSimState(); + // Note that pulling the SIM card returns UNKNOWN, not ABSENT. + return simState != TelephonyManager.SIM_STATE_ABSENT + && simState != TelephonyManager.SIM_STATE_UNKNOWN; + } + /** * Returns the default subscription if available else returns * SubscriptionManager#INVALID_SUBSCRIPTION_ID diff --git a/tests/robotests/src/com/android/settings/LegalSettingsTest.java b/tests/robotests/src/com/android/settings/LegalSettingsTest.java index 72c6fa14fd..af0b757a18 100644 --- a/tests/robotests/src/com/android/settings/LegalSettingsTest.java +++ b/tests/robotests/src/com/android/settings/LegalSettingsTest.java @@ -45,7 +45,7 @@ public class LegalSettingsTest { mContext = spy(RuntimeEnvironment.application); mFragment = new LegalSettings() { @Override - protected boolean removePreference(String key) { + public boolean removePreference(String key) { if (LegalSettings.KEY_WALLPAPER_ATTRIBUTIONS.equals(key)) { mWallpaperRemoved = true; diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.java index 9a38305741..a616102100 100644 --- a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceControllerTest.java @@ -16,6 +16,7 @@ package com.android.settings.datausage; +import static android.net.ConnectivityManager.TYPE_WIFI; import static com.android.settings.core.BasePreferenceController.AVAILABLE; import static com.android.settings.core.BasePreferenceController.DISABLED_UNSUPPORTED; import static com.google.common.truth.Truth.assertThat; @@ -28,9 +29,11 @@ import static org.mockito.Mockito.when; import android.app.Activity; import android.content.Context; import android.content.Intent; +import android.net.ConnectivityManager; import android.net.NetworkTemplate; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; import com.android.internal.logging.nano.MetricsProto; import com.android.settings.R; @@ -89,6 +92,10 @@ public class DataUsageSummaryPreferenceControllerTest { private EntityHeaderController mHeaderController; @Mock private DataUsageSummary mDataUsageSummary; + @Mock + private TelephonyManager mTelephonyManager; + @Mock + private ConnectivityManager mConnectivityManager; private FakeFeatureFactory mFactory; private Activity mActivity; @@ -103,12 +110,17 @@ public class DataUsageSummaryPreferenceControllerTest { doReturn("%1$s %2%s").when(mContext) .getString(com.android.internal.R.string.fileSizeSuffix); - mActivity = Robolectric.setupActivity(Activity.class); mFactory = FakeFeatureFactory.setupForTest(); when(mFactory.metricsFeatureProvider.getMetricsCategory(any(Object.class))) .thenReturn(MetricsProto.MetricsEvent.SETTINGS_APP_NOTIF_CATEGORY); ShadowEntityHeaderController.setUseMock(mHeaderController); + mActivity = spy(Robolectric.buildActivity(Activity.class).get()); + when(mActivity.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager); + when(mActivity.getSystemService(ConnectivityManager.class)) + .thenReturn(mConnectivityManager); + when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY); + when(mConnectivityManager.isNetworkSupported(TYPE_WIFI)).thenReturn(false); mController = new DataUsageSummaryPreferenceController( mDataUsageController, mDataInfoController, @@ -146,6 +158,7 @@ public class DataUsageSummaryPreferenceControllerTest { verify(mSummaryPreference).setUsageInfo(info.cycleEnd, now - UPDATE_BACKOFF_MS, CARRIER_NAME, 1 /* numPlans */, intent); verify(mSummaryPreference).setChartEnabled(true); + verify(mSummaryPreference).setWifiMode(false, null); } @Test @@ -169,6 +182,7 @@ public class DataUsageSummaryPreferenceControllerTest { verify(mSummaryPreference).setUsageInfo(info.cycleEnd, now - UPDATE_BACKOFF_MS, CARRIER_NAME, 0 /* numPlans */, intent); verify(mSummaryPreference).setChartEnabled(true); + verify(mSummaryPreference).setWifiMode(false, null); } @Test @@ -194,6 +208,7 @@ public class DataUsageSummaryPreferenceControllerTest { 0 /* numPlans */, null /* launchIntent */); verify(mSummaryPreference).setChartEnabled(true); + verify(mSummaryPreference).setWifiMode(false, null); } @Test @@ -220,6 +235,7 @@ public class DataUsageSummaryPreferenceControllerTest { 0 /* numPlans */, null /* launchIntent */); verify(mSummaryPreference).setChartEnabled(false); + verify(mSummaryPreference).setWifiMode(false, null); } @Test @@ -300,6 +316,30 @@ public class DataUsageSummaryPreferenceControllerTest { verify(mSummaryPreference).setLimitInfo(captor.capture()); CharSequence value = captor.getValue(); assertThat(value.toString()).isEqualTo("1.00 MB data warning / 1.00 MB data limit"); + verify(mSummaryPreference).setWifiMode(false, null); + } + + @Test + public void testSummaryUpdate_noSim_shouldSetWifiMode() { + final long now = System.currentTimeMillis(); + final DataUsageController.DataUsageInfo info = createTestDataUsageInfo(now); + info.warningLevel = 1000000L; + info.limitLevel = 1000000L; + + final Intent intent = new Intent(); + + when(mDataUsageController.getDataUsageInfo(any())).thenReturn(info); + mController.setPlanValues(0 /* dataPlanCount */, LIMIT1, USAGE1); + mController.setCarrierValues(CARRIER_NAME, now - UPDATE_BACKOFF_MS, info.cycleEnd, intent); + + when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_ABSENT); + mController.updateState(mSummaryPreference); + + verify(mSummaryPreference).setWifiMode(true, info.period); + verify(mSummaryPreference).setLimitInfo(null); + verify(mSummaryPreference).setUsageNumbers(info.usageLevel, -1L, true); + verify(mSummaryPreference).setChartEnabled(false); + verify(mSummaryPreference).setUsageInfo(info.cycleEnd, -1L, null, 0, null); } @Test @@ -321,7 +361,7 @@ public class DataUsageSummaryPreferenceControllerTest { } @Test - public void testMobileData_preferenceDisabled() { + public void testMobileData_noSimNoWifi_preferenceDisabled() { mController = new DataUsageSummaryPreferenceController( mDataUsageController, mDataInfoController, @@ -332,11 +372,29 @@ public class DataUsageSummaryPreferenceControllerTest { mSubscriptionManager, mActivity, null, null, null); - when(mSubscriptionManager.getDefaultDataSubscriptionInfo()).thenReturn(null); + when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_ABSENT); + when(mConnectivityManager.isNetworkSupported(TYPE_WIFI)).thenReturn(false); assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_UNSUPPORTED); } @Test + public void testMobileData_noSimWifi_preferenceDisabled() { + mController = new DataUsageSummaryPreferenceController( + mDataUsageController, + mDataInfoController, + mNetworkTemplate, + mPolicyEditor, + R.string.cell_data_template, + true, + mSubscriptionManager, + mActivity, null, null, null); + + when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_ABSENT); + when(mConnectivityManager.isNetworkSupported(TYPE_WIFI)).thenReturn(true); + assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); + } + + @Test public void testMobileData_entityHeaderSet() { final RecyclerView recyclerView = new RecyclerView(mActivity); diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceTest.java index 436ceaf74f..637c429632 100644 --- a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceTest.java +++ b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryPreferenceTest.java @@ -17,10 +17,16 @@ package com.android.settings.datausage; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.verify; +import android.app.Activity; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.graphics.Typeface; +import android.net.NetworkTemplate; +import android.os.Bundle; import android.support.v7.preference.PreferenceViewHolder; import android.view.LayoutInflater; import android.view.View; @@ -30,16 +36,23 @@ import android.widget.ProgressBar; import android.widget.TextView; import com.android.settings.R; +import com.android.settings.SettingsActivity; +import com.android.settings.SubSettings; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.SettingsShadowResourcesImpl; import com.android.settingslib.Utils; +import com.android.settingslib.core.instrumentation.VisibilityLoggerMixin; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.MockitoAnnotations; +import org.robolectric.Robolectric; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; +import org.robolectric.Shadows; +import org.robolectric.shadows.ShadowActivity; import java.util.concurrent.TimeUnit; @@ -389,6 +402,48 @@ public class DataUsageSummaryPreferenceTest { assertThat(mDataRemaining.getText()).isEqualTo(""); } + @Test + public void testSetWifiMode_withUsageInfo_dataUsageShown() { + final int daysLeft = 3; + final long cycleEnd = System.currentTimeMillis() + TimeUnit.DAYS.toMillis(daysLeft) + + TimeUnit.HOURS.toMillis(1); + final Activity activity = Robolectric.setupActivity(Activity.class); + mSummaryPreference.setUsageInfo(cycleEnd, mUpdateTime, DUMMY_CARRIER, 0 /* numPlans */, + new Intent()); + mSummaryPreference.setUsageNumbers(1000000L, -1L, true); + final String cycleText = "The quick fox"; + mSummaryPreference.setWifiMode(true, cycleText); + + bindViewHolder(); + assertThat(mUsageTitle.getText().toString()) + .isEqualTo(mContext.getString(R.string.data_usage_wifi_title)); + assertThat(mUsageTitle.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mCycleTime.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mCycleTime.getText()).isEqualTo(cycleText); + assertThat(mCarrierInfo.getVisibility()).isEqualTo(View.GONE); + assertThat(mDataLimits.getVisibility()).isEqualTo(View.GONE); + assertThat(mLaunchButton.getVisibility()).isEqualTo(View.VISIBLE); + assertThat(mLaunchButton.getText()) + .isEqualTo(mContext.getString(R.string.launch_wifi_text)); + + mLaunchButton.callOnClick(); + ShadowActivity shadowActivity = Shadows.shadowOf(activity); + Intent startedIntent = shadowActivity.getNextStartedActivity(); + assertThat(startedIntent.getComponent()).isEqualTo(new ComponentName("com.android.settings", + SubSettings.class.getName())); + + final Bundle expect = new Bundle(1); + expect.putParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE, + NetworkTemplate.buildTemplateWifiWildcard()); + final Bundle actual = startedIntent + .getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS); + assertThat((NetworkTemplate) actual.getParcelable(DataUsageList.EXTRA_NETWORK_TEMPLATE)) + .isEqualTo(NetworkTemplate.buildTemplateWifiWildcard()); + + assertThat(startedIntent.getCharSequenceExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_TITLE)) + .isEqualTo(mContext.getString(R.string.wifi_data_usage)); + } + private void bindViewHolder() { mSummaryPreference.onBindViewHolder(mHolder); mUsageTitle = (TextView) mHolder.findViewById(R.id.usage_title); diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java index d065c73606..a6ddec133e 100644 --- a/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java +++ b/tests/robotests/src/com/android/settings/datausage/DataUsageSummaryTest.java @@ -16,24 +16,19 @@ package com.android.settings.datausage; -import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyObject; -import static org.mockito.Matchers.endsWith; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - import android.app.Activity; import android.content.Context; -import android.net.ConnectivityManager; -import android.telephony.TelephonyManager; +import android.net.NetworkPolicyManager; +import android.os.Bundle; import android.text.format.Formatter; -import com.android.settings.R; import com.android.settings.dashboard.SummaryLoader; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.testutils.shadow.SettingsShadowResources; +import com.android.settings.testutils.shadow.SettingsShadowResourcesImpl; +import com.android.settings.testutils.shadow.ShadowDashboardFragment; +import com.android.settings.testutils.shadow.ShadowDataUsageUtils; +import com.android.settings.testutils.shadow.ShadowUtils; import org.junit.Before; import org.junit.Test; @@ -41,18 +36,35 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.robolectric.Robolectric; +import org.robolectric.annotation.Config; import org.robolectric.shadows.ShadowApplication; +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.endsWith; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +@Config(shadows = { + SettingsShadowResourcesImpl.class, + SettingsShadowResources.SettingsShadowTheme.class, + ShadowUtils.class, + ShadowDataUsageUtils.class, + ShadowDashboardFragment.class +}) @RunWith(SettingsRobolectricTestRunner.class) public class DataUsageSummaryTest { @Mock - private ConnectivityManager mManager; - private Context mContext; - @Mock - TelephonyManager mTelephonyManager; - @Mock private SummaryLoader mSummaryLoader; + @Mock + private NetworkPolicyManager mNetworkPolicyManager; + private Context mContext; private Activity mActivity; private SummaryLoader.SummaryProvider mSummaryProvider; @@ -65,12 +77,10 @@ public class DataUsageSummaryTest { public void setUp() { MockitoAnnotations.initMocks(this); ShadowApplication shadowContext = ShadowApplication.getInstance(); - shadowContext.setSystemService(Context.CONNECTIVITY_SERVICE, mManager); - mContext = shadowContext.getApplicationContext(); - when(mManager.isNetworkSupported(anyInt())).thenReturn(true); + shadowContext.setSystemService(Context.NETWORK_POLICY_SERVICE, mNetworkPolicyManager); + mContext = shadowContext.getApplicationContext(); mActivity = spy(Robolectric.buildActivity(Activity.class).get()); - when(mActivity.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager); mSummaryProvider = DataUsageSummary.SUMMARY_PROVIDER_FACTORY .createSummaryProvider(mActivity, mSummaryLoader); @@ -89,15 +99,73 @@ public class DataUsageSummaryTest { @Test public void setListening_shouldBlankSummaryWithNoSim() { - when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_ABSENT); + ShadowDataUsageUtils.HAS_SIM = false; mSummaryProvider.setListening(true); verify(mSummaryLoader).setSummary(mSummaryProvider, null); } @Test public void setListening_shouldSetSummaryWithSim() { - when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY); + ShadowDataUsageUtils.HAS_SIM = true; mSummaryProvider.setListening(true); verify(mSummaryLoader).setSummary(anyObject(), endsWith(" of data used")); } + + @Test + public void configuration_withSim_shouldShowMobileAndWifi() { + ShadowDataUsageUtils.IS_MOBILE_DATA_SUPPORTED = true; + ShadowDataUsageUtils.IS_WIFI_SUPPORTED = true; + ShadowDataUsageUtils.DEFAULT_SUBSCRIPTION_ID = 1; + ShadowDataUsageUtils.HAS_SIM = true; + + final DataUsageSummary dataUsageSummary = spy(new DataUsageSummary()); + doReturn(mContext).when(dataUsageSummary).getContext(); + + doReturn(true).when(dataUsageSummary).removePreference(anyString()); + doNothing().when(dataUsageSummary).addWifiSection(); + doNothing().when(dataUsageSummary).addMobileSection(1); + + dataUsageSummary.onCreate(null); + + verify(dataUsageSummary).addWifiSection(); + verify(dataUsageSummary).addMobileSection(anyInt()); + } + + @Test + public void configuration_withoutSim_shouldShowWifiSectionOnly() { + ShadowDataUsageUtils.IS_MOBILE_DATA_SUPPORTED = true; + ShadowDataUsageUtils.IS_WIFI_SUPPORTED = true; + ShadowDataUsageUtils.HAS_SIM = false; + + final DataUsageSummary dataUsageSummary = spy(new DataUsageSummary()); + doReturn(mContext).when(dataUsageSummary).getContext(); + + doReturn(true).when(dataUsageSummary).removePreference(anyString()); + doNothing().when(dataUsageSummary).addWifiSection(); + doNothing().when(dataUsageSummary).addMobileSection(1); + + dataUsageSummary.onCreate(null); + + verify(dataUsageSummary).addWifiSection(); + verify(dataUsageSummary, never()).addMobileSection(anyInt()); + } + + @Test + public void configuration_withoutMobile_shouldShowWifiSectionOnly() { + ShadowDataUsageUtils.IS_MOBILE_DATA_SUPPORTED = false; + ShadowDataUsageUtils.IS_WIFI_SUPPORTED = true; + ShadowDataUsageUtils.HAS_SIM = false; + + final DataUsageSummary dataUsageSummary = spy(new DataUsageSummary()); + doReturn(mContext).when(dataUsageSummary).getContext(); + + doReturn(true).when(dataUsageSummary).removePreference(anyString()); + doNothing().when(dataUsageSummary).addWifiSection(); + doNothing().when(dataUsageSummary).addMobileSection(1); + + dataUsageSummary.onCreate(null); + + verify(dataUsageSummary).addWifiSection(); + verify(dataUsageSummary, never()).addMobileSection(anyInt()); + } } diff --git a/tests/robotests/src/com/android/settings/datausage/DataUsageUtilsTest.java b/tests/robotests/src/com/android/settings/datausage/DataUsageUtilsTest.java index b988a6ee38..d59a4a864f 100644 --- a/tests/robotests/src/com/android/settings/datausage/DataUsageUtilsTest.java +++ b/tests/robotests/src/com/android/settings/datausage/DataUsageUtilsTest.java @@ -22,6 +22,7 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.net.ConnectivityManager; +import android.telephony.TelephonyManager; import com.android.settings.testutils.SettingsRobolectricTestRunner; @@ -37,6 +38,8 @@ public final class DataUsageUtilsTest { @Mock private ConnectivityManager mManager; + @Mock + private TelephonyManager mTelephonyManager; private Context mContext; @Before @@ -45,6 +48,7 @@ public final class DataUsageUtilsTest { ShadowApplication shadowContext = ShadowApplication.getInstance(); mContext = shadowContext.getApplicationContext(); shadowContext.setSystemService(Context.CONNECTIVITY_SERVICE, mManager); + shadowContext.setSystemService(Context.TELEPHONY_SERVICE, mTelephonyManager); } @Test @@ -60,4 +64,18 @@ public final class DataUsageUtilsTest { boolean hasMobileData = DataUsageUtils.hasMobileData(mContext); assertThat(hasMobileData).isFalse(); } + + @Test + public void hasSim_simStateReady() { + when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_READY); + boolean hasSim = DataUsageUtils.hasSim(mContext); + assertThat(hasSim).isTrue(); + } + + @Test + public void hasSim_simStateMissing() { + when(mTelephonyManager.getSimState()).thenReturn(TelephonyManager.SIM_STATE_ABSENT); + boolean hasSim = DataUsageUtils.hasSim(mContext); + assertThat(hasSim).isFalse(); + } } diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDataUsageUtils.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDataUsageUtils.java index fecceb6b90..73cabfb159 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDataUsageUtils.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDataUsageUtils.java @@ -1,6 +1,7 @@ package com.android.settings.testutils.shadow; import android.content.Context; +import android.telephony.SubscriptionManager; import com.android.settings.datausage.DataUsageUtils; import org.robolectric.annotation.Implementation; @@ -11,6 +12,8 @@ public class ShadowDataUsageUtils { public static boolean IS_MOBILE_DATA_SUPPORTED = true; public static boolean IS_WIFI_SUPPORTED = true; + public static boolean HAS_SIM = true; + public static int DEFAULT_SUBSCRIPTION_ID = SubscriptionManager.INVALID_SUBSCRIPTION_ID; @Implementation public static boolean hasMobileData(Context context) { @@ -21,4 +24,17 @@ public class ShadowDataUsageUtils { public static boolean hasWifiRadio(Context context) { return IS_WIFI_SUPPORTED; } + + @Implementation + public static int getDefaultSubscriptionId(Context context) { + return DEFAULT_SUBSCRIPTION_ID; + } + + @Implementation + public static boolean hasSim(Context context) { + return HAS_SIM; + } + + @Implementation + public static boolean hasEthernet(Context context) { return false; } }