DynamicDenylistManager shall not exist
Remove DynamicDenylistManager to avoid its conflicting behavior with our firewall. This stops the resetting of firewall policies on boot and for other reasons. The user is in control of these policies and doesn't need them to be unexpectedly reset. Issue: calyxos#2211 Test: Manual: Turn off Background network access for any app. Then, in Firewall, turn off another toggle like Wi-Fi. Reboot, and check the toggles. Background network access and Wi-Fi should still be off. Change-Id: Ie62ddfa3a893c9adf5d4fd0c8670235a5a51e03f
This commit is contained in:
committed by
Michael Bestas
parent
668fe20d73
commit
a8f79a720f
@@ -53,7 +53,6 @@ import androidx.preference.PreferenceCategory;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.deviceinfo.StorageWizardMoveConfirm;
|
||||
import com.android.settings.fuelgauge.datasaver.DynamicDenylistManager;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.applications.AppUtils;
|
||||
import com.android.settingslib.applications.ApplicationsState.Callbacks;
|
||||
@@ -362,8 +361,6 @@ public class AppStorageSettings extends AppInfoWithHeader
|
||||
mButtonsPref.setButton1Enabled(false);
|
||||
// Invoke uninstall or clear user data based on sysPackage
|
||||
String packageName = mAppEntry.info.packageName;
|
||||
DynamicDenylistManager.getInstance(getContext())
|
||||
.resetDenylistIfNeeded(packageName, /* force= */ false);
|
||||
Log.i(TAG, "Clearing user data for package : " + packageName);
|
||||
if (mClearDataObserver == null) {
|
||||
mClearDataObserver = new ClearUserDataObserver();
|
||||
|
||||
@@ -39,7 +39,6 @@ import androidx.appcompat.app.AlertDialog;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.fuelgauge.BatteryOptimizeUtils;
|
||||
import com.android.settings.fuelgauge.datasaver.DynamicDenylistManager;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -156,8 +155,6 @@ public class ResetAppsHelper implements DialogInterface.OnClickListener,
|
||||
}
|
||||
mAom.resetAllModes();
|
||||
BatteryOptimizeUtils.resetAppOptimizationMode(mContext, mIPm, mAom);
|
||||
DynamicDenylistManager.getInstance(mContext)
|
||||
.resetDenylistIfNeeded(/* packageName= */ null, /* force= */ true);
|
||||
final int[] restrictedUids = mNpm.getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND);
|
||||
final int currentUserId = ActivityManager.getCurrentUser();
|
||||
for (int uid : restrictedUids) {
|
||||
|
||||
@@ -50,7 +50,6 @@ import com.android.settings.R;
|
||||
import com.android.settings.applications.AppInfoBase;
|
||||
import com.android.settings.datausage.lib.AppDataUsageDetailsRepository;
|
||||
import com.android.settings.datausage.lib.NetworkTemplates;
|
||||
import com.android.settings.fuelgauge.datasaver.DynamicDenylistManager;
|
||||
import com.android.settings.network.SubscriptionUtil;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.AppItem;
|
||||
|
||||
@@ -23,7 +23,6 @@ import android.content.Context;
|
||||
import android.net.NetworkPolicyManager;
|
||||
import android.util.SparseIntArray;
|
||||
|
||||
import com.android.settings.fuelgauge.datasaver.DynamicDenylistManager;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
import com.android.settingslib.utils.ThreadUtils;
|
||||
@@ -40,7 +39,6 @@ public class DataSaverBackend {
|
||||
private final MetricsFeatureProvider mMetricsFeatureProvider;
|
||||
|
||||
private final NetworkPolicyManager mPolicyManager;
|
||||
private final DynamicDenylistManager mDynamicDenylistManager;
|
||||
private final ArrayList<Listener> mListeners = new ArrayList<>();
|
||||
private SparseIntArray mUidPolicies = new SparseIntArray();
|
||||
private boolean mAllowlistInitialized;
|
||||
@@ -52,7 +50,6 @@ public class DataSaverBackend {
|
||||
mContext = context.getApplicationContext();
|
||||
mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
|
||||
mPolicyManager = NetworkPolicyManager.from(mContext);
|
||||
mDynamicDenylistManager = DynamicDenylistManager.getInstance(mContext);
|
||||
}
|
||||
|
||||
public void addListener(Listener listener) {
|
||||
@@ -132,8 +129,7 @@ public class DataSaverBackend {
|
||||
|
||||
public boolean isDenylisted(int uid) {
|
||||
loadDenylist();
|
||||
return mUidPolicies.get(uid, POLICY_NONE) == POLICY_REJECT_METERED_BACKGROUND
|
||||
&& mDynamicDenylistManager.isInManualDenylist(uid);
|
||||
return mUidPolicies.get(uid, POLICY_NONE) == POLICY_REJECT_METERED_BACKGROUND;
|
||||
}
|
||||
|
||||
private void loadDenylist() {
|
||||
|
||||
@@ -26,7 +26,6 @@ import android.util.Log;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.fuelgauge.batterysaver.BatterySaverScheduleRadioButtonsController;
|
||||
import com.android.settings.fuelgauge.datasaver.DynamicDenylistManager;
|
||||
import com.android.settingslib.fuelgauge.BatterySaverUtils;
|
||||
|
||||
import java.util.List;
|
||||
@@ -51,7 +50,6 @@ public final class BatterySettingsMigrateChecker extends BroadcastReceiver {
|
||||
context = context.getApplicationContext();
|
||||
verifySaverConfiguration(context);
|
||||
verifyBatteryOptimizeModes(context);
|
||||
DynamicDenylistManager.getInstance(context).onBootComplete();
|
||||
}
|
||||
|
||||
/** Avoid users set important apps into the unexpected battery optimize modes */
|
||||
|
||||
@@ -1,276 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.fuelgauge.datasaver;
|
||||
|
||||
import static android.net.NetworkPolicyManager.POLICY_NONE;
|
||||
import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
|
||||
|
||||
import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.NetworkPolicyManager;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/** A class to dynamically manage per apps {@link NetworkPolicyManager} POLICY_ flags. */
|
||||
public class DynamicDenylistManager {
|
||||
|
||||
private static final String TAG = "DynamicDenylistManager";
|
||||
private static final String PREF_KEY_MANUAL_DENY = "manual_denylist_preference";
|
||||
private static final String PREF_KEY_DYNAMIC_DENY = "dynamic_denylist_preference";
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||
public static DynamicDenylistManager sInstance = null;
|
||||
|
||||
private final Context mContext;
|
||||
private final NetworkPolicyManager mNetworkPolicyManager;
|
||||
private final Object mLock = new Object();
|
||||
|
||||
@VisibleForTesting
|
||||
static final String PREF_KEY_MANUAL_DENYLIST_SYNCED = "manual_denylist_synced";
|
||||
|
||||
/** @return a DynamicDenylistManager object */
|
||||
public static DynamicDenylistManager getInstance(Context context) {
|
||||
synchronized (DynamicDenylistManager.class) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new DynamicDenylistManager(
|
||||
context, NetworkPolicyManager.from(context));
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
DynamicDenylistManager(Context context, NetworkPolicyManager networkPolicyManager) {
|
||||
mContext = context.getApplicationContext();
|
||||
mNetworkPolicyManager = networkPolicyManager;
|
||||
syncPolicyIfNeeded();
|
||||
}
|
||||
|
||||
/** Sync the policy from {@link NetworkPolicyManager} if needed. */
|
||||
private void syncPolicyIfNeeded() {
|
||||
if (getManualDenylistPref().contains(PREF_KEY_MANUAL_DENYLIST_SYNCED)) {
|
||||
Log.i(TAG, "syncPolicyIfNeeded() ignore synced manual denylist");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mNetworkPolicyManager == null) {
|
||||
Log.w(TAG, "syncPolicyIfNeeded: invalid mNetworkPolicyManager");
|
||||
return;
|
||||
}
|
||||
|
||||
final SharedPreferences.Editor editor = getManualDenylistPref().edit();
|
||||
final int[] existedUids = mNetworkPolicyManager
|
||||
.getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND);
|
||||
if (existedUids != null && existedUids.length != 0) {
|
||||
for (int uid : existedUids) {
|
||||
editor.putInt(String.valueOf(uid), POLICY_REJECT_METERED_BACKGROUND);
|
||||
}
|
||||
}
|
||||
editor.putInt(PREF_KEY_MANUAL_DENYLIST_SYNCED, POLICY_NONE).apply();
|
||||
}
|
||||
|
||||
/** Set policy flags for specific UID. */
|
||||
public void setUidPolicyLocked(int uid, int policy) {
|
||||
if (mNetworkPolicyManager == null) {
|
||||
Log.w(TAG, "setUidPolicyLocked: invalid mNetworkPolicyManager");
|
||||
return;
|
||||
}
|
||||
|
||||
Log.i(TAG, "setUidPolicyLocked: uid=" + uid + " policy=" + policy);
|
||||
synchronized (mLock) {
|
||||
mNetworkPolicyManager.setUidPolicy(uid, policy);
|
||||
}
|
||||
updateDenylistPref(uid, policy);
|
||||
}
|
||||
|
||||
/** Suggest a list of package to set as POLICY_REJECT. */
|
||||
public void setDenylist(Set<Integer> denylistTargetUids) {
|
||||
if (denylistTargetUids == null || mNetworkPolicyManager == null) {
|
||||
return;
|
||||
}
|
||||
final Set<Integer> manualDenylistUids = getDenylistAllUids(getManualDenylistPref());
|
||||
denylistTargetUids.removeAll(manualDenylistUids);
|
||||
|
||||
final Set<Integer> lastDynamicDenylistUids = getDenylistAllUids(getDynamicDenylistPref());
|
||||
if (lastDynamicDenylistUids.equals(denylistTargetUids)) {
|
||||
Log.i(TAG, "setDenylist() ignore the same denylist with size: "
|
||||
+ lastDynamicDenylistUids.size());
|
||||
return;
|
||||
}
|
||||
|
||||
final ArraySet<Integer> failedUids = new ArraySet<>();
|
||||
synchronized (mLock) {
|
||||
// Set new added UIDs into REJECT policy.
|
||||
for (Integer uidInteger : denylistTargetUids) {
|
||||
if (uidInteger == null) {
|
||||
continue;
|
||||
}
|
||||
final int uid = uidInteger.intValue();
|
||||
if (!lastDynamicDenylistUids.contains(uid)) {
|
||||
try {
|
||||
mNetworkPolicyManager.setUidPolicy(uid, POLICY_REJECT_METERED_BACKGROUND);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "failed to setUidPolicy(REJECT) for " + uid, e);
|
||||
failedUids.add(uid);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Unset removed UIDs back to NONE policy.
|
||||
for (int uid : lastDynamicDenylistUids) {
|
||||
if (!denylistTargetUids.contains(uid)) {
|
||||
try {
|
||||
mNetworkPolicyManager.setUidPolicy(uid, POLICY_NONE);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "failed to setUidPolicy(NONE) for " + uid, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Store target denied uids into DynamicDenylistPref.
|
||||
final SharedPreferences.Editor editor = getDynamicDenylistPref().edit();
|
||||
editor.clear();
|
||||
denylistTargetUids.forEach(uid -> {
|
||||
if (!failedUids.contains(uid)) {
|
||||
editor.putInt(String.valueOf(uid), POLICY_REJECT_METERED_BACKGROUND);
|
||||
}
|
||||
});
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
/** Return true if the target uid is in {@link #getManualDenylistPref()}. */
|
||||
public boolean isInManualDenylist(int uid) {
|
||||
return getManualDenylistPref().contains(String.valueOf(uid));
|
||||
}
|
||||
|
||||
/** Reset the UIDs in the denylist if needed. */
|
||||
public void resetDenylistIfNeeded(String packageName, boolean force) {
|
||||
if (!force && !SETTINGS_PACKAGE_NAME.equals(packageName)) {
|
||||
Log.w(TAG, "resetDenylistIfNeeded: invalid conditions");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mNetworkPolicyManager == null) {
|
||||
Log.w(TAG, "setUidPolicyLocked: invalid mNetworkPolicyManager");
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (mLock) {
|
||||
final int[] uids = mNetworkPolicyManager
|
||||
.getUidsWithPolicy(POLICY_REJECT_METERED_BACKGROUND);
|
||||
if (uids != null && uids.length != 0) {
|
||||
Log.i(TAG, "resetDenylistIfNeeded: " + Arrays.toString(uids));
|
||||
for (int uid : uids) {
|
||||
if (!getDenylistAllUids(getManualDenylistPref()).contains(uid)) {
|
||||
mNetworkPolicyManager.setUidPolicy(uid, POLICY_NONE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Log.w(TAG, "resetDenylistIfNeeded: there is no valid UIDs");
|
||||
}
|
||||
}
|
||||
clearSharedPreferences();
|
||||
}
|
||||
|
||||
/** Reset the POLICY_REJECT_METERED uids when device is boot completed. */
|
||||
public void onBootComplete() {
|
||||
resetDenylistIfNeeded(/* packageName= */ null, /* force= */ true);
|
||||
syncPolicyIfNeeded();
|
||||
}
|
||||
|
||||
/** Dump the data stored in the {@link SharedPreferences}. */
|
||||
public void dump(PrintWriter writer) {
|
||||
writer.println("Dump of DynamicDenylistManager:");
|
||||
final List<String> manualDenyList =
|
||||
getPackageNames(mContext, getDenylistAllUids(getManualDenylistPref()));
|
||||
writer.println("\tManualDenylist:");
|
||||
if (manualDenyList != null) {
|
||||
manualDenyList.forEach(packageName -> writer.println("\t\t" + packageName));
|
||||
writer.flush();
|
||||
}
|
||||
|
||||
final List<String> dynamicDenyList =
|
||||
getPackageNames(mContext, getDenylistAllUids(getDynamicDenylistPref()));
|
||||
writer.println("\tDynamicDenylist:");
|
||||
if (dynamicDenyList != null) {
|
||||
dynamicDenyList.forEach(packageName -> writer.println("\t\t" + packageName));
|
||||
writer.flush();
|
||||
}
|
||||
}
|
||||
|
||||
private Set<Integer> getDenylistAllUids(SharedPreferences sharedPreferences) {
|
||||
final ArraySet<Integer> uids = new ArraySet<>();
|
||||
for (String key : sharedPreferences.getAll().keySet()) {
|
||||
if (PREF_KEY_MANUAL_DENYLIST_SYNCED.equals(key)) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
uids.add(Integer.parseInt(key));
|
||||
} catch (NumberFormatException e) {
|
||||
Log.e(TAG, "getDenylistAllUids() unexpected format for " + key);
|
||||
}
|
||||
}
|
||||
return uids;
|
||||
}
|
||||
|
||||
void updateDenylistPref(int uid, int policy) {
|
||||
final String uidString = String.valueOf(uid);
|
||||
if (policy != POLICY_REJECT_METERED_BACKGROUND) {
|
||||
getManualDenylistPref().edit().remove(uidString).apply();
|
||||
} else {
|
||||
getManualDenylistPref().edit().putInt(uidString, policy).apply();
|
||||
}
|
||||
getDynamicDenylistPref().edit().remove(uidString).apply();
|
||||
}
|
||||
|
||||
void clearSharedPreferences() {
|
||||
Log.i(TAG, "clearSharedPreferences()");
|
||||
getManualDenylistPref().edit().clear().apply();
|
||||
getDynamicDenylistPref().edit().clear().apply();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
SharedPreferences getManualDenylistPref() {
|
||||
return mContext.getSharedPreferences(PREF_KEY_MANUAL_DENY, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
SharedPreferences getDynamicDenylistPref() {
|
||||
return mContext.getSharedPreferences(PREF_KEY_DYNAMIC_DENY, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
private static List<String> getPackageNames(Context context, Set<Integer> uids) {
|
||||
if (uids == null || uids.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
final PackageManager pm = context.getPackageManager();
|
||||
final List<String> packageNames = new ArrayList<>(uids.size());
|
||||
uids.forEach(uid -> packageNames.add(pm.getNameForUid(uid)));
|
||||
return packageNames;
|
||||
}
|
||||
}
|
||||
@@ -1,446 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.fuelgauge.datasaver;
|
||||
|
||||
import static android.net.NetworkPolicyManager.POLICY_NONE;
|
||||
import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
|
||||
|
||||
import static com.android.settings.Utils.SETTINGS_PACKAGE_NAME;
|
||||
import static com.android.settings.fuelgauge.datasaver.DynamicDenylistManager.PREF_KEY_MANUAL_DENYLIST_SYNCED;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.NetworkPolicyManager;
|
||||
import android.util.ArraySet;
|
||||
|
||||
import org.junit.After;
|
||||
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 java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class DynamicDenylistManagerTest {
|
||||
|
||||
private static final int[] EMPTY_ARRAY = new int[] {};
|
||||
private static final String FAKE_UID_1 = "1001";
|
||||
private static final String FAKE_UID_2 = "1002";
|
||||
private static final int FAKE_UID_1_INT = Integer.parseInt(FAKE_UID_1);
|
||||
private static final int FAKE_UID_2_INT = Integer.parseInt(FAKE_UID_2);
|
||||
|
||||
private SharedPreferences mManualDenyListPref;
|
||||
private SharedPreferences mDynamicDenyListPref;
|
||||
private DynamicDenylistManager mDynamicDenylistManager;
|
||||
|
||||
@Mock
|
||||
private NetworkPolicyManager mNetworkPolicyManager;
|
||||
@Mock
|
||||
private PackageManager mPackageManager;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
mDynamicDenylistManager.clearSharedPreferences();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void init_withoutExistedRejectPolicy_createWithExpectedValue() {
|
||||
initDynamicDenylistManager(EMPTY_ARRAY);
|
||||
|
||||
assertThat(mManualDenyListPref.getAll()).hasSize(1);
|
||||
assertTrue(mManualDenyListPref.contains(PREF_KEY_MANUAL_DENYLIST_SYNCED));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void init_withExistedRejectPolicy_createWithExpectedValue() {
|
||||
initDynamicDenylistManager(new int[] {FAKE_UID_1_INT, FAKE_UID_2_INT});
|
||||
|
||||
assertThat(mManualDenyListPref.getAll()).hasSize(3);
|
||||
assertTrue(mManualDenyListPref.contains(PREF_KEY_MANUAL_DENYLIST_SYNCED));
|
||||
assertTrue(mManualDenyListPref.contains(FAKE_UID_1));
|
||||
assertTrue(mManualDenyListPref.contains(FAKE_UID_2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getManualDenylistPref_initiated_containsExpectedValue() {
|
||||
initDynamicDenylistManager(EMPTY_ARRAY);
|
||||
|
||||
setupPreference(mManualDenyListPref, FAKE_UID_1);
|
||||
|
||||
assertTrue(mManualDenyListPref.contains(FAKE_UID_1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDynamicDenylistPref_initiated_containsExpectedValue() {
|
||||
initDynamicDenylistManager(EMPTY_ARRAY);
|
||||
|
||||
setupPreference(mDynamicDenyListPref, FAKE_UID_1);
|
||||
|
||||
assertTrue(mDynamicDenyListPref.contains(FAKE_UID_1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateManualDenylist_policyReject_addsUid() {
|
||||
initDynamicDenylistManager(EMPTY_ARRAY);
|
||||
|
||||
mDynamicDenylistManager.updateDenylistPref(FAKE_UID_1_INT,
|
||||
POLICY_REJECT_METERED_BACKGROUND);
|
||||
|
||||
assertTrue(mManualDenyListPref.contains(FAKE_UID_1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateManualDenylist_policyNone_removesUid() {
|
||||
initDynamicDenylistManager(EMPTY_ARRAY);
|
||||
setupPreference(mManualDenyListPref, FAKE_UID_1);
|
||||
assertTrue(mManualDenyListPref.contains(FAKE_UID_1));
|
||||
|
||||
mDynamicDenylistManager.updateDenylistPref(FAKE_UID_1_INT, POLICY_NONE);
|
||||
|
||||
assertFalse(mManualDenyListPref.contains(FAKE_UID_1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateManualDenylist_samePolicy_doNothing() {
|
||||
initDynamicDenylistManager(EMPTY_ARRAY);
|
||||
setupPreference(mManualDenyListPref, FAKE_UID_1);
|
||||
assertTrue(mManualDenyListPref.contains(FAKE_UID_1));
|
||||
assertThat(mManualDenyListPref.getAll()).hasSize(2);
|
||||
|
||||
mDynamicDenylistManager.updateDenylistPref(FAKE_UID_1_INT,
|
||||
POLICY_REJECT_METERED_BACKGROUND);
|
||||
|
||||
assertThat(mManualDenyListPref.getAll()).hasSize(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setUidPolicyLocked_invokeSetUidPolicy() {
|
||||
initDynamicDenylistManager(EMPTY_ARRAY);
|
||||
|
||||
mDynamicDenylistManager.setUidPolicyLocked(FAKE_UID_1_INT,
|
||||
POLICY_REJECT_METERED_BACKGROUND);
|
||||
|
||||
assertTrue(mManualDenyListPref.contains(FAKE_UID_1));
|
||||
verify(mNetworkPolicyManager).setUidPolicy(eq(FAKE_UID_1_INT),
|
||||
eq(POLICY_REJECT_METERED_BACKGROUND));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setDenylist_emptyListAndNoData_doNothing() {
|
||||
initDynamicDenylistManager(EMPTY_ARRAY);
|
||||
|
||||
setDenylist(Collections.emptySet());
|
||||
|
||||
verify(mNetworkPolicyManager, never()).setUidPolicy(anyInt(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setDenylist_uidDeniedAlready_doNothing() {
|
||||
initDynamicDenylistManager(new int[] {FAKE_UID_1_INT});
|
||||
final ArraySet uids = new ArraySet<>();
|
||||
uids.add(FAKE_UID_1_INT);
|
||||
uids.add(null);
|
||||
|
||||
setDenylist(uids);
|
||||
|
||||
verify(mNetworkPolicyManager, never()).setUidPolicy(anyInt(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setDenylist_sameList_doNothing() {
|
||||
initDynamicDenylistManager(EMPTY_ARRAY);
|
||||
setupPreference(mDynamicDenyListPref, FAKE_UID_2, FAKE_UID_1);
|
||||
|
||||
setDenylist(new ArraySet<>(List.of(FAKE_UID_1_INT, FAKE_UID_2_INT)));
|
||||
|
||||
verify(mNetworkPolicyManager, never()).setUidPolicy(anyInt(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setDenylist_newListWithOldData_modifyPolicyNoneAndReject() {
|
||||
initDynamicDenylistManager(EMPTY_ARRAY);
|
||||
setupPreference(mDynamicDenyListPref, FAKE_UID_2);
|
||||
|
||||
setDenylist(new ArraySet<>(List.of(FAKE_UID_1_INT)));
|
||||
|
||||
verify(mNetworkPolicyManager).setUidPolicy(FAKE_UID_2_INT, POLICY_NONE);
|
||||
verify(mNetworkPolicyManager).setUidPolicy(FAKE_UID_1_INT,
|
||||
POLICY_REJECT_METERED_BACKGROUND);
|
||||
assertThat(mDynamicDenyListPref.getAll()).hasSize(1);
|
||||
assertTrue(mDynamicDenyListPref.contains(FAKE_UID_1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setDenylist_newListWithoutOldData_modifyPolicyReject() {
|
||||
initDynamicDenylistManager(EMPTY_ARRAY);
|
||||
|
||||
setDenylist(new ArraySet<>(List.of(FAKE_UID_1_INT)));
|
||||
|
||||
verify(mNetworkPolicyManager, never()).setUidPolicy(anyInt(), eq(POLICY_NONE));
|
||||
verify(mNetworkPolicyManager).setUidPolicy(FAKE_UID_1_INT,
|
||||
POLICY_REJECT_METERED_BACKGROUND);
|
||||
assertThat(mDynamicDenyListPref.getAll()).hasSize(1);
|
||||
assertTrue(mDynamicDenyListPref.contains(FAKE_UID_1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setDenylist_emptyListWithOldData_modifyPolicyNone() {
|
||||
initDynamicDenylistManager(EMPTY_ARRAY);
|
||||
setupPreference(mDynamicDenyListPref, FAKE_UID_2);
|
||||
|
||||
setDenylist(Collections.emptySet());
|
||||
|
||||
verify(mNetworkPolicyManager).setUidPolicy(FAKE_UID_2_INT, POLICY_NONE);
|
||||
verify(mNetworkPolicyManager, never()).setUidPolicy(anyInt(),
|
||||
eq(POLICY_REJECT_METERED_BACKGROUND));
|
||||
assertThat(mDynamicDenyListPref.getAll()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isInManualDenylist_returnsFalse() {
|
||||
initDynamicDenylistManager(EMPTY_ARRAY);
|
||||
|
||||
assertFalse(mDynamicDenylistManager.isInManualDenylist(FAKE_UID_1_INT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isInManualDenylist_incorrectUid_returnsFalse() {
|
||||
initDynamicDenylistManager(EMPTY_ARRAY);
|
||||
|
||||
mManualDenyListPref.edit().putInt(FAKE_UID_2, POLICY_REJECT_METERED_BACKGROUND).apply();
|
||||
|
||||
assertFalse(mDynamicDenylistManager.isInManualDenylist(FAKE_UID_1_INT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isInManualDenylist_initiated_returnsTrue() {
|
||||
initDynamicDenylistManager(EMPTY_ARRAY);
|
||||
|
||||
mManualDenyListPref.edit().putInt(FAKE_UID_1, POLICY_REJECT_METERED_BACKGROUND).apply();
|
||||
|
||||
assertTrue(mDynamicDenylistManager.isInManualDenylist(FAKE_UID_1_INT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resetDenylistIfNeeded_nullPackageName_doNothing() {
|
||||
initDynamicDenylistManager(new int[0], new int[] {FAKE_UID_1_INT, FAKE_UID_2_INT});
|
||||
|
||||
mDynamicDenylistManager.resetDenylistIfNeeded(null, false);
|
||||
|
||||
assertThat(mManualDenyListPref.getAll()).hasSize(1);
|
||||
verify(mNetworkPolicyManager, never()).setUidPolicy(anyInt(), eq(POLICY_NONE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resetDenylistIfNeeded_invalidPackageName_doNothing() {
|
||||
initDynamicDenylistManager(new int[0], new int[] {FAKE_UID_1_INT, FAKE_UID_2_INT});
|
||||
|
||||
mDynamicDenylistManager.resetDenylistIfNeeded("invalid_package_name", false);
|
||||
|
||||
assertThat(mManualDenyListPref.getAll()).hasSize(1);
|
||||
verify(mNetworkPolicyManager, never()).setUidPolicy(anyInt(), eq(POLICY_NONE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resetDenylistIfNeeded_denylistUnchanged_doNothingWithPolicy() {
|
||||
initDynamicDenylistManager(new int[] {FAKE_UID_1_INT, FAKE_UID_2_INT});
|
||||
|
||||
mDynamicDenylistManager.resetDenylistIfNeeded(SETTINGS_PACKAGE_NAME, false);
|
||||
|
||||
verify(mNetworkPolicyManager, never()).setUidPolicy(anyInt(), eq(POLICY_NONE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resetDenylistIfNeeded_denylistChanged_resetAndClear() {
|
||||
initDynamicDenylistManager(new int[0], new int[] {FAKE_UID_1_INT, FAKE_UID_2_INT});
|
||||
|
||||
mDynamicDenylistManager.resetDenylistIfNeeded(SETTINGS_PACKAGE_NAME, false);
|
||||
|
||||
assertThat(mManualDenyListPref.getAll()).isEmpty();
|
||||
verify(mNetworkPolicyManager, times(2)).setUidPolicy(anyInt(), eq(POLICY_NONE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resetDenylistIfNeeded_forceResetWithNullPackageName_resetAndClear() {
|
||||
initDynamicDenylistManager(new int[0], new int[] {FAKE_UID_2_INT});
|
||||
|
||||
mDynamicDenylistManager.resetDenylistIfNeeded(null, true);
|
||||
|
||||
assertThat(mManualDenyListPref.getAll()).isEmpty();
|
||||
verify(mNetworkPolicyManager).setUidPolicy(eq(FAKE_UID_2_INT), eq(POLICY_NONE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resetDenylistIfNeeded_forceResetWithInvalidPackageName_resetAndClear() {
|
||||
initDynamicDenylistManager(new int[0], new int[] {FAKE_UID_1_INT, FAKE_UID_2_INT});
|
||||
|
||||
mDynamicDenylistManager.resetDenylistIfNeeded("invalid_package_name", true);
|
||||
|
||||
assertThat(mManualDenyListPref.getAll()).isEmpty();
|
||||
verify(mNetworkPolicyManager, times(2)).setUidPolicy(anyInt(), eq(POLICY_NONE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resetDenylistIfNeeded_forceResetButDenylistUnchanged_doNothingWithPolicy() {
|
||||
initDynamicDenylistManager(new int[] {FAKE_UID_1_INT});
|
||||
|
||||
mDynamicDenylistManager.resetDenylistIfNeeded(SETTINGS_PACKAGE_NAME, true);
|
||||
|
||||
assertThat(mManualDenyListPref.getAll()).isEmpty();
|
||||
verify(mNetworkPolicyManager, never()).setUidPolicy(anyInt(), eq(POLICY_NONE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resetDenylistIfNeeded_forceResetWithDenylistChanged_resetAndClear() {
|
||||
initDynamicDenylistManager(new int[0], new int[] {FAKE_UID_1_INT, FAKE_UID_2_INT});
|
||||
|
||||
mDynamicDenylistManager.resetDenylistIfNeeded(SETTINGS_PACKAGE_NAME, true);
|
||||
|
||||
assertThat(mManualDenyListPref.getAll()).isEmpty();
|
||||
verify(mNetworkPolicyManager, times(2)).setUidPolicy(anyInt(), eq(POLICY_NONE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clearSharedPreferences_manualDenyListPrefIsEmpty() {
|
||||
initDynamicDenylistManager(EMPTY_ARRAY);
|
||||
mManualDenyListPref.edit().putInt(FAKE_UID_1, POLICY_REJECT_METERED_BACKGROUND).apply();
|
||||
assertThat(mManualDenyListPref.getAll()).hasSize(2);
|
||||
assertTrue(mManualDenyListPref.contains(FAKE_UID_1));
|
||||
assertTrue(mManualDenyListPref.contains(PREF_KEY_MANUAL_DENYLIST_SYNCED));
|
||||
|
||||
mDynamicDenylistManager.clearSharedPreferences();
|
||||
|
||||
assertThat(mManualDenyListPref.getAll()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clearSharedPreferences_dynamicDenyListPrefIsEmpty() {
|
||||
initDynamicDenylistManager(EMPTY_ARRAY);
|
||||
mDynamicDenyListPref.edit().putInt(FAKE_UID_1, POLICY_REJECT_METERED_BACKGROUND).apply();
|
||||
assertThat(mDynamicDenyListPref.getAll()).hasSize(1);
|
||||
assertTrue(mDynamicDenyListPref.contains(FAKE_UID_1));
|
||||
|
||||
mDynamicDenylistManager.clearSharedPreferences();
|
||||
|
||||
assertThat(mDynamicDenyListPref.getAll()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dump_dumpExpectedResult() {
|
||||
initDynamicDenylistManager(EMPTY_ARRAY);
|
||||
setupPreference(mManualDenyListPref, FAKE_UID_1);
|
||||
setupPreference(mDynamicDenyListPref, FAKE_UID_2);
|
||||
final StringWriter stringWriter = new StringWriter();
|
||||
final PrintWriter printWriter = new PrintWriter(stringWriter);
|
||||
when(mPackageManager.getNameForUid(FAKE_UID_1_INT)).thenReturn("app1");
|
||||
when(mPackageManager.getNameForUid(FAKE_UID_2_INT)).thenReturn("app2");
|
||||
|
||||
mDynamicDenylistManager.dump(printWriter);
|
||||
|
||||
final String dumpResults = stringWriter.toString();
|
||||
assertThat(dumpResults.contains("\tManualDenylist:\n\t\tapp1")).isTrue();
|
||||
assertThat(dumpResults.contains("\tDynamicDenylist:\n\t\tapp2")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dump_withEmptySharedPreferences_dumpExpectedResult() {
|
||||
initDynamicDenylistManager(EMPTY_ARRAY, EMPTY_ARRAY);
|
||||
mDynamicDenylistManager.clearSharedPreferences();
|
||||
final StringWriter stringWriter = new StringWriter();
|
||||
final PrintWriter printWriter = new PrintWriter(stringWriter);
|
||||
|
||||
mDynamicDenylistManager.dump(printWriter);
|
||||
|
||||
final String dumpResults = stringWriter.toString();
|
||||
assertThat(dumpResults.contains("Dump of DynamicDenylistManager:")).isTrue();
|
||||
assertThat(dumpResults.contains("\tManualDenylist:\n\tDynamicDenylist:")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBootComplete_resetIntoManualMode() {
|
||||
initDynamicDenylistManager(new int[] {FAKE_UID_1_INT});
|
||||
setDenylist(new ArraySet<>(List.of(FAKE_UID_2_INT)));
|
||||
// Ensure the testing environment for manual denylist.
|
||||
assertThat(mManualDenyListPref.getAll()).hasSize(2);
|
||||
assertTrue(mManualDenyListPref.contains(PREF_KEY_MANUAL_DENYLIST_SYNCED));
|
||||
assertTrue(mManualDenyListPref.contains(FAKE_UID_1));
|
||||
// Ensure the testing environment for dynamic denylist.
|
||||
assertThat(mDynamicDenyListPref.getAll()).hasSize(1);
|
||||
|
||||
mDynamicDenylistManager.onBootComplete();
|
||||
|
||||
// Keep the users set uids in the manual denylist.
|
||||
assertThat(mManualDenyListPref.getAll()).hasSize(2);
|
||||
assertTrue(mManualDenyListPref.contains(PREF_KEY_MANUAL_DENYLIST_SYNCED));
|
||||
assertTrue(mManualDenyListPref.contains(FAKE_UID_1));
|
||||
// Clear the uids in the dynamic denylist.
|
||||
assertThat(mDynamicDenyListPref.getAll()).isEmpty();
|
||||
}
|
||||
|
||||
private void initDynamicDenylistManager(int[] preload) {
|
||||
initDynamicDenylistManager(preload, preload);
|
||||
}
|
||||
|
||||
private void initDynamicDenylistManager(int[] preload1, int[] preload2) {
|
||||
final Context context = spy(RuntimeEnvironment.application.getApplicationContext());
|
||||
when(context.getApplicationContext()).thenReturn(context);
|
||||
when(context.getPackageManager()).thenReturn(mPackageManager);
|
||||
when(mNetworkPolicyManager.getUidsWithPolicy(anyInt()))
|
||||
.thenReturn(preload1).thenReturn(preload2);
|
||||
mDynamicDenylistManager = new DynamicDenylistManager(context, mNetworkPolicyManager);
|
||||
mManualDenyListPref = mDynamicDenylistManager.getManualDenylistPref();
|
||||
mDynamicDenyListPref = mDynamicDenylistManager.getDynamicDenylistPref();
|
||||
}
|
||||
|
||||
private void setDenylist(Set<Integer> packageNameList) {
|
||||
mDynamicDenylistManager.setDenylist(packageNameList);
|
||||
}
|
||||
|
||||
private void setupPreference(SharedPreferences sharedPreferences, String... uids) {
|
||||
final SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
for (String uid : uids) {
|
||||
editor.putInt(uid, POLICY_REJECT_METERED_BACKGROUND);
|
||||
}
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user