diff --git a/res/drawable/ic_signal_strength_zero_bar_no_internet.xml b/res/drawable/ic_signal_strength_zero_bar_no_internet.xml new file mode 100644 index 00000000000..f38a36804bc --- /dev/null +++ b/res/drawable/ic_signal_strength_zero_bar_no_internet.xml @@ -0,0 +1,34 @@ + + + + + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index f465115acf5..352879306b5 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -12527,6 +12527,15 @@ Turn off Airplane Mode + + Active, %1$s + + Internet off + + Non\u2011carrier networks unavailable + + Networks unavailable + Unavailable because bedtime mode is on diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java index 4390aad2512..eca38693998 100644 --- a/src/com/android/settings/Utils.java +++ b/src/com/android/settings/Utils.java @@ -1156,5 +1156,4 @@ public final class Utils extends com.android.settingslib.Utils { public static boolean isProviderModelEnabled(Context context) { return FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL); } - } diff --git a/src/com/android/settings/network/ProviderModelSliceHelper.java b/src/com/android/settings/network/ProviderModelSliceHelper.java new file mode 100644 index 00000000000..482695a8db6 --- /dev/null +++ b/src/com/android/settings/network/ProviderModelSliceHelper.java @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.settings.network; + +import static com.android.settings.network.telephony.MobileNetworkUtils.NO_CELL_DATA_TYPE_ICON; + +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.net.Uri; +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 androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; +import androidx.core.graphics.drawable.IconCompat; +import androidx.slice.builders.GridRowBuilder; +import androidx.slice.builders.ListBuilder; +import androidx.slice.builders.SliceAction; + +import com.android.settings.R; +import com.android.settings.Utils; +import com.android.settings.network.telephony.MobileNetworkUtils; +import com.android.settings.slices.CustomSliceable; +import com.android.settings.wifi.slice.WifiSliceItem; +import com.android.settingslib.WirelessUtils; +import com.android.settingslib.net.SignalStrengthUtil; +import com.android.settingslib.utils.ThreadUtils; +import com.android.wifitrackerlib.WifiEntry; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.Semaphore; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collectors; + +/** + * The helper is for slice of carrier and non-Carrier, used by ProviderModelSlice. + */ +public class ProviderModelSliceHelper { + private static final String TAG = "ProviderModelSlice"; + private final SubscriptionManager mSubscriptionManager; + private final TelephonyManager mTelephonyManager; + protected final Context mContext; + private CustomSliceable mSliceable; + + public ProviderModelSliceHelper(Context context, CustomSliceable sliceable) { + mContext = context; + mSliceable = sliceable; + mSubscriptionManager = context.getSystemService(SubscriptionManager.class); + mTelephonyManager = context.getSystemService(TelephonyManager.class); + } + + private static void log(String s) { + Log.d(TAG, s); + } + + protected ListBuilder.HeaderBuilder createHeader() { + return new ListBuilder.HeaderBuilder() + .setTitle(mContext.getText(R.string.summary_placeholder)) + .setPrimaryAction(getPrimarySliceAction()); + } + + protected ListBuilder createListBuilder(Uri uri) { + final ListBuilder builder = new ListBuilder(mContext, uri, ListBuilder.INFINITY) + .setAccentColor(-1) + .setKeywords(getKeywords()); + return builder; + } + + protected GridRowBuilder createMessageGridRow(int messageResId) { + final CharSequence title = mContext.getText(messageResId); + return new GridRowBuilder() + // Add cells to the grid row. + .addCell(new GridRowBuilder.CellBuilder().addTitleText(title)) + .setPrimaryAction(getPrimarySliceAction()); + } + + @Nullable + protected WifiSliceItem getConnectedWifiItem(List wifiList) { + if (wifiList == null) { + return null; + } + Optional item = wifiList.stream() + .filter(x -> x.getConnectedState() == WifiEntry.CONNECTED_STATE_CONNECTED) + .findFirst(); + return item.isPresent() ? item.get() : null; + } + + protected boolean hasCarrier() { + if (isAirplaneModeEnabled() + || mSubscriptionManager == null || mTelephonyManager == null + || mSubscriptionManager.getDefaultDataSubscriptionId() + == mSubscriptionManager.INVALID_SUBSCRIPTION_ID) { + return false; + } + return true; + } + + protected ListBuilder.RowBuilder createCarrierRow() { + final String title = getMobileTitle(); + final String summary = getMobileSummary(); + Drawable drawable = mContext.getDrawable( + R.drawable.ic_signal_strength_zero_bar_no_internet); + try { + drawable = getMobileDrawable(drawable); + } catch (Throwable e) { + e.printStackTrace(); + } + final IconCompat levelIcon = Utils.createIconWithDrawable(drawable); + final PendingIntent toggleAction = mSliceable.getBroadcastIntent(mContext); + final SliceAction toggleSliceAction = SliceAction.createToggle(toggleAction, + "mobile_toggle" /* actionTitle */, isMobileDataEnabled()); + final ListBuilder.RowBuilder rowBuilder = new ListBuilder.RowBuilder() + .setTitle(title) + .setTitleItem(levelIcon, ListBuilder.ICON_IMAGE) + .addEndItem(toggleSliceAction) + .setPrimaryAction(toggleSliceAction) + .setSubtitle(summary); + return rowBuilder; + } + + protected SliceAction getPrimarySliceAction() { + return SliceAction.createDeeplink( + getPrimaryAction(), + Utils.createIconWithDrawable(new ColorDrawable(Color.TRANSPARENT)), + ListBuilder.ICON_IMAGE, mContext.getText(R.string.summary_placeholder)); + } + + private PendingIntent getPrimaryAction() { + final Intent intent = new Intent("android.settings.NETWORK_PROVIDER_SETTINGS") + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + return PendingIntent.getActivity(mContext, 0 /* requestCode */, + intent, PendingIntent.FLAG_IMMUTABLE /* flags */); + } + + private boolean shouldInflateSignalStrength(int subId) { + return SignalStrengthUtil.shouldInflateSignalStrength(mContext, subId); + } + + protected boolean isAirplaneModeEnabled() { + return WirelessUtils.isAirplaneModeOn(mContext); + } + + protected boolean isMobileDataEnabled() { + if (mTelephonyManager == null) { + return false; + } + return mTelephonyManager.isDataEnabled(); + } + + protected boolean isDataSimActive() { + return MobileNetworkUtils.activeNetworkIsCellular(mContext); + } + + protected boolean isNoCarrierData() { + if (mTelephonyManager == null) { + return false; + } + boolean mobileDataOnAndNoData = isMobileDataEnabled() + && mTelephonyManager.getDataState() != mTelephonyManager.DATA_CONNECTED; + ServiceState serviceState = mTelephonyManager.getServiceState(); + boolean mobileDataOffAndOutOfService = !isMobileDataEnabled() && serviceState != null + && serviceState.getState() == serviceState.STATE_OUT_OF_SERVICE; + log("mobileDataOnAndNoData: " + mobileDataOnAndNoData + + ",mobileDataOffAndOutOfService: " + mobileDataOffAndOutOfService); + return mobileDataOnAndNoData || mobileDataOffAndOutOfService; + } + + private boolean isAirplaneSafeNetworksModeEnabled() { + // TODO: isAirplaneSafeNetworksModeEnabled is not READY + return false; + } + + @VisibleForTesting + Drawable getMobileDrawable(Drawable drawable) throws Throwable { + // set color and drawable + if (mTelephonyManager == null) { + log("mTelephonyManager == null"); + return drawable; + } + if (!isNoCarrierData()) { + Semaphore lock = new Semaphore(0); + AtomicReference shared = new AtomicReference<>(); + ThreadUtils.postOnMainThread(() -> { + shared.set(getDrawableWithSignalStrength()); + lock.release(); + }); + lock.acquire(); + drawable = shared.get(); + } + + if (isDataSimActive()) { + drawable.setTint(Utils.getColorAccentDefaultColor(mContext)); + } + return drawable; + } + + /** + * To get the signal bar icon with level. + * + * @return The Drawable which is a signal bar icon with level. + */ + public Drawable getDrawableWithSignalStrength() { + final SignalStrength strength = mTelephonyManager.getSignalStrength(); + int level = (strength == null) ? 0 : strength.getLevel(); + int numLevels = SignalStrength.NUM_SIGNAL_STRENGTH_BINS; + if (mSubscriptionManager != null && shouldInflateSignalStrength( + mSubscriptionManager.getDefaultDataSubscriptionId())) { + level += 1; + numLevels += 1; + } + return MobileNetworkUtils.getSignalStrengthIcon(mContext, level, numLevels, + NO_CELL_DATA_TYPE_ICON, false); + } + + private String getMobileSummary() { + String summary = ""; + //TODO: get radio technology. + String networkType = ""; + if (isDataSimActive()) { + summary = mContext.getString(R.string.mobile_data_connection_active, networkType); + } else if (!isMobileDataEnabled()) { + summary = mContext.getString(R.string.mobile_data_off_summary); + } + return summary; + } + + private String getMobileTitle() { + String title = mContext.getText(R.string.mobile_data_settings_title).toString(); + if (mSubscriptionManager == null) { + return title; + } + final SubscriptionInfo defaultSubscription = mSubscriptionManager.getActiveSubscriptionInfo( + mSubscriptionManager.getDefaultDataSubscriptionId()); + if (defaultSubscription != null) { + title = defaultSubscription.getDisplayName().toString(); + } + return title; + } + + protected SubscriptionManager getSubscriptionManager() { + return mSubscriptionManager; + } + + private Set getKeywords() { + final String keywords = mContext.getString(R.string.keywords_internet); + return Arrays.stream(TextUtils.split(keywords, ",")) + .map(String::trim) + .collect(Collectors.toSet()); + } +} diff --git a/src/com/android/settings/wifi/slice/WifiSlice.java b/src/com/android/settings/wifi/slice/WifiSlice.java index 7d009f4f11a..56d87c34b29 100644 --- a/src/com/android/settings/wifi/slice/WifiSlice.java +++ b/src/com/android/settings/wifi/slice/WifiSlice.java @@ -147,7 +147,7 @@ public class WifiSlice implements CustomSliceable { return builder; } - private ListBuilder.RowBuilder getWifiSliceItemRow(WifiSliceItem wifiSliceItem) { + protected ListBuilder.RowBuilder getWifiSliceItemRow(WifiSliceItem wifiSliceItem) { final CharSequence title = wifiSliceItem.getTitle(); final IconCompat levelIcon = getWifiSliceItemLevelIcon(wifiSliceItem); final ListBuilder.RowBuilder rowBuilder = new ListBuilder.RowBuilder() diff --git a/tests/unit/src/com/android/settings/network/ProviderModelSliceHelperTest.java b/tests/unit/src/com/android/settings/network/ProviderModelSliceHelperTest.java new file mode 100644 index 00000000000..abbc2ec7923 --- /dev/null +++ b/tests/unit/src/com/android/settings/network/ProviderModelSliceHelperTest.java @@ -0,0 +1,307 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.network; + +import static com.google.common.truth.Truth.assertThat; + +import static junit.framework.Assert.assertEquals; + +import static org.mockito.ArgumentMatchers.anyInt; +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.content.Context; +import android.content.Intent; +import android.graphics.drawable.Drawable; +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.Uri; +import android.os.PersistableBundle; +import android.telephony.CarrierConfigManager; +import android.telephony.ServiceState; +import android.telephony.SubscriptionInfo; +import android.telephony.SubscriptionManager; +import android.telephony.TelephonyManager; + +import androidx.slice.Slice; +import androidx.slice.builders.GridRowBuilder; +import androidx.slice.builders.GridRowBuilder.CellBuilder; +import androidx.slice.builders.ListBuilder; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import com.android.settings.Utils; +import com.android.settings.slices.CustomSliceable; +import com.android.settings.testutils.ResourcesUtils; +import com.android.settings.wifi.slice.WifiSliceItem; +import com.android.wifitrackerlib.WifiEntry; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.ArrayList; +import java.util.List; + +@RunWith(AndroidJUnit4.class) +public class ProviderModelSliceHelperTest { + private Context mContext; + private MockProviderModelSliceHelper mProviderModelSliceHelper; + private PersistableBundle mBundle; + private Network mNetwork; + private NetworkCapabilities mNetworkCapabilities; + + @Mock + private SubscriptionManager mSubscriptionManager; + @Mock + private CarrierConfigManager mCarrierConfigManager; + @Mock + private ConnectivityManager mConnectivityManager; + @Mock + private TelephonyManager mTelephonyManager; + @Mock + private ServiceState mServiceState; + @Mock + private WifiSliceItem mWifiSliceItem1; + @Mock + private WifiSliceItem mWifiSliceItem2; + @Mock + private SubscriptionInfo mDefaultDataSubscriptionInfo; + @Mock + private Drawable mDrawableWithSignalStrength; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = spy(ApplicationProvider.getApplicationContext()); + mBundle = new PersistableBundle(); + mNetwork = new Network(anyInt()); + + when(mContext.getSystemService(SubscriptionManager.class)).thenReturn(mSubscriptionManager); + when(mContext.getSystemService(CarrierConfigManager.class)).thenReturn( + mCarrierConfigManager); + when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(mBundle); + when(mContext.getSystemService(ConnectivityManager.class)).thenReturn(mConnectivityManager); + when(mConnectivityManager.getActiveNetwork()).thenReturn(mNetwork); + when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager); + when(mTelephonyManager.createForSubscriptionId(anyInt())).thenReturn(mTelephonyManager); + + TestCustomSliceable testCustomSliceable = new TestCustomSliceable(); + mProviderModelSliceHelper = new MockProviderModelSliceHelper(mContext, testCustomSliceable); + } + + @Test + public void createMessageGridRow_inputTheResourceId_verifyTitle() { + int messageResId = ResourcesUtils.getResourcesId(mContext, "string", + "non_carrier_network_unavailable"); + CharSequence title = ResourcesUtils.getResourcesString(mContext, + "non_carrier_network_unavailable"); + + GridRowBuilder testGridRow = mProviderModelSliceHelper.createMessageGridRow(messageResId); + List cellItem = testGridRow.getCells(); + + assertThat(cellItem.get(0).getTitle()).isEqualTo(title); + } + + @Test + public void getConnectedWifiItem_inputListInvolveOneConnectedWifiItem_verifyReturnItem() { + when(mWifiSliceItem1.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_CONNECTED); + when(mWifiSliceItem2.getConnectedState()).thenReturn( + WifiEntry.CONNECTED_STATE_DISCONNECTED); + List wifiList = new ArrayList<>(); + wifiList.add(mWifiSliceItem1); + wifiList.add(mWifiSliceItem2); + + WifiSliceItem testItem = mProviderModelSliceHelper.getConnectedWifiItem(wifiList); + + assertThat(testItem).isNotNull(); + assertEquals(mWifiSliceItem1, testItem); + } + + @Test + public void getConnectedWifiItem_inputListInvolveNoConnectedWifiItem_verifyReturnItem() { + when(mWifiSliceItem1.getConnectedState()).thenReturn( + WifiEntry.CONNECTED_STATE_DISCONNECTED); + when(mWifiSliceItem2.getConnectedState()).thenReturn( + WifiEntry.CONNECTED_STATE_DISCONNECTED); + List wifiList = new ArrayList<>(); + wifiList.add(mWifiSliceItem1); + wifiList.add(mWifiSliceItem2); + + WifiSliceItem testItem = mProviderModelSliceHelper.getConnectedWifiItem(wifiList); + + assertThat(testItem).isNull(); + } + + @Test + public void getConnectedWifiItem_inputNull_verifyReturnItem() { + List wifiList = null; + + WifiSliceItem testItem = mProviderModelSliceHelper.getConnectedWifiItem(wifiList); + + assertThat(testItem).isNull(); + } + + @Test + public void createCarrierRow_hasDefaultDataSubscriptionId_verifyTitle() { + String expectDisplayName = "Name1"; + int defaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId(); + when(mSubscriptionManager.getActiveSubscriptionInfo(defaultDataSubId)).thenReturn( + mDefaultDataSubscriptionInfo); + when(mDefaultDataSubscriptionInfo.getDisplayName()).thenReturn(expectDisplayName); + when(mServiceState.getState()).thenReturn(ServiceState.STATE_IN_SERVICE); + mBundle.putBoolean(CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL, false); + + ListBuilder.RowBuilder testRowBuild = mProviderModelSliceHelper.createCarrierRow(); + + assertThat(testRowBuild.getTitle()).isEqualTo(expectDisplayName); + } + + @Test + public void isNoCarrierData_mobileDataOnAndNoData_returnTrue() { + when(mTelephonyManager.isDataEnabled()).thenReturn(true); + when(mTelephonyManager.getDataState()).thenReturn(mTelephonyManager.DATA_DISCONNECTED); + when(mTelephonyManager.getServiceState()).thenReturn(mServiceState); + when(mServiceState.getState()).thenReturn(ServiceState.STATE_IN_SERVICE); + + assertThat(mProviderModelSliceHelper.isNoCarrierData()).isTrue(); + } + + @Test + public void isNoCarrierData_mobileDataOffAndOutOfService_returnTrue() { + when(mTelephonyManager.isDataEnabled()).thenReturn(false); + when(mTelephonyManager.getDataState()).thenReturn(mTelephonyManager.DATA_DISCONNECTED); + when(mTelephonyManager.getServiceState()).thenReturn(mServiceState); + when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE); + + assertThat(mProviderModelSliceHelper.isNoCarrierData()).isTrue(); + } + + @Test + public void isNoCarrierData_mobileDataOnAndDataConnected_returnFalse() { + when(mTelephonyManager.isDataEnabled()).thenReturn(true); + when(mTelephonyManager.getDataState()).thenReturn(mTelephonyManager.DATA_CONNECTED); + when(mTelephonyManager.getServiceState()).thenReturn(mServiceState); + when(mServiceState.getState()).thenReturn(ServiceState.STATE_IN_SERVICE); + + assertThat(mProviderModelSliceHelper.isNoCarrierData()).isFalse(); + } + + @Test + public void isNoCarrierData_mobileDataOffAndVoiceIsInService_returnFalse() { + when(mTelephonyManager.isDataEnabled()).thenReturn(false); + when(mTelephonyManager.getDataState()).thenReturn(mTelephonyManager.DATA_DISCONNECTED); + when(mTelephonyManager.getServiceState()).thenReturn(mServiceState); + when(mServiceState.getState()).thenReturn(ServiceState.STATE_IN_SERVICE); + + assertThat(mProviderModelSliceHelper.isNoCarrierData()).isFalse(); + } + + @Test + public void getMobileDrawable_noCarrierData_getMobileDrawable() throws Throwable { + when(mTelephonyManager.isDataEnabled()).thenReturn(false); + when(mTelephonyManager.getDataState()).thenReturn(mTelephonyManager.DATA_DISCONNECTED); + when(mTelephonyManager.getServiceState()).thenReturn(mServiceState); + when(mServiceState.getState()).thenReturn(ServiceState.STATE_OUT_OF_SERVICE); + int defaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId(); + when(mSubscriptionManager.getActiveSubscriptionInfo(defaultDataSubId)).thenReturn( + mDefaultDataSubscriptionInfo); + when(mConnectivityManager.getActiveNetwork()).thenReturn(null); + Drawable expectDrawable = mock(Drawable.class); + + assertThat(mProviderModelSliceHelper.getMobileDrawable(expectDrawable)).isEqualTo( + expectDrawable); + } + + @Test + public void getMobileDrawable_hasCarrierDataAndDataIsOnCellular_getMobileDrawable() + throws Throwable { + when(mTelephonyManager.isDataEnabled()).thenReturn(true); + when(mTelephonyManager.getDataState()).thenReturn(mTelephonyManager.DATA_CONNECTED); + when(mTelephonyManager.getServiceState()).thenReturn(mServiceState); + when(mServiceState.getState()).thenReturn(ServiceState.STATE_IN_SERVICE); + Drawable drawable = mock(Drawable.class); + int defaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId(); + when(mSubscriptionManager.getActiveSubscriptionInfo(defaultDataSubId)).thenReturn( + mDefaultDataSubscriptionInfo); + addNetworkTransportType(NetworkCapabilities.TRANSPORT_CELLULAR); + + assertThat(mProviderModelSliceHelper.getMobileDrawable(drawable)).isEqualTo( + mDrawableWithSignalStrength); + + verify(mDrawableWithSignalStrength).setTint(Utils.getColorAccentDefaultColor(mContext)); + } + + @Test + public void getMobileDrawable_hasCarrierDataAndDataIsOnWifi_getMobileDrawable() + throws Throwable { + when(mTelephonyManager.isDataEnabled()).thenReturn(true); + when(mTelephonyManager.getDataState()).thenReturn(mTelephonyManager.DATA_CONNECTED); + when(mTelephonyManager.getServiceState()).thenReturn(mServiceState); + when(mServiceState.getState()).thenReturn(ServiceState.STATE_IN_SERVICE); + Drawable drawable = mock(Drawable.class); + int defaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId(); + when(mSubscriptionManager.getActiveSubscriptionInfo(defaultDataSubId)).thenReturn( + mDefaultDataSubscriptionInfo); + addNetworkTransportType(NetworkCapabilities.TRANSPORT_WIFI); + + assertThat(mProviderModelSliceHelper.getMobileDrawable(drawable)).isEqualTo( + mDrawableWithSignalStrength); + } + + private void addNetworkTransportType(int networkType) { + mNetworkCapabilities = new NetworkCapabilities().addTransportType(networkType); + when(mConnectivityManager.getNetworkCapabilities(mNetwork)).thenReturn( + mNetworkCapabilities); + } + + private class TestCustomSliceable implements CustomSliceable { + TestCustomSliceable() { + } + + @Override + public Slice getSlice() { + return null; + } + + @Override + public Uri getUri() { + return Uri.parse("content://android.settings.slices/action/provider_model"); + } + + @Override + public Intent getIntent() { + return new Intent(); + } + } + + private class MockProviderModelSliceHelper extends ProviderModelSliceHelper { + MockProviderModelSliceHelper(Context context, CustomSliceable sliceable) { + super(context, sliceable); + } + + @Override + public Drawable getDrawableWithSignalStrength() { + return mDrawableWithSignalStrength; + } + } +} diff --git a/tests/unit/src/com/android/settings/testutils/ResourcesUtils.java b/tests/unit/src/com/android/settings/testutils/ResourcesUtils.java index 89cc7b37bb8..8ef310d49ab 100644 --- a/tests/unit/src/com/android/settings/testutils/ResourcesUtils.java +++ b/tests/unit/src/com/android/settings/testutils/ResourcesUtils.java @@ -17,15 +17,43 @@ package com.android.settings.testutils; import android.content.Context; +/** + * Test util to provide the correct resources. + */ public final class ResourcesUtils { + /** + * Return a resource identifier for the given resource name. + * @param context Context to use. + * @param type Optional default resource type to find, if "type/" is not included in the name. + * Can be null to require an explicit type. + * @param name The name of the desired resource. + * @return The associated resource identifier. Returns 0 if no such resource was found. + * (0 is not a valid resource ID.) + */ public static int getResourcesId(Context context, String type, String name) { return context.getResources().getIdentifier(name, type, context.getPackageName()); } + /** + * Returns a localized string from the application's package's default string table. + * @param context Context to use. + * @param name The name of the desired resource. + * @return The string data associated with the resource, stripped of styled text information. + */ public static String getResourcesString(Context context, String name) { return context.getResources().getString(getResourcesId(context, "string", name)); } + /** + * Return the string value associated with a particular neame of resource, + * substituting the format arguments as defined in {@link java.util.Formatter} + * and {@link java.lang.String#format}. It will be stripped of any styled text + * information. + * @param context Context to use. + * @param name The name of the desired resource. + * @param value The format arguments that will be used for substitution. + * @return The string data associated with the resource, stripped of styled text information. + */ public static String getResourcesString(Context context, String name, Object... value) { return context.getResources().getString(getResourcesId(context, "string", name), value); }