fix: 引入Settings的Module
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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.datausage;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.ProgressBar;
|
||||
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settingslib.AppItem;
|
||||
import com.android.settingslib.net.UidDetail;
|
||||
import com.android.settingslib.net.UidDetailProvider;
|
||||
|
||||
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;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class AppDataUsagePreferenceTest {
|
||||
private static final String FIFTY_PERCENT = "50%";
|
||||
|
||||
@Mock
|
||||
private UidDetailProvider mUidDetailProvider;
|
||||
private AppItem mAppItem;
|
||||
private UidDetail mUidDetail;
|
||||
|
||||
private AppDataUsagePreference mPreference;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mAppItem = new AppItem(123);
|
||||
mUidDetail = new UidDetail();
|
||||
mUidDetail.icon = new ColorDrawable(Color.BLUE);
|
||||
mUidDetail.label = "title";
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createPref_hasCachedUidDetail_shouldSetAppInfo() {
|
||||
when(mUidDetailProvider.getUidDetail(mAppItem.key, false /* blocking */))
|
||||
.thenReturn(mUidDetail);
|
||||
|
||||
mPreference = new AppDataUsagePreference(RuntimeEnvironment.application, mAppItem,
|
||||
50 /* percent */, mUidDetailProvider);
|
||||
|
||||
assertThat(mPreference.getTitle()).isEqualTo(mUidDetail.label);
|
||||
assertThat(mPreference.getIcon()).isEqualTo(mUidDetail.icon);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createPref_noCachedUidDetail_shouldSetAppInfo() {
|
||||
when(mUidDetailProvider.getUidDetail(mAppItem.key, true /* blocking */))
|
||||
.thenReturn(mUidDetail);
|
||||
|
||||
mPreference = new AppDataUsagePreference(RuntimeEnvironment.application, mAppItem,
|
||||
50 /* percent */, mUidDetailProvider);
|
||||
|
||||
assertThat(mPreference.getTitle()).isEqualTo(mUidDetail.label);
|
||||
assertThat(mPreference.getIcon()).isEqualTo(mUidDetail.icon);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createPref_progressBarShouldSetPercentageContentDescription() {
|
||||
when(mUidDetailProvider.getUidDetail(mAppItem.key, true /* blocking */))
|
||||
.thenReturn(mUidDetail);
|
||||
mPreference = new AppDataUsagePreference(RuntimeEnvironment.application, mAppItem,
|
||||
50 /* percent */, mUidDetailProvider);
|
||||
final View view = LayoutInflater.from(RuntimeEnvironment.application).inflate(
|
||||
com.android.settingslib.widget.preference.app.R.layout.preference_app, null);
|
||||
final PreferenceViewHolder preferenceViewHolder =
|
||||
PreferenceViewHolder.createInstanceForTests(view);
|
||||
final ProgressBar progressBar = (ProgressBar) preferenceViewHolder.findViewById(
|
||||
android.R.id.progress);
|
||||
|
||||
mPreference.onBindViewHolder(preferenceViewHolder);
|
||||
|
||||
assertThat(progressBar.getContentDescription()).isEqualTo(FIFTY_PERCENT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,327 @@
|
||||
/*
|
||||
* 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.datausage;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.anyBoolean;
|
||||
import static org.mockito.Mockito.anyInt;
|
||||
import static org.mockito.Mockito.anyString;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.eq;
|
||||
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.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.net.NetworkPolicyManager;
|
||||
import android.net.NetworkTemplate;
|
||||
import android.os.Bundle;
|
||||
import android.os.Process;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Range;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.android.settings.applications.AppInfoBase;
|
||||
import com.android.settings.datausage.lib.NetworkUsageDetailsData;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.shadow.ShadowDataUsageUtils;
|
||||
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
|
||||
import com.android.settings.testutils.shadow.ShadowFragment;
|
||||
import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
|
||||
import com.android.settings.widget.EntityHeaderController;
|
||||
import com.android.settingslib.AppItem;
|
||||
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
import com.android.settingslib.core.AbstractPreferenceController;
|
||||
import com.android.settingslib.net.UidDetail;
|
||||
import com.android.settingslib.net.UidDetailProvider;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.RuntimeEnvironment;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowSubscriptionManager;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {ShadowEntityHeaderController.class, ShadowRestrictedLockUtilsInternal.class})
|
||||
public class AppDataUsageTest {
|
||||
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private EntityHeaderController mHeaderController;
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
|
||||
private AppDataUsage mFragment;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
ShadowEntityHeaderController.setUseMock(mHeaderController);
|
||||
when(mHeaderController.setUid(anyInt())).thenReturn(mHeaderController);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
ShadowEntityHeaderController.reset();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowFragment.class)
|
||||
public void onCreate_appUid_shouldGetAppLabelFromAppInfo() throws NameNotFoundException {
|
||||
mFragment = spy(new TestFragment());
|
||||
final FragmentActivity activity = spy(Robolectric.setupActivity(FragmentActivity.class));
|
||||
doReturn(mPackageManager).when(activity).getPackageManager();
|
||||
doReturn(activity).when(mFragment).getActivity();
|
||||
doReturn(RuntimeEnvironment.application).when(mFragment).getContext();
|
||||
ReflectionHelpers.setField(mFragment, "mDashboardFeatureProvider",
|
||||
FakeFeatureFactory.setupForTest().dashboardFeatureProvider);
|
||||
final String packageName = "testPackage";
|
||||
final int uid = (Process.FIRST_APPLICATION_UID + Process.LAST_APPLICATION_UID) / 2;
|
||||
doReturn(new String[]{packageName}).when(mPackageManager).getPackagesForUid(uid);
|
||||
final String label = "testLabel";
|
||||
final AppItem appItem = new AppItem(uid);
|
||||
appItem.uids.put(uid, true);
|
||||
final ApplicationInfo info = spy(new ApplicationInfo());
|
||||
doReturn(label).when(info).loadLabel(mPackageManager);
|
||||
when(mPackageManager.getApplicationInfoAsUser(
|
||||
eq(packageName), anyInt() /* flags */, anyInt() /* userId */)).thenReturn(info);
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable(AppDataUsage.ARG_APP_ITEM, appItem);
|
||||
args.putInt(AppInfoBase.ARG_PACKAGE_UID, uid);
|
||||
mFragment.setArguments(args);
|
||||
|
||||
mFragment.onCreate(Bundle.EMPTY);
|
||||
|
||||
assertThat(mFragment.mLabel).isEqualTo(label);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowFragment.class)
|
||||
public void onCreate_notAppUid_shouldGetAppLabelFromUidDetailProvider() {
|
||||
mFragment = spy(new TestFragment());
|
||||
ReflectionHelpers.setField(mFragment, "mDashboardFeatureProvider",
|
||||
FakeFeatureFactory.setupForTest().dashboardFeatureProvider);
|
||||
doReturn(Robolectric.setupActivity(FragmentActivity.class)).when(mFragment).getActivity();
|
||||
doReturn(RuntimeEnvironment.application).when(mFragment).getContext();
|
||||
final UidDetailProvider uidDetailProvider = mock(UidDetailProvider.class);
|
||||
doReturn(uidDetailProvider).when(mFragment).getUidDetailProvider();
|
||||
final String label = "testLabel";
|
||||
final int uid = Process.SYSTEM_UID;
|
||||
final UidDetail uidDetail = new UidDetail();
|
||||
uidDetail.label = label;
|
||||
when(uidDetailProvider.getUidDetail(eq(uid), anyBoolean() /* blocking */)).
|
||||
thenReturn(uidDetail);
|
||||
final AppItem appItem = new AppItem(uid);
|
||||
appItem.uids.put(uid, true);
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable(AppDataUsage.ARG_APP_ITEM, appItem);
|
||||
args.putInt(AppInfoBase.ARG_PACKAGE_UID, uid);
|
||||
mFragment.setArguments(args);
|
||||
|
||||
mFragment.onCreate(Bundle.EMPTY);
|
||||
|
||||
assertThat(mFragment.mLabel).isEqualTo(label);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindAppHeader_allWorkApps_shouldNotShowAppInfoLink() {
|
||||
mFragment = spy(new TestFragment());
|
||||
|
||||
when(mFragment.getPreferenceManager())
|
||||
.thenReturn(mock(PreferenceManager.class, RETURNS_DEEP_STUBS));
|
||||
doReturn(mock(PreferenceScreen.class)).when(mFragment).getPreferenceScreen();
|
||||
ReflectionHelpers.setField(mFragment, "mAppItem", mock(AppItem.class));
|
||||
|
||||
mFragment.addEntityHeader();
|
||||
|
||||
verify(mHeaderController).setHasAppInfoLink(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindAppHeader_workApp_shouldSetWorkAppUid()
|
||||
throws PackageManager.NameNotFoundException {
|
||||
final int fakeUserId = 100;
|
||||
|
||||
mFragment = spy(new TestFragment());
|
||||
final ArraySet<String> packages = new ArraySet<>();
|
||||
packages.add("pkg");
|
||||
final AppItem appItem = new AppItem(123456789);
|
||||
|
||||
ReflectionHelpers.setField(mFragment, "mPackageManager", mPackageManager);
|
||||
ReflectionHelpers.setField(mFragment, "mAppItem", appItem);
|
||||
ReflectionHelpers.setField(mFragment, "mPackages", packages);
|
||||
|
||||
when(mPackageManager.getPackageUidAsUser(anyString(), anyInt()))
|
||||
.thenReturn(fakeUserId);
|
||||
|
||||
when(mHeaderController.setHasAppInfoLink(anyBoolean())).thenReturn(mHeaderController);
|
||||
|
||||
when(mFragment.getPreferenceManager())
|
||||
.thenReturn(mock(PreferenceManager.class, RETURNS_DEEP_STUBS));
|
||||
doReturn(mock(PreferenceScreen.class)).when(mFragment).getPreferenceScreen();
|
||||
|
||||
mFragment.addEntityHeader();
|
||||
|
||||
verify(mHeaderController).setHasAppInfoLink(true);
|
||||
verify(mHeaderController).setUid(fakeUserId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changePreference_backgroundData_shouldUpdateUI() {
|
||||
mFragment = spy(new TestFragment());
|
||||
final AppItem appItem = new AppItem(123456789);
|
||||
final RestrictedSwitchPreference pref = mock(RestrictedSwitchPreference.class);
|
||||
final DataSaverBackend dataSaverBackend = mock(DataSaverBackend.class);
|
||||
ReflectionHelpers.setField(mFragment, "mAppItem", appItem);
|
||||
ReflectionHelpers.setField(mFragment, "mRestrictBackground", pref);
|
||||
ReflectionHelpers.setField(mFragment, "mDataSaverBackend", dataSaverBackend);
|
||||
|
||||
doNothing().when(mFragment).updatePrefs();
|
||||
|
||||
mFragment.onPreferenceChange(pref, true /* value */);
|
||||
|
||||
verify(mFragment).updatePrefs();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updatePrefs_restrictedByAdmin_shouldDisablePreference() {
|
||||
mFragment = spy(new TestFragment());
|
||||
final int testUid = 123123;
|
||||
final AppItem appItem = new AppItem(testUid);
|
||||
final RestrictedSwitchPreference restrictBackgroundPref
|
||||
= mock(RestrictedSwitchPreference.class);
|
||||
final RestrictedSwitchPreference unrestrictedDataPref
|
||||
= mock(RestrictedSwitchPreference.class);
|
||||
final DataSaverBackend dataSaverBackend = mock(DataSaverBackend.class);
|
||||
final NetworkPolicyManager networkPolicyManager = mock(NetworkPolicyManager.class);
|
||||
ReflectionHelpers.setField(mFragment, "mAppItem", appItem);
|
||||
ReflectionHelpers.setField(mFragment, "mRestrictBackground", restrictBackgroundPref);
|
||||
ReflectionHelpers.setField(mFragment, "mUnrestrictedData", unrestrictedDataPref);
|
||||
ReflectionHelpers.setField(mFragment, "mDataSaverBackend", dataSaverBackend);
|
||||
ReflectionHelpers.setField(mFragment.services, "mPolicyManager", networkPolicyManager);
|
||||
ReflectionHelpers.setField(mFragment, "mContext", RuntimeEnvironment.application);
|
||||
when(mFragment.getListView()).thenReturn(mock(RecyclerView.class));
|
||||
|
||||
ShadowRestrictedLockUtilsInternal.setRestricted(true);
|
||||
doReturn(NetworkPolicyManager.POLICY_NONE).when(networkPolicyManager)
|
||||
.getUidPolicy(testUid);
|
||||
|
||||
mFragment.updatePrefs();
|
||||
|
||||
verify(restrictBackgroundPref).setDisabledByAdmin(any(EnforcedAdmin.class));
|
||||
verify(unrestrictedDataPref).setDisabledByAdmin(any(EnforcedAdmin.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bindData_shouldUpdateUsageSummary() {
|
||||
mFragment = spy(new TestFragment());
|
||||
final Context context = RuntimeEnvironment.application;
|
||||
ReflectionHelpers.setField(mFragment, "mContext", context);
|
||||
final long backgroundBytes = 1234L;
|
||||
final long foregroundBytes = 5678L;
|
||||
final NetworkUsageDetailsData appUsage = new NetworkUsageDetailsData(
|
||||
new Range<>(1L, 2L),
|
||||
backgroundBytes + foregroundBytes,
|
||||
foregroundBytes,
|
||||
backgroundBytes
|
||||
);
|
||||
final Preference backgroundPref = mock(Preference.class);
|
||||
ReflectionHelpers.setField(mFragment, "mBackgroundUsage", backgroundPref);
|
||||
final Preference foregroundPref = mock(Preference.class);
|
||||
ReflectionHelpers.setField(mFragment, "mForegroundUsage", foregroundPref);
|
||||
final Preference totalPref = mock(Preference.class);
|
||||
ReflectionHelpers.setField(mFragment, "mTotalUsage", totalPref);
|
||||
|
||||
mFragment.bindData(appUsage);
|
||||
|
||||
verify(totalPref).setSummary(
|
||||
DataUsageUtils.formatDataUsage(context, backgroundBytes + foregroundBytes));
|
||||
verify(backgroundPref).setSummary(DataUsageUtils.formatDataUsage(context, backgroundBytes));
|
||||
verify(foregroundPref).setSummary(DataUsageUtils.formatDataUsage(context, foregroundBytes));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = {ShadowDataUsageUtils.class, ShadowSubscriptionManager.class,
|
||||
ShadowFragment.class})
|
||||
public void onCreate_noNetworkTemplateAndInvalidDataSubscription_shouldUseWifiTemplate() {
|
||||
ShadowDataUsageUtils.IS_MOBILE_DATA_SUPPORTED = true;
|
||||
ShadowDataUsageUtils.IS_WIFI_SUPPORTED = true;
|
||||
ShadowSubscriptionManager.setDefaultDataSubscriptionId(
|
||||
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
||||
mFragment = spy(new TestFragment());
|
||||
doReturn(Robolectric.setupActivity(FragmentActivity.class)).when(mFragment).getActivity();
|
||||
doReturn(RuntimeEnvironment.application).when(mFragment).getContext();
|
||||
final UidDetailProvider uidDetailProvider = mock(UidDetailProvider.class);
|
||||
doReturn(uidDetailProvider).when(mFragment).getUidDetailProvider();
|
||||
doReturn(new UidDetail()).when(uidDetailProvider).getUidDetail(anyInt(), anyBoolean());
|
||||
|
||||
ReflectionHelpers.setField(mFragment, "mDashboardFeatureProvider",
|
||||
FakeFeatureFactory.setupForTest().dashboardFeatureProvider);
|
||||
final Bundle args = new Bundle();
|
||||
args.putInt(AppInfoBase.ARG_PACKAGE_UID, 123123);
|
||||
mFragment.setArguments(args);
|
||||
|
||||
mFragment.onCreate(Bundle.EMPTY);
|
||||
|
||||
assertThat(mFragment.mTemplate.getMatchRule())
|
||||
.isEqualTo(NetworkTemplate.MATCH_WIFI);
|
||||
assertTrue(mFragment.mTemplate.getSubscriberIds().isEmpty());
|
||||
assertTrue(mFragment.mTemplate.getWifiNetworkKeys().isEmpty());
|
||||
}
|
||||
|
||||
private static class TestFragment extends AppDataUsage {
|
||||
@Override
|
||||
protected <T extends AbstractPreferenceController> T use(Class<T> clazz) {
|
||||
return mock(clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
void initCycle(List<Integer> uidList) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSimHardwareVisible(Context context) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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.datausage;
|
||||
|
||||
import static android.net.NetworkPolicy.CYCLE_NONE;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.anyInt;
|
||||
import static org.mockito.Mockito.anyLong;
|
||||
import static org.mockito.Mockito.anyString;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.nullable;
|
||||
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.DialogInterface;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.net.NetworkPolicyManager;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.android.settings.testutils.shadow.ShadowFragment;
|
||||
import com.android.settingslib.NetworkPolicyEditor;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
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;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {
|
||||
com.android.settings.testutils.shadow.ShadowFragment.class,
|
||||
})
|
||||
public class BillingCycleSettingsTest {
|
||||
|
||||
private static final int LIMIT_BYTES = 123;
|
||||
|
||||
@Mock
|
||||
private BillingCycleSettings mMockBillingCycleSettings;
|
||||
private BillingCycleSettings.ConfirmLimitFragment mConfirmLimitFragment;
|
||||
@Mock
|
||||
private PreferenceManager mMockPreferenceManager;
|
||||
@Mock
|
||||
private NetworkPolicyEditor mNetworkPolicyEditor;
|
||||
@Mock
|
||||
private NetworkPolicyManager mNetworkPolicyManager;
|
||||
@Mock
|
||||
private PackageManager mMockPackageManager;
|
||||
|
||||
private Context mContext;
|
||||
@Mock
|
||||
private Preference mBillingCycle;
|
||||
@Mock
|
||||
private Preference mDataWarning;
|
||||
@Mock
|
||||
private Preference mDataLimit;
|
||||
@Mock
|
||||
private SwitchPreference mEnableDataWarning;
|
||||
@Mock
|
||||
private SwitchPreference mEnableDataLimit;
|
||||
|
||||
private SharedPreferences mSharedPreferences;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = spy(RuntimeEnvironment.application);
|
||||
mConfirmLimitFragment = new BillingCycleSettings.ConfirmLimitFragment();
|
||||
mConfirmLimitFragment.setTargetFragment(mMockBillingCycleSettings, 0);
|
||||
mSharedPreferences = RuntimeEnvironment.application.getSharedPreferences(
|
||||
"testSharedPreferences", Context.MODE_PRIVATE);
|
||||
when(mMockBillingCycleSettings.getPreferenceManager()).thenReturn(mMockPreferenceManager);
|
||||
when(mMockPreferenceManager.getSharedPreferences()).thenReturn(mSharedPreferences);
|
||||
final Bundle args = new Bundle();
|
||||
args.putLong(BillingCycleSettings.ConfirmLimitFragment.EXTRA_LIMIT_BYTES, LIMIT_BYTES);
|
||||
mConfirmLimitFragment.setArguments(args);
|
||||
mSharedPreferences.edit().putBoolean(
|
||||
BillingCycleSettings.KEY_SET_DATA_LIMIT, false).apply();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataUsageLimit_shouldNotBeSetOnCancel() {
|
||||
mConfirmLimitFragment.onClick(null, DialogInterface.BUTTON_NEGATIVE);
|
||||
|
||||
assertThat(mSharedPreferences.getBoolean(BillingCycleSettings.KEY_SET_DATA_LIMIT, true))
|
||||
.isFalse();
|
||||
verify(mMockBillingCycleSettings, never()).setPolicyLimitBytes(anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataUsageLimit_shouldBeSetOnConfirmation() {
|
||||
mConfirmLimitFragment.onClick(null, DialogInterface.BUTTON_POSITIVE);
|
||||
|
||||
assertThat(mSharedPreferences.getBoolean(BillingCycleSettings.KEY_SET_DATA_LIMIT, false))
|
||||
.isTrue();
|
||||
verify(mMockBillingCycleSettings).setPolicyLimitBytes(LIMIT_BYTES);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataUsageSummary_shouldBeNull() {
|
||||
final BillingCycleSettings billingCycleSettings = spy(new BillingCycleSettings());
|
||||
when(billingCycleSettings.getContext()).thenReturn(mContext);
|
||||
billingCycleSettings.setUpForTest(mNetworkPolicyEditor, mBillingCycle,
|
||||
mDataLimit, mDataWarning, mEnableDataLimit, mEnableDataWarning);
|
||||
|
||||
doReturn("some-string").when(billingCycleSettings).getString(anyInt(), anyInt());
|
||||
when(mNetworkPolicyEditor.getPolicyCycleDay(any())).thenReturn(CYCLE_NONE + 1);
|
||||
when(mNetworkPolicyEditor.getPolicyLimitBytes(any())).thenReturn(2000L);
|
||||
when(mNetworkPolicyEditor.getPolicyWarningBytes(any())).thenReturn(1000L);
|
||||
|
||||
billingCycleSettings.updatePrefs();
|
||||
|
||||
verify(mBillingCycle).setSummary(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowFragment.class)
|
||||
@Ignore
|
||||
public void onCreate_emptyArguments_shouldSetDefaultNetworkTemplate() {
|
||||
final BillingCycleSettings billingCycleSettings = spy(new BillingCycleSettings());
|
||||
when(billingCycleSettings.getContext()).thenReturn(mContext);
|
||||
when(billingCycleSettings.getArguments()).thenReturn(Bundle.EMPTY);
|
||||
final FragmentActivity activity = mock(FragmentActivity.class);
|
||||
when(billingCycleSettings.getActivity()).thenReturn(activity);
|
||||
final Resources.Theme theme = mContext.getTheme();
|
||||
when(activity.getTheme()).thenReturn(theme);
|
||||
doNothing().when(billingCycleSettings)
|
||||
.onCreatePreferences(any(Bundle.class), nullable(String.class));
|
||||
when(mContext.getSystemService(Context.NETWORK_POLICY_SERVICE))
|
||||
.thenReturn(mNetworkPolicyManager);
|
||||
when(mContext.getPackageManager()).thenReturn(mMockPackageManager);
|
||||
when(mMockPackageManager.hasSystemFeature(any())).thenReturn(true);
|
||||
final SwitchPreference preference = mock(SwitchPreference.class);
|
||||
when(billingCycleSettings.findPreference(anyString())).thenReturn(preference);
|
||||
|
||||
billingCycleSettings.onCreate(Bundle.EMPTY);
|
||||
|
||||
assertThat(billingCycleSettings.mNetworkTemplate).isNotNull();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
package com.android.settings.datausage;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.util.SparseIntArray;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.datausage.ChartDataUsagePreference.DataUsageSummaryNode;
|
||||
import com.android.settings.datausage.lib.NetworkCycleChartData;
|
||||
import com.android.settings.datausage.lib.NetworkUsageData;
|
||||
import com.android.settings.widget.UsageView;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.robolectric.Robolectric;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class ChartDataUsagePreferenceTest {
|
||||
|
||||
// Test cycle start date, 20 Mar 2018 22:00: GMT
|
||||
private static final long TIMESTAMP_START = 1521583200000L;
|
||||
// Test bucket end date, 22 Mar 2018 00:00:00
|
||||
private static final long TIMESTAMP_END = 1521676800000L;
|
||||
|
||||
private List<NetworkUsageData> mNetworkCycleData;
|
||||
private NetworkCycleChartData mNetworkCycleChartData;
|
||||
private ChartDataUsagePreference mPreference;
|
||||
private Activity mActivity;
|
||||
private PreferenceViewHolder mHolder;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mActivity = spy(Robolectric.setupActivity(Activity.class));
|
||||
mPreference = new ChartDataUsagePreference(mActivity, null /* attrs */);
|
||||
LayoutInflater inflater = LayoutInflater.from(mActivity);
|
||||
View view = inflater.inflate(mPreference.getLayoutResource(), null /* root */,
|
||||
false /* attachToRoot */);
|
||||
mHolder = spy(PreferenceViewHolder.createInstanceForTests(view));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void calcPoints_dataAvailableFromCycleStart_shouldAddDataPointsOnly() {
|
||||
final UsageView usageView = mock(UsageView.class);
|
||||
final ArgumentCaptor<SparseIntArray> pointsCaptor =
|
||||
ArgumentCaptor.forClass(SparseIntArray.class);
|
||||
createTestNetworkData();
|
||||
mPreference.setTime(
|
||||
mNetworkCycleChartData.getTotal().getStartTime(),
|
||||
mNetworkCycleChartData.getTotal().getEndTime());
|
||||
mPreference.setNetworkCycleData(mNetworkCycleChartData);
|
||||
|
||||
mPreference.calcPoints(usageView, mNetworkCycleData.subList(0, 5));
|
||||
|
||||
verify(usageView).addPath(pointsCaptor.capture());
|
||||
final SparseIntArray points = pointsCaptor.getValue();
|
||||
// the point should be normal usage data
|
||||
assertThat(points.valueAt(1)).isNotEqualTo(-1);
|
||||
}
|
||||
|
||||
@Ignore("b/313568482")
|
||||
@Test
|
||||
public void calcPoints_dataNotAvailableAtCycleStart_shouldIndicateStartOfData() {
|
||||
final UsageView usageView = mock(UsageView.class);
|
||||
final ArgumentCaptor<SparseIntArray> pointsCaptor =
|
||||
ArgumentCaptor.forClass(SparseIntArray.class);
|
||||
createTestNetworkData();
|
||||
mPreference.setTime(
|
||||
mNetworkCycleChartData.getTotal().getStartTime(),
|
||||
mNetworkCycleChartData.getTotal().getEndTime());
|
||||
mPreference.setNetworkCycleData(mNetworkCycleChartData);
|
||||
|
||||
mPreference.calcPoints(usageView, mNetworkCycleData.subList(2, 7));
|
||||
|
||||
verify(usageView).addPath(pointsCaptor.capture());
|
||||
final SparseIntArray points = pointsCaptor.getValue();
|
||||
// indicator that no data is available
|
||||
assertThat(points.keyAt(1)).isEqualTo(points.keyAt(2) - 1);
|
||||
assertThat(points.valueAt(1)).isEqualTo(-1);
|
||||
}
|
||||
|
||||
@Ignore("b/313568482")
|
||||
@Test
|
||||
public void calcPoints_shouldNotDrawPointForFutureDate() {
|
||||
final UsageView usageView = mock(UsageView.class);
|
||||
final ArgumentCaptor<SparseIntArray> pointsCaptor =
|
||||
ArgumentCaptor.forClass(SparseIntArray.class);
|
||||
final long tonight = System.currentTimeMillis() + TimeUnit.HOURS.toMillis(12);
|
||||
mNetworkCycleData = new ArrayList<>();
|
||||
// add test usage data for last 5 days
|
||||
mNetworkCycleData.add(new NetworkUsageData(
|
||||
tonight - TimeUnit.DAYS.toMillis(5),
|
||||
tonight - TimeUnit.DAYS.toMillis(4),
|
||||
743823454L));
|
||||
mNetworkCycleData.add(new NetworkUsageData(
|
||||
tonight - TimeUnit.DAYS.toMillis(4),
|
||||
tonight - TimeUnit.DAYS.toMillis(3),
|
||||
64396L));
|
||||
mNetworkCycleData.add(new NetworkUsageData(
|
||||
tonight - TimeUnit.DAYS.toMillis(3),
|
||||
tonight - TimeUnit.DAYS.toMillis(2),
|
||||
2832L));
|
||||
mNetworkCycleData.add(new NetworkUsageData(
|
||||
tonight - TimeUnit.DAYS.toMillis(2),
|
||||
tonight - TimeUnit.DAYS.toMillis(1),
|
||||
83849690L));
|
||||
mNetworkCycleData.add(new NetworkUsageData(
|
||||
tonight - TimeUnit.DAYS.toMillis(1), tonight, 1883657L));
|
||||
// add test usage data for next 5 days
|
||||
mNetworkCycleData.add(new NetworkUsageData(
|
||||
tonight, tonight + TimeUnit.DAYS.toMillis(1), 0L));
|
||||
mNetworkCycleData.add(new NetworkUsageData(
|
||||
tonight + TimeUnit.DAYS.toMillis(1),
|
||||
tonight + TimeUnit.DAYS.toMillis(2),
|
||||
0L));
|
||||
mNetworkCycleData.add(new NetworkUsageData(
|
||||
tonight + TimeUnit.DAYS.toMillis(2),
|
||||
tonight + TimeUnit.DAYS.toMillis(3),
|
||||
0L));
|
||||
mNetworkCycleData.add(new NetworkUsageData(
|
||||
tonight + TimeUnit.DAYS.toMillis(3),
|
||||
tonight + TimeUnit.DAYS.toMillis(4),
|
||||
0L));
|
||||
mNetworkCycleData.add(new NetworkUsageData(
|
||||
tonight + TimeUnit.DAYS.toMillis(4),
|
||||
tonight + TimeUnit.DAYS.toMillis(5),
|
||||
0L));
|
||||
mNetworkCycleData.add(new NetworkUsageData(
|
||||
tonight + TimeUnit.DAYS.toMillis(5),
|
||||
tonight + TimeUnit.DAYS.toMillis(6),
|
||||
0L));
|
||||
|
||||
mNetworkCycleChartData = new NetworkCycleChartData(
|
||||
new NetworkUsageData(
|
||||
tonight - TimeUnit.DAYS.toMillis(5),
|
||||
tonight + TimeUnit.DAYS.toMillis(6),
|
||||
0),
|
||||
mNetworkCycleData
|
||||
);
|
||||
mPreference.setTime(
|
||||
mNetworkCycleChartData.getTotal().getStartTime(),
|
||||
mNetworkCycleChartData.getTotal().getEndTime());
|
||||
mPreference.setNetworkCycleData(mNetworkCycleChartData);
|
||||
|
||||
mPreference.calcPoints(usageView, mNetworkCycleData);
|
||||
|
||||
verify(usageView).addPath(pointsCaptor.capture());
|
||||
final SparseIntArray points = pointsCaptor.getValue();
|
||||
// should only have 7 points: 1 test point indicating the start of data, starting point 0,
|
||||
// and 5 actual data point for each day
|
||||
assertThat(points.size()).isEqualTo(7);
|
||||
assertThat(points.keyAt(0)).isEqualTo(-1);
|
||||
assertThat(points.keyAt(1)).isEqualTo(0);
|
||||
assertThat(points.keyAt(2)).isEqualTo(TimeUnit.DAYS.toMinutes(1));
|
||||
assertThat(points.keyAt(3)).isEqualTo(TimeUnit.DAYS.toMinutes(2));
|
||||
assertThat(points.keyAt(4)).isEqualTo(TimeUnit.DAYS.toMinutes(3));
|
||||
assertThat(points.keyAt(5)).isEqualTo(TimeUnit.DAYS.toMinutes(4));
|
||||
assertThat(points.keyAt(6)).isEqualTo(TimeUnit.DAYS.toMinutes(5));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void notifyChange_nonEmptyDataUsage_shouldHaveSingleContentDescription() {
|
||||
final UsageView chart = (UsageView) mHolder.findViewById(R.id.data_usage);
|
||||
final TextView labelTop = (TextView) mHolder.findViewById(R.id.label_top);
|
||||
final TextView labelMiddle = (TextView) mHolder.findViewById(R.id.label_middle);
|
||||
final TextView labelBottom = (TextView) mHolder.findViewById(R.id.label_bottom);
|
||||
final TextView labelStart = (TextView) mHolder.findViewById(R.id.label_start);
|
||||
final TextView labelEnd = (TextView) mHolder.findViewById(R.id.label_end);
|
||||
createTestNetworkData();
|
||||
mPreference.setTime(
|
||||
mNetworkCycleChartData.getTotal().getStartTime(),
|
||||
mNetworkCycleChartData.getTotal().getEndTime());
|
||||
mPreference.setNetworkCycleData(mNetworkCycleChartData);
|
||||
|
||||
mPreference.onBindViewHolder(mHolder);
|
||||
|
||||
assertThat(chart.getContentDescription()).isNotNull();
|
||||
assertThat(labelTop.getContentDescription()).isNull();
|
||||
assertThat(labelMiddle.getContentDescription()).isNull();
|
||||
assertThat(labelBottom.getContentDescription()).isNull();
|
||||
assertThat(labelStart.getContentDescription()).isNull();
|
||||
assertThat(labelEnd.getContentDescription()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDensedStatsData_someSamePercentageNodes_getDifferentPercentageNodes() {
|
||||
createSomeSamePercentageNetworkData();
|
||||
final List<DataUsageSummaryNode> densedStatsData =
|
||||
mPreference.getDensedStatsData(mNetworkCycleData);
|
||||
|
||||
assertThat(mNetworkCycleData.size()).isEqualTo(8);
|
||||
assertThat(densedStatsData.size()).isEqualTo(3);
|
||||
assertThat(densedStatsData.get(0).getDataUsagePercentage()).isEqualTo(33);
|
||||
assertThat(densedStatsData.get(1).getDataUsagePercentage()).isEqualTo(99);
|
||||
assertThat(densedStatsData.get(2).getDataUsagePercentage()).isEqualTo(100);
|
||||
}
|
||||
|
||||
private void createTestNetworkData() {
|
||||
mNetworkCycleData = new ArrayList<>();
|
||||
// create 10 arbitrary network data
|
||||
mNetworkCycleData.add(new NetworkUsageData(1521583200000L, 1521586800000L, 743823454L));
|
||||
mNetworkCycleData.add(new NetworkUsageData(1521586800000L, 1521590400000L, 64396L));
|
||||
mNetworkCycleData.add(new NetworkUsageData(1521590400000L, 1521655200000L, 2832L));
|
||||
mNetworkCycleData.add(new NetworkUsageData(1521655200000L, 1521658800000L, 83849690L));
|
||||
mNetworkCycleData.add(new NetworkUsageData(1521658800000L, 1521662400000L, 1883657L));
|
||||
mNetworkCycleData.add(new NetworkUsageData(1521662400000L, 1521666000000L, 705259L));
|
||||
mNetworkCycleData.add(new NetworkUsageData(1521666000000L, 1521669600000L, 216169L));
|
||||
mNetworkCycleData.add(new NetworkUsageData(1521669600000L, 1521673200000L, 6069175L));
|
||||
mNetworkCycleData.add(new NetworkUsageData(1521673200000L, 1521676800000L, 120389L));
|
||||
mNetworkCycleData.add(new NetworkUsageData(1521676800000L, 1521678800000L, 29947L));
|
||||
|
||||
mNetworkCycleChartData = new NetworkCycleChartData(
|
||||
new NetworkUsageData(TIMESTAMP_START, TIMESTAMP_END, 0),
|
||||
mNetworkCycleData
|
||||
);
|
||||
}
|
||||
|
||||
private void createSomeSamePercentageNetworkData() {
|
||||
mNetworkCycleData = new ArrayList<>();
|
||||
mNetworkCycleData.add(new NetworkUsageData(1521583200000L, 1521586800000L, 100)); //33%
|
||||
mNetworkCycleData.add(new NetworkUsageData(1521586800000L, 1521590400000L, 1)); //33%
|
||||
mNetworkCycleData.add(new NetworkUsageData(1521590400000L, 1521655200000L, 0)); //33%
|
||||
mNetworkCycleData.add(new NetworkUsageData(1521655200000L, 1521658800000L, 0)); //33%
|
||||
mNetworkCycleData.add(new NetworkUsageData(1521658800000L, 1521662400000L, 200)); //99%
|
||||
mNetworkCycleData.add(new NetworkUsageData(1521662400000L, 1521666000000L, 1)); //99%
|
||||
mNetworkCycleData.add(new NetworkUsageData(1521666000000L, 1521669600000L, 1)); //100
|
||||
mNetworkCycleData.add(new NetworkUsageData(1521669600000L, 1521673200000L, 0)); //100%
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.datausage;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.NetworkStats;
|
||||
import android.net.NetworkTemplate;
|
||||
|
||||
import com.android.settingslib.net.DataUsageController;
|
||||
|
||||
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;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class DataUsagePreferenceTest {
|
||||
|
||||
@Mock
|
||||
private DataUsageController mController;
|
||||
|
||||
private Context mContext;
|
||||
private DataUsagePreference mPreference;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mPreference = spy(new DataUsagePreference(mContext, null /* attrs */));
|
||||
doReturn(mController).when(mPreference).getDataUsageController();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setTemplate_noDataUsage_shouldDisablePreference() {
|
||||
doReturn(0L).when(mController).getHistoricalUsageLevel(any(NetworkTemplate.class));
|
||||
|
||||
mPreference.setTemplate(new NetworkTemplate.Builder(NetworkTemplate.MATCH_MOBILE)
|
||||
.setMeteredness(NetworkStats.METERED_YES).build(),
|
||||
5 /* subId */);
|
||||
|
||||
verify(mPreference).setEnabled(false);
|
||||
verify(mPreference).setIntent(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setTemplate_hasDataUsage_shouldNotDisablePreference() {
|
||||
doReturn(200L).when(mController).getHistoricalUsageLevel(any(NetworkTemplate.class));
|
||||
|
||||
mPreference.setTemplate(new NetworkTemplate.Builder(NetworkTemplate.MATCH_MOBILE)
|
||||
.setMeteredness(NetworkStats.METERED_YES).build(),
|
||||
5 /* subId */);
|
||||
|
||||
verify(mPreference, never()).setEnabled(false);
|
||||
verify(mPreference).setIntent(any(Intent.class));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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.datausage;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
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;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.os.UserManager;
|
||||
import android.telephony.SubscriptionManager;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.testutils.shadow.ShadowDashboardFragment;
|
||||
import com.android.settings.testutils.shadow.ShadowDataUsageUtils;
|
||||
import com.android.settings.testutils.shadow.ShadowUserManager;
|
||||
import com.android.settings.testutils.shadow.ShadowUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Spy;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowSubscriptionManager;
|
||||
|
||||
@Config(shadows = {
|
||||
ShadowUtils.class,
|
||||
ShadowDataUsageUtils.class,
|
||||
ShadowDashboardFragment.class,
|
||||
ShadowUserManager.class,
|
||||
})
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class DataUsageSummaryTest {
|
||||
@Rule
|
||||
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
@Spy
|
||||
Context mContext = ApplicationProvider.getApplicationContext();
|
||||
@Mock
|
||||
private UserManager mUserManager;
|
||||
|
||||
private DataUsageSummary mDataUsageSummary;
|
||||
|
||||
/**
|
||||
* This set up is contrived to get a passing test so that the build doesn't block without tests.
|
||||
* These tests should be updated as code gets refactored to improve testability.
|
||||
*/
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
|
||||
doReturn(false).when(mUserManager).isGuestUser();
|
||||
|
||||
ShadowUserManager.getShadow().setIsAdminUser(true);
|
||||
|
||||
Resources mResources = spy(mContext.getResources());
|
||||
doReturn(mResources).when(mContext).getResources();
|
||||
doReturn(true).when(mResources).getBoolean(R.bool.config_show_sim_info);
|
||||
|
||||
mDataUsageSummary = spy(new DataUsageSummary());
|
||||
doReturn(mContext).when(mDataUsageSummary).getContext();
|
||||
doNothing().when(mDataUsageSummary).enableProxySubscriptionManager(any());
|
||||
doReturn(true).when(mDataUsageSummary).removePreference(anyString());
|
||||
doNothing().when(mDataUsageSummary).addWifiSection();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void formatUsage_shouldLookLikeFormatFileSize() {
|
||||
final long usage = 2147483648L; // 2GB
|
||||
final String formattedUsage =
|
||||
DataUsageSummary.formatUsage(mContext, "^1", usage).toString();
|
||||
final CharSequence formattedInIECUnit = DataUsageUtils.formatDataUsage(mContext, usage);
|
||||
assertThat(formattedUsage).isEqualTo(formattedInIECUnit);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowSubscriptionManager.class)
|
||||
public void configuration_withSim_shouldShowMobileAndWifi() {
|
||||
ShadowDataUsageUtils.IS_MOBILE_DATA_SUPPORTED = true;
|
||||
ShadowDataUsageUtils.IS_WIFI_SUPPORTED = true;
|
||||
ShadowSubscriptionManager.setDefaultDataSubscriptionId(1);
|
||||
|
||||
final DataUsageSummary dataUsageSummary = spy(new DataUsageSummary());
|
||||
doNothing().when(dataUsageSummary).enableProxySubscriptionManager(any());
|
||||
doReturn(true).when(dataUsageSummary).hasActiveSubscription();
|
||||
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;
|
||||
|
||||
final DataUsageSummary dataUsageSummary = spy(new DataUsageSummary());
|
||||
doNothing().when(dataUsageSummary).enableProxySubscriptionManager(any());
|
||||
doReturn(false).when(dataUsageSummary).hasActiveSubscription();
|
||||
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;
|
||||
|
||||
final DataUsageSummary dataUsageSummary = spy(new DataUsageSummary());
|
||||
doNothing().when(dataUsageSummary).enableProxySubscriptionManager(any());
|
||||
doReturn(false).when(dataUsageSummary).hasActiveSubscription();
|
||||
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
|
||||
@Config(shadows = ShadowSubscriptionManager.class)
|
||||
public void configuration_invalidDataSusbscription_shouldShowWifiSectionOnly() {
|
||||
ShadowDataUsageUtils.IS_MOBILE_DATA_SUPPORTED = true;
|
||||
ShadowDataUsageUtils.IS_WIFI_SUPPORTED = true;
|
||||
ShadowSubscriptionManager.setDefaultDataSubscriptionId(
|
||||
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
||||
|
||||
final DataUsageSummary dataUsageSummary = spy(new DataUsageSummary());
|
||||
doNothing().when(dataUsageSummary).enableProxySubscriptionManager(any());
|
||||
doReturn(false).when(dataUsageSummary).hasActiveSubscription();
|
||||
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 onCreate_isNotGuestUser_shouldNotFinish() {
|
||||
doReturn(false).when(mUserManager).isGuestUser();
|
||||
|
||||
mDataUsageSummary.onCreate(null);
|
||||
|
||||
verify(mDataUsageSummary, never()).finish();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onCreate_isGuestUser_shouldFinish() {
|
||||
doReturn(true).when(mUserManager).isGuestUser();
|
||||
|
||||
mDataUsageSummary.onCreate(null);
|
||||
|
||||
verify(mDataUsageSummary).finish();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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.datausage;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
import android.app.usage.NetworkStatsManager;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.DataUnit;
|
||||
|
||||
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.shadows.ShadowApplication;
|
||||
import org.robolectric.shadows.ShadowPackageManager;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public final class DataUsageUtilsTest {
|
||||
|
||||
@Mock
|
||||
private TelephonyManager mTelephonyManager;
|
||||
@Mock
|
||||
private NetworkStatsManager mNetworkStatsManager;
|
||||
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
final ShadowApplication shadowContext = ShadowApplication.getInstance();
|
||||
mContext = RuntimeEnvironment.application;
|
||||
shadowContext.setSystemService(Context.TELEPHONY_SERVICE, mTelephonyManager);
|
||||
shadowContext.setSystemService(Context.NETWORK_STATS_SERVICE, mNetworkStatsManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mobileDataStatus_whenNetworkIsSupported() {
|
||||
when(mTelephonyManager.isDataCapable()).thenReturn(true);
|
||||
final boolean hasMobileData = DataUsageUtils.hasMobileData(mContext);
|
||||
assertThat(hasMobileData).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mobileDataStatus_whenNetworkIsNotSupported() {
|
||||
when(mTelephonyManager.isDataCapable()).thenReturn(false);
|
||||
final boolean hasMobileData = DataUsageUtils.hasMobileData(mContext);
|
||||
assertThat(hasMobileData).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void formatDataUsage_useIECUnit() {
|
||||
final CharSequence formattedDataUsage = DataUsageUtils.formatDataUsage(
|
||||
mContext, DataUnit.GIBIBYTES.toBytes(1));
|
||||
|
||||
assertThat(formattedDataUsage).isEqualTo("1.00 GB");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hasEthernet_shouldQueryEthernetSummaryForUser() throws Exception {
|
||||
ShadowPackageManager pm = shadowOf(RuntimeEnvironment.application.getPackageManager());
|
||||
pm.setSystemFeature(PackageManager.FEATURE_ETHERNET, true);
|
||||
final String subscriber = "TestSub";
|
||||
when(mTelephonyManager.getSubscriberId()).thenReturn(subscriber);
|
||||
|
||||
DataUsageUtils.hasEthernet(mContext);
|
||||
|
||||
verify(mNetworkStatsManager).querySummaryForUser(eq(ConnectivityManager.TYPE_ETHERNET),
|
||||
eq(subscriber), anyLong() /* startTime */, anyLong() /* endTime */);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
package com.android.settings.datausage;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.nullable;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.doNothing;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.os.Process;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.applications.AppStateBaseBridge;
|
||||
import com.android.settings.datausage.AppStateDataUsageBridge.DataUsageState;
|
||||
import com.android.settings.testutils.FakeFeatureFactory;
|
||||
import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
|
||||
import com.android.settings.testutils.shadow.ShadowRestrictedLockUtilsInternal;
|
||||
import com.android.settingslib.applications.ApplicationsState;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
||||
|
||||
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 org.robolectric.annotation.Implements;
|
||||
import org.robolectric.util.ReflectionHelpers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
@Config(shadows = {
|
||||
ShadowRestrictedLockUtils.class,
|
||||
ShadowRestrictedLockUtilsInternal.class,
|
||||
UnrestrictedDataAccessPreferenceControllerTest.ShadowAppStateBaseBridge.class
|
||||
})
|
||||
public class UnrestrictedDataAccessPreferenceControllerTest {
|
||||
@Mock
|
||||
private ApplicationsState mState;
|
||||
@Mock
|
||||
private ApplicationsState.Session mSession;
|
||||
|
||||
private Context mContext;
|
||||
private FakeFeatureFactory mFeatureFactory;
|
||||
private PreferenceManager mPreferenceManager;
|
||||
private PreferenceScreen mPreferenceScreen;
|
||||
private UnrestrictedDataAccess mFragment;
|
||||
private UnrestrictedDataAccessPreferenceController mController;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mContext = RuntimeEnvironment.application;
|
||||
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||
ReflectionHelpers.setStaticField(ApplicationsState.class, "sInstance", mState);
|
||||
when(mState.newSession(any())).thenReturn(mSession);
|
||||
mController = spy(new UnrestrictedDataAccessPreferenceController(mContext, "pref_key"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAddPreference_forApps_shouldBeTrue() {
|
||||
final int uid = Process.FIRST_APPLICATION_UID + 10;
|
||||
final AppEntry entry = createAppEntry(uid);
|
||||
assertThat(UnrestrictedDataAccessPreferenceController.shouldAddPreference(entry)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAddPreference_forNonApps_shouldBeFalse() {
|
||||
final int uid = Process.FIRST_APPLICATION_UID - 10;
|
||||
final AppEntry entry = createAppEntry(uid);
|
||||
assertThat(UnrestrictedDataAccessPreferenceController.shouldAddPreference(entry)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void logSpecialPermissionChange() {
|
||||
mController.logSpecialPermissionChange(true, "app");
|
||||
verify(mFeatureFactory.metricsFeatureProvider).action(nullable(Context.class),
|
||||
eq(MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_UNL_DATA_ALLOW), eq("app"));
|
||||
|
||||
mController.logSpecialPermissionChange(false, "app");
|
||||
verify(mFeatureFactory.metricsFeatureProvider).action(nullable(Context.class),
|
||||
eq(MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_UNL_DATA_DENY), eq("app"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onRebuildComplete_restricted_shouldBeDisabled() {
|
||||
mFragment = spy(new UnrestrictedDataAccess());
|
||||
doNothing().when(mFragment).setLoading(anyBoolean(), anyBoolean());
|
||||
mController.setParentFragment(mFragment);
|
||||
mPreferenceManager = new PreferenceManager(mContext);
|
||||
mPreferenceScreen = spy(mPreferenceManager.createPreferenceScreen(mContext));
|
||||
doReturn(mPreferenceManager).when(mFragment).getPreferenceManager();
|
||||
doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
|
||||
doReturn(0).when(mPreferenceScreen).getPreferenceCount();
|
||||
final DataSaverBackend dataSaverBackend = mock(DataSaverBackend.class);
|
||||
ReflectionHelpers.setField(mController, "mDataSaverBackend", dataSaverBackend);
|
||||
ReflectionHelpers.setField(mController, "mScreen", mPreferenceScreen);
|
||||
|
||||
final String testPkg1 = "com.example.one";
|
||||
final String testPkg2 = "com.example.two";
|
||||
ShadowRestrictedLockUtilsInternal.setRestrictedPkgs(testPkg2);
|
||||
|
||||
doAnswer((invocation) -> {
|
||||
final UnrestrictedDataAccessPreference preference = invocation.getArgument(0);
|
||||
final AppEntry entry = preference.getEntry();
|
||||
// Verify preference is disabled by admin and the summary is changed accordingly.
|
||||
if (testPkg1.equals(entry.info.packageName)) {
|
||||
assertThat(preference.isDisabledByAdmin()).isFalse();
|
||||
assertThat(preference.getSummary()).isEqualTo("");
|
||||
} else if (testPkg2.equals(entry.info.packageName)) {
|
||||
assertThat(preference.isDisabledByAdmin()).isTrue();
|
||||
assertThat(preference.getSummary()).isEqualTo(
|
||||
mContext.getString(
|
||||
com.android.settingslib.widget.restricted.R.string.disabled_by_admin));
|
||||
}
|
||||
assertThat(preference.isChecked()).isFalse();
|
||||
preference.performClick();
|
||||
// Verify that when the preference is clicked, support details intent is launched
|
||||
// if the preference is disabled by admin, otherwise the switch is toggled.
|
||||
if (testPkg1.equals(entry.info.packageName)) {
|
||||
assertThat(preference.isChecked()).isTrue();
|
||||
assertThat(ShadowRestrictedLockUtils.hasAdminSupportDetailsIntentLaunched())
|
||||
.isFalse();
|
||||
} else if (testPkg2.equals(entry.info.packageName)) {
|
||||
assertThat(preference.isChecked()).isFalse();
|
||||
assertThat(ShadowRestrictedLockUtils.hasAdminSupportDetailsIntentLaunched())
|
||||
.isTrue();
|
||||
}
|
||||
ShadowRestrictedLockUtils.clearAdminSupportDetailsIntentLaunch();
|
||||
return null;
|
||||
}).when(mPreferenceScreen).addPreference(any(UnrestrictedDataAccessPreference.class));
|
||||
|
||||
mController.onRebuildComplete(createAppEntries(testPkg1, testPkg2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onRebuildComplete_ecmRestricted_shouldBeDisabled() {
|
||||
mFragment = spy(new UnrestrictedDataAccess());
|
||||
mContext = spy(mContext);
|
||||
doNothing().when(mFragment).setLoading(anyBoolean(), anyBoolean());
|
||||
mController.setParentFragment(mFragment);
|
||||
mPreferenceManager = new PreferenceManager(mContext);
|
||||
mPreferenceScreen = spy(mPreferenceManager.createPreferenceScreen(mContext));
|
||||
doReturn(mPreferenceManager).when(mFragment).getPreferenceManager();
|
||||
doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
|
||||
doReturn(0).when(mPreferenceScreen).getPreferenceCount();
|
||||
final DataSaverBackend dataSaverBackend = mock(DataSaverBackend.class);
|
||||
ReflectionHelpers.setField(mController, "mDataSaverBackend", dataSaverBackend);
|
||||
ReflectionHelpers.setField(mController, "mScreen", mPreferenceScreen);
|
||||
|
||||
final String testPkg = "com.example.disabled";
|
||||
doNothing().when(mContext).startActivity(any());
|
||||
ShadowRestrictedLockUtilsInternal.setEcmRestrictedPkgs(testPkg);
|
||||
|
||||
doAnswer((invocation) -> {
|
||||
final UnrestrictedDataAccessPreference preference = invocation.getArgument(0);
|
||||
// Verify preference is disabled by ecm and the summary is changed accordingly.
|
||||
assertThat(preference.isDisabledByEcm()).isTrue();
|
||||
assertThat(preference.getSummary().toString()).isEqualTo(
|
||||
mContext.getString(
|
||||
com.android.settingslib.R.string.disabled_by_app_ops_text));
|
||||
assertThat(preference.isChecked()).isFalse();
|
||||
preference.performClick();
|
||||
// Verify that when the preference is clicked, ecm details intent is launched
|
||||
assertThat(preference.isChecked()).isFalse();
|
||||
verify(mContext).startActivity(any());
|
||||
|
||||
return null;
|
||||
}).when(mPreferenceScreen).addPreference(any(UnrestrictedDataAccessPreference.class));
|
||||
|
||||
mController.onRebuildComplete(createAppEntries(testPkg));
|
||||
verify(mPreferenceScreen).addPreference(any(UnrestrictedDataAccessPreference.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onRebuildComplete_ecmNotRestricted_notDisabled() {
|
||||
mFragment = spy(new UnrestrictedDataAccess());
|
||||
mContext = spy(mContext);
|
||||
doNothing().when(mFragment).setLoading(anyBoolean(), anyBoolean());
|
||||
mController.setParentFragment(mFragment);
|
||||
mPreferenceManager = new PreferenceManager(mContext);
|
||||
mPreferenceScreen = spy(mPreferenceManager.createPreferenceScreen(mContext));
|
||||
doReturn(mPreferenceManager).when(mFragment).getPreferenceManager();
|
||||
doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
|
||||
doReturn(0).when(mPreferenceScreen).getPreferenceCount();
|
||||
final DataSaverBackend dataSaverBackend = mock(DataSaverBackend.class);
|
||||
ReflectionHelpers.setField(mController, "mDataSaverBackend", dataSaverBackend);
|
||||
ReflectionHelpers.setField(mController, "mScreen", mPreferenceScreen);
|
||||
|
||||
final String testPkg = "com.example.enabled";
|
||||
doNothing().when(mContext).startActivity(any());
|
||||
ShadowRestrictedLockUtilsInternal.setEcmRestrictedPkgs();
|
||||
|
||||
doAnswer((invocation) -> {
|
||||
final UnrestrictedDataAccessPreference preference = invocation.getArgument(0);
|
||||
assertThat(preference.isDisabledByEcm()).isFalse();
|
||||
assertThat(preference.getSummary()).isEqualTo("");
|
||||
assertThat(preference.isChecked()).isFalse();
|
||||
preference.performClick();
|
||||
// Verify that when the preference is clicked, ecm details intent is not launched
|
||||
assertThat(preference.isChecked()).isTrue();
|
||||
verify(mContext, never()).startActivity(any());
|
||||
|
||||
return null;
|
||||
}).when(mPreferenceScreen).addPreference(any(UnrestrictedDataAccessPreference.class));
|
||||
|
||||
mController.onRebuildComplete(createAppEntries(testPkg));
|
||||
verify(mPreferenceScreen).addPreference(any(UnrestrictedDataAccessPreference.class));
|
||||
}
|
||||
|
||||
private ArrayList<AppEntry> createAppEntries(String... packageNames) {
|
||||
final ArrayList<AppEntry> appEntries = new ArrayList<>();
|
||||
for (int i = 0; i < packageNames.length; ++i) {
|
||||
final ApplicationInfo info = new ApplicationInfo();
|
||||
info.packageName = packageNames[i];
|
||||
info.uid = Process.FIRST_APPLICATION_UID + i;
|
||||
info.sourceDir = info.packageName;
|
||||
final AppEntry appEntry = spy(new AppEntry(mContext, info, i));
|
||||
appEntry.extraInfo = new DataUsageState(false, false);
|
||||
doNothing().when(appEntry).ensureLabel(any(Context.class));
|
||||
ReflectionHelpers.setField(appEntry, "info", info);
|
||||
appEntries.add(appEntry);
|
||||
}
|
||||
return appEntries;
|
||||
}
|
||||
|
||||
private AppEntry createAppEntry(int uid) {
|
||||
final ApplicationInfo info = new ApplicationInfo();
|
||||
info.packageName = "com.example.three";
|
||||
info.uid = uid;
|
||||
info.sourceDir = info.packageName;
|
||||
return new AppEntry(mContext, info, uid);
|
||||
}
|
||||
|
||||
@Implements(AppStateBaseBridge.class)
|
||||
public static class ShadowAppStateBaseBridge {
|
||||
|
||||
public void __constructor__(ApplicationsState appState,
|
||||
AppStateBaseBridge.Callback callback) {
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user