Merge "Add policy transparency for metered data related settings."
This commit is contained in:
committed by
Android (Google) Code Review
commit
67ddb0ae00
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
<PreferenceScreen
|
<PreferenceScreen
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:settings="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:key="app_data_usage_screen"
|
||||||
android:title="@string/data_usage_app_summary_title">
|
android:title="@string/data_usage_app_summary_title">
|
||||||
|
|
||||||
<com.android.settings.datausage.SpinnerPreference
|
<com.android.settings.datausage.SpinnerPreference
|
||||||
@@ -50,15 +52,19 @@
|
|||||||
android:key="app_settings"
|
android:key="app_settings"
|
||||||
android:title="@string/data_usage_app_settings" />
|
android:title="@string/data_usage_app_settings" />
|
||||||
|
|
||||||
<SwitchPreference
|
<com.android.settingslib.RestrictedSwitchPreference
|
||||||
android:key="restrict_background"
|
android:key="restrict_background"
|
||||||
android:title="@string/data_usage_app_restrict_background"
|
android:title="@string/data_usage_app_restrict_background"
|
||||||
android:summary="@string/data_usage_app_restrict_background_summary" />
|
android:summary="@string/data_usage_app_restrict_background_summary"
|
||||||
|
settings:useAdditionalSummary="true"
|
||||||
|
settings:restrictedSwitchSummary="@string/disabled_by_admin" />
|
||||||
|
|
||||||
<SwitchPreference
|
<com.android.settingslib.RestrictedSwitchPreference
|
||||||
android:key="unrestricted_data_saver"
|
android:key="unrestricted_data_saver"
|
||||||
android:title="@string/unrestricted_app_title"
|
android:title="@string/unrestricted_app_title"
|
||||||
android:summary="@string/unrestricted_app_summary" />
|
android:summary="@string/unrestricted_app_summary"
|
||||||
|
settings:useAdditionalSummary="true"
|
||||||
|
settings:restrictedSwitchSummary="@string/disabled_by_admin" />
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
@@ -33,7 +33,6 @@ import android.os.Bundle;
|
|||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.support.annotation.VisibleForTesting;
|
import android.support.annotation.VisibleForTesting;
|
||||||
import android.support.v14.preference.SwitchPreference;
|
|
||||||
import android.support.v7.preference.Preference;
|
import android.support.v7.preference.Preference;
|
||||||
import android.support.v7.preference.PreferenceCategory;
|
import android.support.v7.preference.PreferenceCategory;
|
||||||
import android.text.format.Formatter;
|
import android.text.format.Formatter;
|
||||||
@@ -48,6 +47,9 @@ import com.android.settings.R;
|
|||||||
import com.android.settings.applications.AppInfoBase;
|
import com.android.settings.applications.AppInfoBase;
|
||||||
import com.android.settings.widget.EntityHeaderController;
|
import com.android.settings.widget.EntityHeaderController;
|
||||||
import com.android.settingslib.AppItem;
|
import com.android.settingslib.AppItem;
|
||||||
|
import com.android.settingslib.RestrictedLockUtils;
|
||||||
|
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||||
|
import com.android.settingslib.RestrictedSwitchPreference;
|
||||||
import com.android.settingslib.net.ChartData;
|
import com.android.settingslib.net.ChartData;
|
||||||
import com.android.settingslib.net.ChartDataLoader;
|
import com.android.settingslib.net.ChartDataLoader;
|
||||||
import com.android.settingslib.net.UidDetail;
|
import com.android.settingslib.net.UidDetail;
|
||||||
@@ -80,7 +82,7 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
|
|||||||
private Preference mForegroundUsage;
|
private Preference mForegroundUsage;
|
||||||
private Preference mBackgroundUsage;
|
private Preference mBackgroundUsage;
|
||||||
private Preference mAppSettings;
|
private Preference mAppSettings;
|
||||||
private SwitchPreference mRestrictBackground;
|
private RestrictedSwitchPreference mRestrictBackground;
|
||||||
private PreferenceCategory mAppList;
|
private PreferenceCategory mAppList;
|
||||||
|
|
||||||
private Drawable mIcon;
|
private Drawable mIcon;
|
||||||
@@ -97,7 +99,7 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
|
|||||||
private AppItem mAppItem;
|
private AppItem mAppItem;
|
||||||
private Intent mAppSettingsIntent;
|
private Intent mAppSettingsIntent;
|
||||||
private SpinnerPreference mCycle;
|
private SpinnerPreference mCycle;
|
||||||
private SwitchPreference mUnrestrictedData;
|
private RestrictedSwitchPreference mUnrestrictedData;
|
||||||
private DataSaverBackend mDataSaverBackend;
|
private DataSaverBackend mDataSaverBackend;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -160,9 +162,11 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
|
|||||||
removePreference(KEY_UNRESTRICTED_DATA);
|
removePreference(KEY_UNRESTRICTED_DATA);
|
||||||
removePreference(KEY_RESTRICT_BACKGROUND);
|
removePreference(KEY_RESTRICT_BACKGROUND);
|
||||||
} else {
|
} else {
|
||||||
mRestrictBackground = (SwitchPreference) findPreference(KEY_RESTRICT_BACKGROUND);
|
mRestrictBackground = (RestrictedSwitchPreference) findPreference(
|
||||||
|
KEY_RESTRICT_BACKGROUND);
|
||||||
mRestrictBackground.setOnPreferenceChangeListener(this);
|
mRestrictBackground.setOnPreferenceChangeListener(this);
|
||||||
mUnrestrictedData = (SwitchPreference) findPreference(KEY_UNRESTRICTED_DATA);
|
mUnrestrictedData = (RestrictedSwitchPreference) findPreference(
|
||||||
|
KEY_UNRESTRICTED_DATA);
|
||||||
mUnrestrictedData.setOnPreferenceChangeListener(this);
|
mUnrestrictedData.setOnPreferenceChangeListener(this);
|
||||||
}
|
}
|
||||||
mDataSaverBackend = new DataSaverBackend(getContext());
|
mDataSaverBackend = new DataSaverBackend(getContext());
|
||||||
@@ -261,8 +265,11 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updatePrefs(boolean restrictBackground, boolean unrestrictData) {
|
private void updatePrefs(boolean restrictBackground, boolean unrestrictData) {
|
||||||
|
final EnforcedAdmin admin = RestrictedLockUtils.checkIfMeteredDataRestricted(
|
||||||
|
getContext(), mPackageName, UserHandle.getUserId(mAppItem.key));
|
||||||
if (mRestrictBackground != null) {
|
if (mRestrictBackground != null) {
|
||||||
mRestrictBackground.setChecked(!restrictBackground);
|
mRestrictBackground.setChecked(!restrictBackground);
|
||||||
|
mRestrictBackground.setDisabledByAdmin(admin);
|
||||||
}
|
}
|
||||||
if (mUnrestrictedData != null) {
|
if (mUnrestrictedData != null) {
|
||||||
if (restrictBackground) {
|
if (restrictBackground) {
|
||||||
@@ -270,6 +277,7 @@ public class AppDataUsage extends DataUsageBase implements Preference.OnPreferen
|
|||||||
} else {
|
} else {
|
||||||
mUnrestrictedData.setVisible(true);
|
mUnrestrictedData.setVisible(true);
|
||||||
mUnrestrictedData.setChecked(unrestrictData);
|
mUnrestrictedData.setChecked(unrestrictData);
|
||||||
|
mUnrestrictedData.setDisabledByAdmin(admin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
package com.android.settings.datausage;
|
package com.android.settings.datausage;
|
||||||
|
|
||||||
|
import static com.android.settingslib.RestrictedLockUtils.checkIfMeteredDataRestricted;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -37,6 +39,8 @@ import com.android.settings.core.FeatureFlags;
|
|||||||
import com.android.settings.datausage.AppStateDataUsageBridge.DataUsageState;
|
import com.android.settings.datausage.AppStateDataUsageBridge.DataUsageState;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
import com.android.settings.widget.AppSwitchPreference;
|
import com.android.settings.widget.AppSwitchPreference;
|
||||||
|
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||||
|
import com.android.settingslib.RestrictedPreferenceHelper;
|
||||||
import com.android.settingslib.applications.ApplicationsState;
|
import com.android.settingslib.applications.ApplicationsState;
|
||||||
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
||||||
import com.android.settingslib.applications.ApplicationsState.AppFilter;
|
import com.android.settingslib.applications.ApplicationsState.AppFilter;
|
||||||
@@ -172,6 +176,8 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment
|
|||||||
preference.setOnPreferenceChangeListener(this);
|
preference.setOnPreferenceChangeListener(this);
|
||||||
getPreferenceScreen().addPreference(preference);
|
getPreferenceScreen().addPreference(preference);
|
||||||
} else {
|
} else {
|
||||||
|
preference.setDisabledByAdmin(checkIfMeteredDataRestricted(getContext(),
|
||||||
|
entry.info.packageName, UserHandle.getUserId(entry.info.uid)));
|
||||||
preference.reuse();
|
preference.reuse();
|
||||||
}
|
}
|
||||||
preference.setOrder(i);
|
preference.setOrder(i);
|
||||||
@@ -242,16 +248,22 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment
|
|||||||
return app != null && UserHandle.isApp(app.info.uid);
|
return app != null && UserHandle.isApp(app.info.uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AccessPreference extends AppSwitchPreference
|
@VisibleForTesting
|
||||||
|
class AccessPreference extends AppSwitchPreference
|
||||||
implements DataSaverBackend.Listener {
|
implements DataSaverBackend.Listener {
|
||||||
private final AppEntry mEntry;
|
private final AppEntry mEntry;
|
||||||
private final DataUsageState mState;
|
private final DataUsageState mState;
|
||||||
|
private final RestrictedPreferenceHelper mHelper;
|
||||||
|
|
||||||
public AccessPreference(final Context context, AppEntry entry) {
|
public AccessPreference(final Context context, AppEntry entry) {
|
||||||
super(context);
|
super(context);
|
||||||
|
setWidgetLayoutResource(R.layout.restricted_switch_widget);
|
||||||
|
mHelper = new RestrictedPreferenceHelper(context, this, null);
|
||||||
mEntry = entry;
|
mEntry = entry;
|
||||||
mState = (DataUsageState) mEntry.extraInfo;
|
mState = (DataUsageState) mEntry.extraInfo;
|
||||||
mEntry.ensureLabel(getContext());
|
mEntry.ensureLabel(getContext());
|
||||||
|
setDisabledByAdmin(checkIfMeteredDataRestricted(context, entry.info.packageName,
|
||||||
|
UserHandle.getUserId(entry.info.uid)));
|
||||||
setState();
|
setState();
|
||||||
if (mEntry.icon != null) {
|
if (mEntry.icon != null) {
|
||||||
setIcon(mEntry.icon);
|
setIcon(mEntry.icon);
|
||||||
@@ -291,12 +303,21 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void performClick() {
|
||||||
|
if (!mHelper.performClick()) {
|
||||||
|
super.performClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Sets UI state based on whitelist/blacklist status.
|
// Sets UI state based on whitelist/blacklist status.
|
||||||
private void setState() {
|
private void setState() {
|
||||||
setTitle(mEntry.label);
|
setTitle(mEntry.label);
|
||||||
if (mState != null) {
|
if (mState != null) {
|
||||||
setChecked(mState.isDataSaverWhitelisted);
|
setChecked(mState.isDataSaverWhitelisted);
|
||||||
if (mState.isDataSaverBlacklisted) {
|
if (isDisabledByAdmin()) {
|
||||||
|
setSummary(R.string.disabled_by_admin);
|
||||||
|
} else if (mState.isDataSaverBlacklisted) {
|
||||||
setSummary(R.string.restrict_background_blacklisted);
|
setSummary(R.string.restrict_background_blacklisted);
|
||||||
} else {
|
} else {
|
||||||
setSummary("");
|
setSummary("");
|
||||||
@@ -323,10 +344,21 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
holder.findViewById(android.R.id.widget_frame)
|
final boolean disabledByAdmin = isDisabledByAdmin();
|
||||||
.setVisibility(mState != null && mState.isDataSaverBlacklisted
|
final View widgetFrame = holder.findViewById(android.R.id.widget_frame);
|
||||||
|
if (disabledByAdmin) {
|
||||||
|
widgetFrame.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
widgetFrame.setVisibility(mState != null && mState.isDataSaverBlacklisted
|
||||||
? View.INVISIBLE : View.VISIBLE);
|
? View.INVISIBLE : View.VISIBLE);
|
||||||
|
}
|
||||||
super.onBindViewHolder(holder);
|
super.onBindViewHolder(holder);
|
||||||
|
|
||||||
|
mHelper.onBindViewHolder(holder);
|
||||||
|
holder.findViewById(R.id.restricted_icon).setVisibility(
|
||||||
|
disabledByAdmin ? View.VISIBLE : View.GONE);
|
||||||
|
holder.findViewById(android.R.id.switch_widget).setVisibility(
|
||||||
|
disabledByAdmin ? View.GONE : View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -348,6 +380,19 @@ public class UnrestrictedDataAccess extends SettingsPreferenceFragment
|
|||||||
reuse();
|
reuse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDisabledByAdmin(EnforcedAdmin admin) {
|
||||||
|
mHelper.setDisabledByAdmin(admin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDisabledByAdmin() {
|
||||||
|
return mHelper.isDisabledByAdmin();
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public AppEntry getEntryForTest() {
|
||||||
|
return mEntry;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -29,8 +29,8 @@ import static org.mockito.Mockito.verify;
|
|||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.net.NetworkPolicyManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v14.preference.SwitchPreference;
|
|
||||||
import android.support.v7.preference.PreferenceManager;
|
import android.support.v7.preference.PreferenceManager;
|
||||||
import android.support.v7.preference.PreferenceScreen;
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
@@ -40,8 +40,11 @@ import com.android.settings.TestConfig;
|
|||||||
import com.android.settings.testutils.FakeFeatureFactory;
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
|
import com.android.settings.testutils.shadow.ShadowEntityHeaderController;
|
||||||
|
import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
|
||||||
import com.android.settings.widget.EntityHeaderController;
|
import com.android.settings.widget.EntityHeaderController;
|
||||||
import com.android.settingslib.AppItem;
|
import com.android.settingslib.AppItem;
|
||||||
|
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||||
|
import com.android.settingslib.RestrictedSwitchPreference;
|
||||||
import com.android.settingslib.wrapper.PackageManagerWrapper;
|
import com.android.settingslib.wrapper.PackageManagerWrapper;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
@@ -57,7 +60,10 @@ import org.robolectric.util.ReflectionHelpers;
|
|||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
|
||||||
shadows = ShadowEntityHeaderController.class)
|
shadows = {
|
||||||
|
ShadowEntityHeaderController.class,
|
||||||
|
ShadowRestrictedLockUtils.class
|
||||||
|
})
|
||||||
public class AppDataUsageTest {
|
public class AppDataUsageTest {
|
||||||
|
|
||||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||||
@@ -134,7 +140,7 @@ public class AppDataUsageTest {
|
|||||||
public void changePreference_backgroundData_shouldUpdateUI() {
|
public void changePreference_backgroundData_shouldUpdateUI() {
|
||||||
mFragment = spy(new AppDataUsage());
|
mFragment = spy(new AppDataUsage());
|
||||||
final AppItem appItem = new AppItem(123456789);
|
final AppItem appItem = new AppItem(123456789);
|
||||||
final SwitchPreference pref = mock(SwitchPreference.class);
|
final RestrictedSwitchPreference pref = mock(RestrictedSwitchPreference.class);
|
||||||
final DataSaverBackend dataSaverBackend = mock(DataSaverBackend.class);
|
final DataSaverBackend dataSaverBackend = mock(DataSaverBackend.class);
|
||||||
ReflectionHelpers.setField(mFragment, "mAppItem", appItem);
|
ReflectionHelpers.setField(mFragment, "mAppItem", appItem);
|
||||||
ReflectionHelpers.setField(mFragment, "mRestrictBackground", pref);
|
ReflectionHelpers.setField(mFragment, "mRestrictBackground", pref);
|
||||||
@@ -146,4 +152,31 @@ public class AppDataUsageTest {
|
|||||||
|
|
||||||
verify(mFragment).updatePrefs();
|
verify(mFragment).updatePrefs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void updatePrefs_restrictedByAdmin_shouldDisablePreference() {
|
||||||
|
mFragment = spy(new AppDataUsage());
|
||||||
|
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);
|
||||||
|
|
||||||
|
ShadowRestrictedLockUtils.setRestricted(true);
|
||||||
|
doReturn(NetworkPolicyManager.POLICY_NONE).when(networkPolicyManager)
|
||||||
|
.getUidPolicy(testUid);
|
||||||
|
|
||||||
|
mFragment.updatePrefs();
|
||||||
|
|
||||||
|
verify(restrictBackgroundPref).setDisabledByAdmin(any(EnforcedAdmin.class));
|
||||||
|
verify(unrestrictedDataPref).setDisabledByAdmin(any(EnforcedAdmin.class));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,41 +16,68 @@
|
|||||||
package com.android.settings.datausage;
|
package com.android.settings.datausage;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
import static org.mockito.ArgumentMatchers.nullable;
|
import static org.mockito.ArgumentMatchers.nullable;
|
||||||
import static org.mockito.Matchers.eq;
|
import static org.mockito.Matchers.eq;
|
||||||
|
import static org.mockito.Mockito.doAnswer;
|
||||||
|
import static org.mockito.Mockito.doNothing;
|
||||||
|
import static org.mockito.Mockito.doReturn;
|
||||||
|
import static org.mockito.Mockito.spy;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.ApplicationInfo;
|
import android.content.pm.ApplicationInfo;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
|
import android.support.v7.preference.PreferenceManager;
|
||||||
|
import android.support.v7.preference.PreferenceScreen;
|
||||||
|
|
||||||
import com.android.internal.logging.nano.MetricsProto;
|
import com.android.internal.logging.nano.MetricsProto;
|
||||||
|
import com.android.settings.R;
|
||||||
import com.android.settings.TestConfig;
|
import com.android.settings.TestConfig;
|
||||||
|
import com.android.settings.datausage.AppStateDataUsageBridge.DataUsageState;
|
||||||
|
import com.android.settings.datausage.UnrestrictedDataAccess.AccessPreference;
|
||||||
import com.android.settings.testutils.FakeFeatureFactory;
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
import com.android.settings.testutils.SettingsRobolectricTestRunner;
|
||||||
import com.android.settingslib.applications.ApplicationsState;
|
import com.android.settings.testutils.shadow.ShadowRestrictedLockUtils;
|
||||||
|
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.robolectric.RuntimeEnvironment;
|
||||||
import org.robolectric.annotation.Config;
|
import org.robolectric.annotation.Config;
|
||||||
|
import org.robolectric.util.ReflectionHelpers;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@RunWith(SettingsRobolectricTestRunner.class)
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION,
|
||||||
|
shadows = {
|
||||||
|
ShadowRestrictedLockUtils.class
|
||||||
|
})
|
||||||
public class UnrestrictedDataAccessTest {
|
public class UnrestrictedDataAccessTest {
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private ApplicationsState.AppEntry mAppEntry;
|
private AppEntry mAppEntry;
|
||||||
private UnrestrictedDataAccess mFragment;
|
private UnrestrictedDataAccess mFragment;
|
||||||
private FakeFeatureFactory mFeatureFactory;
|
private FakeFeatureFactory mFeatureFactory;
|
||||||
|
@Mock
|
||||||
|
private PreferenceScreen mPreferenceScreen;
|
||||||
|
@Mock
|
||||||
|
private PreferenceManager mPreferenceManager;
|
||||||
|
@Mock
|
||||||
|
private DataSaverBackend mDataSaverBackend;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
mFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||||
mFragment = new UnrestrictedDataAccess();
|
mFragment = spy(new UnrestrictedDataAccess());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -80,4 +107,66 @@ public class UnrestrictedDataAccessTest {
|
|||||||
eq(MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_UNL_DATA_DENY), eq("app"));
|
eq(MetricsProto.MetricsEvent.APP_SPECIAL_PERMISSION_UNL_DATA_DENY), eq("app"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOnRebuildComplete_restricted_shouldBeDisabled() {
|
||||||
|
final Context context = RuntimeEnvironment.application;
|
||||||
|
doReturn(context).when(mFragment).getContext();
|
||||||
|
doReturn(context).when(mPreferenceManager).getContext();
|
||||||
|
doReturn(true).when(mFragment).shouldAddPreference(any(AppEntry.class));
|
||||||
|
doNothing().when(mFragment).setLoading(anyBoolean(), anyBoolean());
|
||||||
|
doReturn(mPreferenceScreen).when(mFragment).getPreferenceScreen();
|
||||||
|
doReturn(mPreferenceManager).when(mFragment).getPreferenceManager();
|
||||||
|
ReflectionHelpers.setField(mFragment, "mDataSaverBackend", mDataSaverBackend);
|
||||||
|
|
||||||
|
final String testPkg1 = "com.example.one";
|
||||||
|
final String testPkg2 = "com.example.two";
|
||||||
|
ShadowRestrictedLockUtils.setRestrictedPkgs(testPkg2);
|
||||||
|
|
||||||
|
doAnswer((invocation) -> {
|
||||||
|
final AccessPreference preference = invocation.getArgument(0);
|
||||||
|
final AppEntry entry = preference.getEntryForTest();
|
||||||
|
// 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(
|
||||||
|
context.getString(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(AccessPreference.class));
|
||||||
|
mFragment.onRebuildComplete(createAppEntries(testPkg1, testPkg2));
|
||||||
|
}
|
||||||
|
|
||||||
|
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(RuntimeEnvironment.application,
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* 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.testutils.shadow;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import com.android.internal.util.ArrayUtils;
|
||||||
|
import com.android.settingslib.RestrictedLockUtils;
|
||||||
|
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||||
|
|
||||||
|
import org.robolectric.annotation.Implementation;
|
||||||
|
import org.robolectric.annotation.Implements;
|
||||||
|
|
||||||
|
@Implements(RestrictedLockUtils.class)
|
||||||
|
public class ShadowRestrictedLockUtils {
|
||||||
|
private static boolean isRestricted;
|
||||||
|
private static String[] restrictedPkgs;
|
||||||
|
private static boolean adminSupportDetailsIntentLaunched;
|
||||||
|
|
||||||
|
@Implementation
|
||||||
|
public static RestrictedLockUtils.EnforcedAdmin checkIfMeteredDataRestricted(Context context,
|
||||||
|
String packageName, int userId) {
|
||||||
|
if (isRestricted) {
|
||||||
|
return new EnforcedAdmin();
|
||||||
|
}
|
||||||
|
if (ArrayUtils.contains(restrictedPkgs, packageName)) {
|
||||||
|
return new EnforcedAdmin();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Implementation
|
||||||
|
public static void sendShowAdminSupportDetailsIntent(Context context, EnforcedAdmin admin) {
|
||||||
|
adminSupportDetailsIntentLaunched = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean hasAdminSupportDetailsIntentLaunched() {
|
||||||
|
return adminSupportDetailsIntentLaunched;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clearAdminSupportDetailsIntentLaunch() {
|
||||||
|
adminSupportDetailsIntentLaunched = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setRestricted(boolean restricted) {
|
||||||
|
isRestricted = restricted;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setRestrictedPkgs(String... pkgs) {
|
||||||
|
restrictedPkgs = pkgs;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user