From 3e35cff7ba977cd9bebb36f400cb2219b9fff16d Mon Sep 17 00:00:00 2001 From: Chaohui Wang Date: Fri, 26 May 2023 11:38:38 +0800 Subject: [PATCH] Move unrestricted data summary to DataSaverController DataSaverController currently used in 2 pages, - Network & internet > Data Saver - Apps > Special app access This helps unify the logic, and instead of showing on "Special app access", this summary shows on "Unrestricted data" is make more sense. Bug: 280280596 Test: Manually on above pages Test: Unit test Change-Id: Ia151ed8179a250f8f20cc5041f9383fffebdab10 --- res/values/strings.xml | 6 - res/xml/apps.xml | 3 +- .../applications/AppDashboardFragment.java | 1 - .../SpecialAppAccessPreferenceController.java | 154 ------------------ .../specialaccess/DataSaverController.java | 36 ---- .../specialaccess/DataSaverController.kt | 88 ++++++++++ .../specialaccess/SpecialAccessSettings.java | 10 ++ .../settings/datausage/DataSaverSummary.kt | 60 ++----- ...cialAppAccessPreferenceControllerTest.java | 125 -------------- .../DataSaverControllerTest.java | 74 --------- .../specialaccess/DataSaverControllerTest.kt} | 31 +++- 11 files changed, 139 insertions(+), 449 deletions(-) delete mode 100644 src/com/android/settings/applications/SpecialAppAccessPreferenceController.java delete mode 100644 src/com/android/settings/applications/specialaccess/DataSaverController.java create mode 100644 src/com/android/settings/applications/specialaccess/DataSaverController.kt delete mode 100644 tests/robotests/src/com/android/settings/applications/SpecialAppAccessPreferenceControllerTest.java delete mode 100644 tests/robotests/src/com/android/settings/applications/specialaccess/DataSaverControllerTest.java rename tests/spa_unit/src/com/android/settings/{datausage/DataSaverSummaryTest.kt => applications/specialaccess/DataSaverControllerTest.kt} (76%) diff --git a/res/values/strings.xml b/res/values/strings.xml index 349a4ab5768..bdf80a30866 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -9702,12 +9702,6 @@ Special app access - - - 1 app can use unrestricted data - %d apps can use unrestricted data - - See more diff --git a/res/xml/apps.xml b/res/xml/apps.xml index ae51bae9063..03212c914fe 100644 --- a/res/xml/apps.xml +++ b/res/xml/apps.xml @@ -105,7 +105,6 @@ android:key="special_access" android:fragment="com.android.settings.applications.specialaccess.SpecialAccessSettings" android:title="@string/special_access" - android:order="20" - settings:controller="com.android.settings.applications.SpecialAppAccessPreferenceController"/> + android:order="20"/> diff --git a/src/com/android/settings/applications/AppDashboardFragment.java b/src/com/android/settings/applications/AppDashboardFragment.java index 7e203b00e3e..11f8405ae56 100644 --- a/src/com/android/settings/applications/AppDashboardFragment.java +++ b/src/com/android/settings/applications/AppDashboardFragment.java @@ -66,7 +66,6 @@ public class AppDashboardFragment extends DashboardFragment { @Override public void onAttach(Context context) { super.onAttach(context); - use(SpecialAppAccessPreferenceController.class).setSession(getSettingsLifecycle()); mAppsPreferenceController = use(AppsPreferenceController.class); mAppsPreferenceController.setFragment(this /* fragment */); getSettingsLifecycle().addObserver(mAppsPreferenceController); diff --git a/src/com/android/settings/applications/SpecialAppAccessPreferenceController.java b/src/com/android/settings/applications/SpecialAppAccessPreferenceController.java deleted file mode 100644 index 42f5930ed62..00000000000 --- a/src/com/android/settings/applications/SpecialAppAccessPreferenceController.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * 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.applications; - -import android.app.Application; -import android.content.Context; - -import androidx.annotation.VisibleForTesting; -import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; - -import com.android.settings.R; -import com.android.settings.core.BasePreferenceController; -import com.android.settings.datausage.AppStateDataUsageBridge; -import com.android.settings.datausage.AppStateDataUsageBridge.DataUsageState; -import com.android.settings.datausage.DataSaverBackend; -import com.android.settingslib.applications.ApplicationsState; -import com.android.settingslib.core.lifecycle.Lifecycle; -import com.android.settingslib.core.lifecycle.LifecycleObserver; -import com.android.settingslib.core.lifecycle.events.OnDestroy; -import com.android.settingslib.core.lifecycle.events.OnStart; -import com.android.settingslib.core.lifecycle.events.OnStop; - -import java.util.ArrayList; - -public class SpecialAppAccessPreferenceController extends BasePreferenceController implements - AppStateBaseBridge.Callback, ApplicationsState.Callbacks, LifecycleObserver, OnStart, - OnStop, OnDestroy { - - @VisibleForTesting - ApplicationsState.Session mSession; - - private final ApplicationsState mApplicationsState; - private final AppStateDataUsageBridge mDataUsageBridge; - private final DataSaverBackend mDataSaverBackend; - - private Preference mPreference; - private boolean mExtraLoaded; - - - public SpecialAppAccessPreferenceController(Context context, String key) { - super(context, key); - mApplicationsState = ApplicationsState.getInstance( - (Application) context.getApplicationContext()); - mDataSaverBackend = new DataSaverBackend(context); - mDataUsageBridge = new AppStateDataUsageBridge(mApplicationsState, this, mDataSaverBackend); - } - - public void setSession(Lifecycle lifecycle) { - mSession = mApplicationsState.newSession(this, lifecycle); - } - - @Override - public int getAvailabilityStatus() { - return AVAILABLE; - } - - @Override - public void displayPreference(PreferenceScreen screen) { - super.displayPreference(screen); - mPreference = screen.findPreference(getPreferenceKey()); - } - - @Override - public void onStart() { - mDataUsageBridge.resume(true /* forceLoadAllApps */); - } - - @Override - public void onStop() { - mDataUsageBridge.pause(); - } - - @Override - public void onDestroy() { - mDataUsageBridge.release(); - } - - @Override - public void updateState(Preference preference) { - updateSummary(); - } - - @Override - public void onExtraInfoUpdated() { - mExtraLoaded = true; - updateSummary(); - } - - private void updateSummary() { - if (!mExtraLoaded || mPreference == null) { - return; - } - - final ArrayList allApps = mSession.getAllApps(); - int count = 0; - for (ApplicationsState.AppEntry entry : allApps) { - if (!ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER.filterApp(entry)) { - continue; - } - if (entry.extraInfo instanceof DataUsageState - && ((DataUsageState) entry.extraInfo).isDataSaverAllowlisted) { - count++; - } - } - mPreference.setSummary(mContext.getResources().getQuantityString( - R.plurals.special_access_summary, count, count)); - } - - @Override - public void onRunningStateChanged(boolean running) { - } - - @Override - public void onPackageListChanged() { - } - - @Override - public void onRebuildComplete(ArrayList apps) { - } - - @Override - public void onPackageIconChanged() { - } - - @Override - public void onPackageSizeChanged(String packageName) { - } - - @Override - public void onAllSizesComputed() { - } - - @Override - public void onLauncherInfoChanged() { - // when the value of the AppEntry.hasLauncherEntry was changed. - updateSummary(); - } - - @Override - public void onLoadEntriesCompleted() { - } -} diff --git a/src/com/android/settings/applications/specialaccess/DataSaverController.java b/src/com/android/settings/applications/specialaccess/DataSaverController.java deleted file mode 100644 index d1fd202aae3..00000000000 --- a/src/com/android/settings/applications/specialaccess/DataSaverController.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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.applications.specialaccess; - -import android.content.Context; - -import com.android.settings.R; -import com.android.settings.core.BasePreferenceController; - -public class DataSaverController extends BasePreferenceController { - - public DataSaverController(Context context, String key) { - super(context, key); - } - - @AvailabilityStatus - public int getAvailabilityStatus() { - return mContext.getResources().getBoolean(R.bool.config_show_data_saver) - ? AVAILABLE : UNSUPPORTED_ON_DEVICE; - } -} diff --git a/src/com/android/settings/applications/specialaccess/DataSaverController.kt b/src/com/android/settings/applications/specialaccess/DataSaverController.kt new file mode 100644 index 00000000000..3a2fdb002b1 --- /dev/null +++ b/src/com/android/settings/applications/specialaccess/DataSaverController.kt @@ -0,0 +1,88 @@ +/* + * 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.applications.specialaccess + +import android.content.Context +import android.net.NetworkPolicyManager +import android.os.UserHandle +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.lifecycleScope +import androidx.lifecycle.repeatOnLifecycle +import androidx.preference.Preference +import androidx.preference.PreferenceScreen +import com.android.settings.R +import com.android.settings.core.BasePreferenceController +import com.android.settingslib.spa.framework.util.formatString +import com.android.settingslib.spaprivileged.model.app.AppListRepository +import com.android.settingslib.spaprivileged.model.app.AppListRepositoryImpl +import com.google.common.annotations.VisibleForTesting +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +class DataSaverController(context: Context, key: String) : BasePreferenceController(context, key) { + + private lateinit var preference: Preference + + @AvailabilityStatus + override fun getAvailabilityStatus(): Int = when { + mContext.resources.getBoolean(R.bool.config_show_data_saver) -> AVAILABLE + else -> UNSUPPORTED_ON_DEVICE + } + + override fun displayPreference(screen: PreferenceScreen) { + super.displayPreference(screen) + preference = screen.findPreference(preferenceKey)!! + } + + fun init(viewLifecycleOwner: LifecycleOwner) { + viewLifecycleOwner.lifecycleScope.launch { + viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { + preference.summary = getUnrestrictedSummary(mContext) + } + } + } + + companion object { + @VisibleForTesting + suspend fun getUnrestrictedSummary( + context: Context, + appListRepository: AppListRepository = + AppListRepositoryImpl(context.applicationContext), + ) = context.formatString( + R.string.data_saver_unrestricted_summary, + "count" to getAllowCount(context.applicationContext, appListRepository), + ) + + private suspend fun getAllowCount(context: Context, appListRepository: AppListRepository) = + withContext(Dispatchers.IO) { + coroutineScope { + val appsDeferred = async { + appListRepository.loadAndFilterApps( + userId = UserHandle.myUserId(), + isSystemApp = false, + ) + } + val uidsAllowed = NetworkPolicyManager.from(context) + .getUidsWithPolicy(NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND) + appsDeferred.await().count { app -> app.uid in uidsAllowed } + } + } + } +} \ No newline at end of file diff --git a/src/com/android/settings/applications/specialaccess/SpecialAccessSettings.java b/src/com/android/settings/applications/specialaccess/SpecialAccessSettings.java index 2cbc30422fc..9f4c8958cf4 100644 --- a/src/com/android/settings/applications/specialaccess/SpecialAccessSettings.java +++ b/src/com/android/settings/applications/specialaccess/SpecialAccessSettings.java @@ -21,6 +21,10 @@ import static android.app.admin.DevicePolicyResources.Strings.Settings.MANAGE_DE import android.app.settings.SettingsEnums; import android.os.Bundle; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; @@ -46,6 +50,12 @@ public class SpecialAccessSettings extends DashboardFragment { MANAGE_DEVICE_ADMIN_APPS, R.string.manage_device_admin); } + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + use(DataSaverController.class).init(getViewLifecycleOwner()); + } + @Override protected int getPreferenceScreenResId() { return R.xml.special_access; diff --git a/src/com/android/settings/datausage/DataSaverSummary.kt b/src/com/android/settings/datausage/DataSaverSummary.kt index 7f38900bbd2..13fbbfa3069 100644 --- a/src/com/android/settings/datausage/DataSaverSummary.kt +++ b/src/com/android/settings/datausage/DataSaverSummary.kt @@ -17,34 +17,22 @@ package com.android.settings.datausage import android.app.settings.SettingsEnums import android.content.Context -import android.net.NetworkPolicyManager import android.os.Bundle -import android.os.UserHandle import android.telephony.SubscriptionManager +import android.view.View import android.widget.Switch -import androidx.annotation.VisibleForTesting -import androidx.lifecycle.lifecycleScope -import androidx.preference.Preference import com.android.settings.R import com.android.settings.SettingsActivity -import com.android.settings.SettingsPreferenceFragment +import com.android.settings.applications.specialaccess.DataSaverController +import com.android.settings.dashboard.DashboardFragment import com.android.settings.search.BaseSearchIndexProvider import com.android.settings.widget.SettingsMainSwitchBar import com.android.settingslib.search.SearchIndexable -import com.android.settingslib.spa.framework.util.formatString -import com.android.settingslib.spaprivileged.model.app.AppListRepository -import com.android.settingslib.spaprivileged.model.app.AppListRepositoryImpl -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.async -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext @SearchIndexable -class DataSaverSummary : SettingsPreferenceFragment() { +class DataSaverSummary : DashboardFragment() { private lateinit var switchBar: SettingsMainSwitchBar private lateinit var dataSaverBackend: DataSaverBackend - private lateinit var unrestrictedAccess: Preference // Flag used to avoid infinite loop due if user switch it on/off too quick. private var switching = false @@ -57,8 +45,6 @@ class DataSaverSummary : SettingsPreferenceFragment() { return } - addPreferencesFromResource(R.xml.data_saver) - unrestrictedAccess = findPreference(KEY_UNRESTRICTED_ACCESS)!! dataSaverBackend = DataSaverBackend(requireContext()) } @@ -73,12 +59,14 @@ class DataSaverSummary : SettingsPreferenceFragment() { } } + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + use(DataSaverController::class.java).init(viewLifecycleOwner) + } + override fun onResume() { super.onResume() dataSaverBackend.addListener(dataSaverBackendListener) - viewLifecycleOwner.lifecycleScope.launch { - unrestrictedAccess.summary = getUnrestrictedSummary(requireContext()) - } } override fun onPause() { @@ -95,9 +83,10 @@ class DataSaverSummary : SettingsPreferenceFragment() { } } + override fun getPreferenceScreenResId() = R.xml.data_saver override fun getMetricsCategory() = SettingsEnums.DATA_SAVER_SUMMARY - override fun getHelpResource() = R.string.help_url_data_saver + override fun getLogTag() = TAG private val dataSaverBackendListener = object : DataSaverBackend.Listener { override fun onDataSaverChanged(isDataSaving: Boolean) { @@ -109,32 +98,7 @@ class DataSaverSummary : SettingsPreferenceFragment() { } companion object { - private const val KEY_UNRESTRICTED_ACCESS = "unrestricted_access" - - @VisibleForTesting - suspend fun getUnrestrictedSummary( - context: Context, - appListRepository: AppListRepository = - AppListRepositoryImpl(context.applicationContext), - ) = context.formatString( - R.string.data_saver_unrestricted_summary, - "count" to getAllowCount(context.applicationContext, appListRepository), - ) - - private suspend fun getAllowCount(context: Context, appListRepository: AppListRepository) = - withContext(Dispatchers.IO) { - coroutineScope { - val appsDeferred = async { - appListRepository.loadAndFilterApps( - userId = UserHandle.myUserId(), - isSystemApp = false, - ) - } - val uidsAllowed = NetworkPolicyManager.from(context) - .getUidsWithPolicy(NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND) - appsDeferred.await().count { app -> app.uid in uidsAllowed } - } - } + private const val TAG = "DataSaverSummary" private fun Context.isDataSaverVisible(): Boolean = resources.getBoolean(R.bool.config_show_data_saver) diff --git a/tests/robotests/src/com/android/settings/applications/SpecialAppAccessPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/SpecialAppAccessPreferenceControllerTest.java deleted file mode 100644 index da5ada783ad..00000000000 --- a/tests/robotests/src/com/android/settings/applications/SpecialAppAccessPreferenceControllerTest.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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.applications; - -import static com.android.settings.core.BasePreferenceController.AVAILABLE; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.ModuleInfo; -import android.content.pm.PackageManager; - -import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; - -import com.android.settings.R; -import com.android.settings.datausage.AppStateDataUsageBridge; -import com.android.settings.testutils.shadow.ShadowApplicationsState; -import com.android.settings.testutils.shadow.ShadowUserManager; -import com.android.settingslib.applications.ApplicationsState; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; - -import java.util.ArrayList; - -@RunWith(RobolectricTestRunner.class) -@Config(shadows = {ShadowUserManager.class, ShadowApplicationsState.class}) -public class SpecialAppAccessPreferenceControllerTest { - - private Context mContext; - @Mock - private ApplicationsState.Session mSession; - @Mock - private PreferenceScreen mScreen; - @Mock - private PackageManager mPackageManager; - - private SpecialAppAccessPreferenceController mController; - private Preference mPreference; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = spy(RuntimeEnvironment.application); - when(mContext.getApplicationContext()).thenReturn(mContext); - ShadowUserManager.getShadow().setProfileIdsWithDisabled(new int[]{0}); - doReturn(mPackageManager).when(mContext).getPackageManager(); - doReturn(new ArrayList()).when(mPackageManager).getInstalledModules(anyInt()); - mController = new SpecialAppAccessPreferenceController(mContext, "test_key"); - mPreference = new Preference(mContext); - when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); - - mController.mSession = mSession; - } - - @Test - public void getAvailabilityState_unsearchable() { - assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); - } - - @Test - public void updateState_shouldSetSummary() { - final ArrayList apps = new ArrayList<>(); - final ApplicationsState.AppEntry entry = mock(ApplicationsState.AppEntry.class); - entry.hasLauncherEntry = true; - entry.info = new ApplicationInfo(); - entry.extraInfo = new AppStateDataUsageBridge.DataUsageState( - true /* allowlisted */, false /* denylisted */); - apps.add(entry); - when(mSession.getAllApps()).thenReturn(apps); - - mController.displayPreference(mScreen); - mController.onExtraInfoUpdated(); - - assertThat(mPreference.getSummary()) - .isEqualTo(mContext.getResources().getQuantityString( - R.plurals.special_access_summary, 1, 1)); - } - - @Test - public void updateState_wrongExtraInfo_shouldNotIncludeInSummary() { - final ArrayList apps = new ArrayList<>(); - final ApplicationsState.AppEntry entry = mock(ApplicationsState.AppEntry.class); - entry.hasLauncherEntry = true; - entry.info = new ApplicationInfo(); - entry.extraInfo = new AppStateNotificationBridge.NotificationsSentState(); - apps.add(entry); - when(mSession.getAllApps()).thenReturn(apps); - - mController.displayPreference(mScreen); - mController.onExtraInfoUpdated(); - - assertThat(mPreference.getSummary()) - .isEqualTo(mContext.getResources().getQuantityString( - R.plurals.special_access_summary, 0, 0)); - } -} diff --git a/tests/robotests/src/com/android/settings/applications/specialaccess/DataSaverControllerTest.java b/tests/robotests/src/com/android/settings/applications/specialaccess/DataSaverControllerTest.java deleted file mode 100644 index f039c97b2dc..00000000000 --- a/tests/robotests/src/com/android/settings/applications/specialaccess/DataSaverControllerTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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.applications.specialaccess; - -import static com.google.common.truth.Truth.assertThat; - -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.when; - -import android.content.Context; -import android.content.res.Resources; - -import com.android.settings.R; - -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.MockitoAnnotations; -import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; -import org.robolectric.annotation.Config; - -@RunWith(RobolectricTestRunner.class) -public class DataSaverControllerTest { - - private Context mContext; - private Resources mResources; - private DataSaverController mController; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = spy(RuntimeEnvironment.application.getApplicationContext()); - - mResources = spy(mContext.getResources()); - when(mContext.getResources()).thenReturn(mResources); - - mController = new DataSaverController(mContext, "key"); - } - - @Test - public void testDataSaver_byDefault_shouldBeShown() { - when(mResources.getBoolean(R.bool.config_show_data_saver)).thenReturn(true); - assertThat(mController.isAvailable()).isTrue(); - } - - @Ignore - @Test - @Config(qualifiers = "mcc999") - public void testDataSaver_ifDisabledByCarrier_shouldNotBeShown() { - assertThat(mController.isAvailable()).isFalse(); - } - - @Test - public void testDataSaver_ifDisabled_shouldNotBeShown() { - when(mResources.getBoolean(R.bool.config_show_data_saver)).thenReturn(false); - assertThat(mController.isAvailable()).isFalse(); - } -} diff --git a/tests/spa_unit/src/com/android/settings/datausage/DataSaverSummaryTest.kt b/tests/spa_unit/src/com/android/settings/applications/specialaccess/DataSaverControllerTest.kt similarity index 76% rename from tests/spa_unit/src/com/android/settings/datausage/DataSaverSummaryTest.kt rename to tests/spa_unit/src/com/android/settings/applications/specialaccess/DataSaverControllerTest.kt index 3c88d8e875b..c2413af7603 100644 --- a/tests/spa_unit/src/com/android/settings/datausage/DataSaverSummaryTest.kt +++ b/tests/spa_unit/src/com/android/settings/applications/specialaccess/DataSaverControllerTest.kt @@ -14,15 +14,19 @@ * limitations under the License. */ -package com.android.settings.datausage +package com.android.settings.applications.specialaccess import android.content.Context import android.content.pm.ApplicationInfo +import android.content.res.Resources import android.net.NetworkPolicyManager import android.net.NetworkPolicyManager.POLICY_ALLOW_METERED_BACKGROUND import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.android.settings.datausage.DataSaverSummary.Companion.getUnrestrictedSummary +import com.android.settings.R +import com.android.settings.applications.specialaccess.DataSaverController.Companion.getUnrestrictedSummary +import com.android.settings.core.BasePreferenceController.AVAILABLE +import com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE import com.android.settingslib.spaprivileged.model.app.AppListRepository import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -41,20 +45,41 @@ import org.mockito.Mockito.`when` as whenever @OptIn(ExperimentalCoroutinesApi::class) @RunWith(AndroidJUnit4::class) -class DataSaverSummaryTest { +class DataSaverControllerTest { @get:Rule val mockito: MockitoRule = MockitoJUnit.rule() @Spy private val context: Context = ApplicationProvider.getApplicationContext() + @Spy + private val resources: Resources = context.resources + @Mock private lateinit var networkPolicyManager: NetworkPolicyManager + @Mock + private lateinit var dataSaverController: DataSaverController + @Before fun setUp() { whenever(context.applicationContext).thenReturn(context) + whenever(context.resources).thenReturn(resources) whenever(NetworkPolicyManager.from(context)).thenReturn(networkPolicyManager) + + dataSaverController = DataSaverController(context, "key") + } + + @Test + fun getAvailabilityStatus_whenConfigOn_available() { + whenever(resources.getBoolean(R.bool.config_show_data_saver)).thenReturn(true) + assertThat(dataSaverController.availabilityStatus).isEqualTo(AVAILABLE) + } + + @Test + fun getAvailabilityStatus_whenConfigOff_unsupportedOnDevice() { + whenever(resources.getBoolean(R.bool.config_show_data_saver)).thenReturn(false) + assertThat(dataSaverController.availabilityStatus).isEqualTo(UNSUPPORTED_ON_DEVICE) } @Test