Auto-deny requests after some user denials
After the user denies the request to add a tile (a particular ComponentName) a certain number of times, auto deny further requests for that user,component pair. Cancelling the dialog (by going back/click outside) don't count against. This information is reset when the package is uninstalled or data is cleared for the package. In the future, this information will be persisted across restarts. Fixes: 208671346 Test: manual Test: atest com.android.server.statusbar Change-Id: I1828d1d3e462fc9b4af94c4350df895994d02b6c
This commit is contained in:
@@ -626,6 +626,9 @@ public class StatusBarManager {
|
||||
* foreground ({@link ActivityManager.RunningAppProcessInfo#IMPORTANCE_FOREGROUND}
|
||||
* and the {@link android.service.quicksettings.TileService} must be exported.
|
||||
*
|
||||
* Note: the system can choose to auto-deny a request if the user has denied that specific
|
||||
* request (user, ComponentName) enough times before.
|
||||
*
|
||||
* @param tileServiceComponentName {@link ComponentName} of the
|
||||
* {@link android.service.quicksettings.TileService} for the request.
|
||||
* @param tileLabel label of the tile to show to the user.
|
||||
|
||||
@@ -64,6 +64,7 @@ import android.service.quicksettings.TileService;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.IndentingPrintWriter;
|
||||
import android.util.Pair;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
@@ -139,6 +140,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
|
||||
private int mCurrentUserId;
|
||||
private boolean mTracingEnabled;
|
||||
|
||||
private final TileRequestTracker mTileRequestTracker;
|
||||
|
||||
private final SparseArray<UiState> mDisplayUiState = new SparseArray<>();
|
||||
@GuardedBy("mLock")
|
||||
private IUdfpsHbmListener mUdfpsHbmListener;
|
||||
@@ -245,6 +248,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
|
||||
mActivityTaskManager = LocalServices.getService(ActivityTaskManagerInternal.class);
|
||||
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
|
||||
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
|
||||
|
||||
mTileRequestTracker = new TileRequestTracker(mContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1765,11 +1770,26 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
|
||||
mCurrentRequestAddTilePackages.put(packageName, currentTime);
|
||||
}
|
||||
|
||||
if (mTileRequestTracker.shouldBeDenied(userId, componentName)) {
|
||||
if (clearTileAddRequest(packageName)) {
|
||||
try {
|
||||
callback.onTileRequest(StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_NOT_ADDED);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "requestAddTile - callback", e);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
IAddTileResultCallback proxyCallback = new IAddTileResultCallback.Stub() {
|
||||
@Override
|
||||
public void onTileRequest(int i) {
|
||||
if (i == StatusBarManager.TILE_ADD_REQUEST_RESULT_DIALOG_DISMISSED) {
|
||||
i = StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_NOT_ADDED;
|
||||
} else if (i == StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_NOT_ADDED) {
|
||||
mTileRequestTracker.addDenial(userId, componentName);
|
||||
} else if (i == StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_ADDED) {
|
||||
mTileRequestTracker.resetRequests(userId, componentName);
|
||||
}
|
||||
if (clearTileAddRequest(packageName)) {
|
||||
try {
|
||||
@@ -1961,6 +1981,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
|
||||
pw.println(" " + requests.get(i) + ",");
|
||||
}
|
||||
pw.println(" ]");
|
||||
IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
|
||||
mTileRequestTracker.dump(fd, ipw.increaseIndent(), args);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.server.statusbar;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.Uri;
|
||||
import android.os.UserHandle;
|
||||
import android.util.ArraySet;
|
||||
import android.util.IndentingPrintWriter;
|
||||
import android.util.SparseArrayMap;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
|
||||
/**
|
||||
* Tracks user denials of requests from {@link StatusBarManagerService#requestAddTile}.
|
||||
*
|
||||
* After a certain number of denials for a particular pair (user,ComponentName), requests will be
|
||||
* auto-denied without showing a dialog to the user.
|
||||
*/
|
||||
public class TileRequestTracker {
|
||||
|
||||
@VisibleForTesting
|
||||
static final int MAX_NUM_DENIALS = 3;
|
||||
|
||||
private final Context mContext;
|
||||
private final Object mLock = new Object();
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private final SparseArrayMap<ComponentName, Integer> mTrackingMap = new SparseArrayMap<>();
|
||||
@GuardedBy("mLock")
|
||||
private final ArraySet<ComponentName> mComponentsToRemove = new ArraySet<>();
|
||||
|
||||
private final BroadcastReceiver mUninstallReceiver = new BroadcastReceiver() {
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Uri data = intent.getData();
|
||||
String packageName = data.getEncodedSchemeSpecificPart();
|
||||
|
||||
if (!intent.hasExtra(Intent.EXTRA_UID)) {
|
||||
return;
|
||||
}
|
||||
int userId = UserHandle.getUserId(intent.getIntExtra(Intent.EXTRA_UID, -1));
|
||||
synchronized (mLock) {
|
||||
mComponentsToRemove.clear();
|
||||
final int elementsForUser = mTrackingMap.numElementsForKey(userId);
|
||||
final int userKeyIndex = mTrackingMap.indexOfKey(userId);
|
||||
for (int compKeyIndex = 0; compKeyIndex < elementsForUser; compKeyIndex++) {
|
||||
ComponentName c = mTrackingMap.keyAt(userKeyIndex, compKeyIndex);
|
||||
if (c.getPackageName().equals(packageName)) {
|
||||
mComponentsToRemove.add(c);
|
||||
}
|
||||
}
|
||||
final int compsToRemoveNum = mComponentsToRemove.size();
|
||||
for (int i = 0; i < compsToRemoveNum; i++) {
|
||||
ComponentName c = mComponentsToRemove.valueAt(i);
|
||||
mTrackingMap.delete(userId, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TileRequestTracker(Context context) {
|
||||
mContext = context;
|
||||
|
||||
IntentFilter intentFilter = new IntentFilter();
|
||||
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
|
||||
intentFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED);
|
||||
intentFilter.addDataScheme("package");
|
||||
mContext.registerReceiverAsUser(mUninstallReceiver, UserHandle.ALL, intentFilter, null,
|
||||
null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether this combination of {@code userId} and {@link ComponentName} should be
|
||||
* auto-denied.
|
||||
*/
|
||||
boolean shouldBeDenied(int userId, ComponentName componentName) {
|
||||
synchronized (mLock) {
|
||||
return mTrackingMap.getOrDefault(userId, componentName, 0) >= MAX_NUM_DENIALS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new denial instance for a given {@code userId} and {@link ComponentName}.
|
||||
*/
|
||||
void addDenial(int userId, ComponentName componentName) {
|
||||
synchronized (mLock) {
|
||||
int current = mTrackingMap.getOrDefault(userId, componentName, 0);
|
||||
mTrackingMap.add(userId, componentName, current + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the number of denied request for a given {@code userId} and {@link ComponentName}.
|
||||
*/
|
||||
void resetRequests(int userId, ComponentName componentName) {
|
||||
synchronized (mLock) {
|
||||
mTrackingMap.delete(userId, componentName);
|
||||
}
|
||||
}
|
||||
|
||||
void dump(FileDescriptor fd, IndentingPrintWriter pw, String[] args) {
|
||||
pw.println("TileRequestTracker:");
|
||||
pw.increaseIndent();
|
||||
synchronized (mLock) {
|
||||
mTrackingMap.forEach((user, componentName, value) -> {
|
||||
pw.println("user=" + user + ", " + componentName.toShortString() + ": " + value);
|
||||
});
|
||||
}
|
||||
pw.decreaseIndent();
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Handler;
|
||||
import android.os.UserHandle;
|
||||
import android.testing.TestableContext;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -34,9 +35,9 @@ import java.util.ArrayList;
|
||||
*
|
||||
* Instead, it keeps a list of the registrations for querying.
|
||||
*/
|
||||
class NoBroadcastContextWrapper extends ContextWrapper {
|
||||
class NoBroadcastContextWrapper extends TestableContext {
|
||||
|
||||
private ArrayList<BroadcastReceiverRegistration> mRegistrationList =
|
||||
ArrayList<BroadcastReceiverRegistration> mRegistrationList =
|
||||
new ArrayList<>();
|
||||
|
||||
NoBroadcastContextWrapper(Context context) {
|
||||
|
||||
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.anyInt;
|
||||
import static org.mockito.Mockito.anyString;
|
||||
import static org.mockito.Mockito.argThat;
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -82,8 +83,7 @@ public class StatusBarManagerServiceTest {
|
||||
|
||||
@Rule
|
||||
public final TestableContext mContext =
|
||||
new TestableContext(
|
||||
new NoBroadcastContextWrapper(InstrumentationRegistry.getContext()), null);
|
||||
new NoBroadcastContextWrapper(InstrumentationRegistry.getContext());
|
||||
|
||||
@Mock
|
||||
private ActivityTaskManagerInternal mActivityTaskManagerInternal;
|
||||
@@ -519,6 +519,62 @@ public class StatusBarManagerServiceTest {
|
||||
callback.mUserResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInstaDenialAfterManyDenials() throws RemoteException {
|
||||
int user = 10;
|
||||
mockEverything(user);
|
||||
|
||||
for (int i = 0; i < TileRequestTracker.MAX_NUM_DENIALS; i++) {
|
||||
mStatusBarManagerService.requestAddTile(TEST_COMPONENT, TILE_LABEL, mIcon, user,
|
||||
new Callback());
|
||||
|
||||
verify(mMockStatusBar, times(i + 1)).requestAddTile(
|
||||
eq(TEST_COMPONENT),
|
||||
eq(APP_NAME),
|
||||
eq(TILE_LABEL),
|
||||
eq(mIcon),
|
||||
mAddTileResultCallbackCaptor.capture()
|
||||
);
|
||||
mAddTileResultCallbackCaptor.getValue().onTileRequest(
|
||||
StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_NOT_ADDED);
|
||||
}
|
||||
|
||||
Callback callback = new Callback();
|
||||
mStatusBarManagerService.requestAddTile(TEST_COMPONENT, TILE_LABEL, mIcon, user, callback);
|
||||
|
||||
// Only called MAX_NUM_DENIALS times
|
||||
verify(mMockStatusBar, times(TileRequestTracker.MAX_NUM_DENIALS)).requestAddTile(
|
||||
any(),
|
||||
any(),
|
||||
any(),
|
||||
any(),
|
||||
mAddTileResultCallbackCaptor.capture()
|
||||
);
|
||||
assertEquals(StatusBarManager.TILE_ADD_REQUEST_RESULT_TILE_NOT_ADDED,
|
||||
callback.mUserResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDialogDismissalNotCountingAgainstDenials() throws RemoteException {
|
||||
int user = 10;
|
||||
mockEverything(user);
|
||||
|
||||
for (int i = 0; i < TileRequestTracker.MAX_NUM_DENIALS * 2; i++) {
|
||||
mStatusBarManagerService.requestAddTile(TEST_COMPONENT, TILE_LABEL, mIcon, user,
|
||||
new Callback());
|
||||
|
||||
verify(mMockStatusBar, times(i + 1)).requestAddTile(
|
||||
eq(TEST_COMPONENT),
|
||||
eq(APP_NAME),
|
||||
eq(TILE_LABEL),
|
||||
eq(mIcon),
|
||||
mAddTileResultCallbackCaptor.capture()
|
||||
);
|
||||
mAddTileResultCallbackCaptor.getValue().onTileRequest(
|
||||
StatusBarManager.TILE_ADD_REQUEST_RESULT_DIALOG_DISMISSED);
|
||||
}
|
||||
}
|
||||
|
||||
private void mockUidCheck() {
|
||||
mockUidCheck(TEST_PACKAGE);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.server.statusbar;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.Uri;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public class TileRequestTrackerTest {
|
||||
|
||||
private static final String TEST_PACKAGE = "test_pkg";
|
||||
private static final String TEST_SERVICE = "test_svc";
|
||||
private static final String TEST_SERVICE_OTHER = "test_svc_other";
|
||||
private static final ComponentName TEST_COMPONENT = new ComponentName(TEST_PACKAGE,
|
||||
TEST_SERVICE);
|
||||
private static final ComponentName TEST_COMPONENT_OTHER = new ComponentName(TEST_PACKAGE,
|
||||
TEST_SERVICE_OTHER);
|
||||
private static final ComponentName TEST_COMPONENT_OTHER_PACKAGE = new ComponentName("other",
|
||||
TEST_SERVICE);
|
||||
private static final int USER_ID = 0;
|
||||
private static final int USER_ID_OTHER = 10;
|
||||
private static final int APP_UID = 12345;
|
||||
private static final int USER_UID = UserHandle.getUid(USER_ID, APP_UID);
|
||||
private static final int USER_OTHER_UID = UserHandle.getUid(USER_ID_OTHER, APP_UID);
|
||||
|
||||
@Rule
|
||||
public final NoBroadcastContextWrapper mContext =
|
||||
new NoBroadcastContextWrapper(InstrumentationRegistry.getContext());
|
||||
|
||||
private TileRequestTracker mTileRequestTracker;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mTileRequestTracker = new TileRequestTracker(mContext);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBroadcastReceiverRegistered() {
|
||||
NoBroadcastContextWrapper.BroadcastReceiverRegistration reg = getReceiverRegistration();
|
||||
|
||||
assertEquals(UserHandle.ALL, reg.mUser);
|
||||
assertNull(reg.mBroadcastPermission);
|
||||
assertNotNull(reg.mReceiver);
|
||||
|
||||
IntentFilter filter = reg.mIntentFilter;
|
||||
assertEquals(2, filter.countActions());
|
||||
assertTrue(filter.hasAction(Intent.ACTION_PACKAGE_REMOVED));
|
||||
assertTrue(filter.hasAction(Intent.ACTION_PACKAGE_DATA_CLEARED));
|
||||
assertTrue(filter.hasDataScheme("package"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoDenialsFromStart() {
|
||||
// Certainly not an exhaustive test
|
||||
assertFalse(mTileRequestTracker.shouldBeDenied(USER_ID, TEST_COMPONENT));
|
||||
assertFalse(mTileRequestTracker.shouldBeDenied(USER_ID_OTHER, TEST_COMPONENT));
|
||||
assertFalse(mTileRequestTracker.shouldBeDenied(USER_ID, TEST_COMPONENT_OTHER));
|
||||
assertFalse(mTileRequestTracker.shouldBeDenied(USER_ID_OTHER, TEST_COMPONENT_OTHER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNoDenialBeforeMax() {
|
||||
for (int i = 1; i < TileRequestTracker.MAX_NUM_DENIALS; i++) {
|
||||
mTileRequestTracker.addDenial(USER_ID, TEST_COMPONENT);
|
||||
}
|
||||
|
||||
assertFalse(mTileRequestTracker.shouldBeDenied(USER_ID, TEST_COMPONENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDenialOnMax() {
|
||||
for (int i = 1; i <= TileRequestTracker.MAX_NUM_DENIALS; i++) {
|
||||
mTileRequestTracker.addDenial(USER_ID, TEST_COMPONENT);
|
||||
}
|
||||
assertTrue(mTileRequestTracker.shouldBeDenied(USER_ID, TEST_COMPONENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDenialPerUser() {
|
||||
for (int i = 1; i <= TileRequestTracker.MAX_NUM_DENIALS; i++) {
|
||||
mTileRequestTracker.addDenial(USER_ID, TEST_COMPONENT);
|
||||
}
|
||||
|
||||
assertFalse(mTileRequestTracker.shouldBeDenied(USER_ID_OTHER, TEST_COMPONENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDenialPerComponent() {
|
||||
for (int i = 1; i <= TileRequestTracker.MAX_NUM_DENIALS; i++) {
|
||||
mTileRequestTracker.addDenial(USER_ID, TEST_COMPONENT);
|
||||
}
|
||||
|
||||
assertFalse(mTileRequestTracker.shouldBeDenied(USER_ID, TEST_COMPONENT_OTHER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPackageUninstallRemovesDenials_allComponents() {
|
||||
for (int i = 1; i <= TileRequestTracker.MAX_NUM_DENIALS; i++) {
|
||||
mTileRequestTracker.addDenial(USER_ID, TEST_COMPONENT);
|
||||
mTileRequestTracker.addDenial(USER_ID, TEST_COMPONENT_OTHER);
|
||||
}
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_PACKAGE_REMOVED);
|
||||
intent.putExtra(Intent.EXTRA_UID, USER_UID);
|
||||
intent.setData(Uri.parse("package:" + TEST_PACKAGE));
|
||||
getReceiverRegistration().mReceiver.onReceive(mContext, intent);
|
||||
|
||||
assertFalse(mTileRequestTracker.shouldBeDenied(USER_ID, TEST_COMPONENT));
|
||||
assertFalse(mTileRequestTracker.shouldBeDenied(USER_ID, TEST_COMPONENT_OTHER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPackageUninstallRemoveDenials_differentUsers() {
|
||||
for (int i = 1; i <= TileRequestTracker.MAX_NUM_DENIALS; i++) {
|
||||
mTileRequestTracker.addDenial(USER_ID, TEST_COMPONENT);
|
||||
mTileRequestTracker.addDenial(USER_ID_OTHER, TEST_COMPONENT);
|
||||
}
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_PACKAGE_REMOVED);
|
||||
intent.putExtra(Intent.EXTRA_UID, USER_OTHER_UID);
|
||||
intent.setData(Uri.parse("package:" + TEST_PACKAGE));
|
||||
getReceiverRegistration().mReceiver.onReceive(mContext, intent);
|
||||
|
||||
// User 0 package was not removed
|
||||
assertTrue(mTileRequestTracker.shouldBeDenied(USER_ID, TEST_COMPONENT));
|
||||
// User 10 package was removed
|
||||
assertFalse(mTileRequestTracker.shouldBeDenied(USER_ID_OTHER, TEST_COMPONENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPackageUninstallRemoveDenials_differentPackages() {
|
||||
for (int i = 1; i <= TileRequestTracker.MAX_NUM_DENIALS; i++) {
|
||||
mTileRequestTracker.addDenial(USER_ID, TEST_COMPONENT);
|
||||
mTileRequestTracker.addDenial(USER_ID, TEST_COMPONENT_OTHER_PACKAGE);
|
||||
}
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_PACKAGE_REMOVED);
|
||||
intent.putExtra(Intent.EXTRA_UID, USER_UID);
|
||||
intent.setData(Uri.parse("package:" + TEST_PACKAGE));
|
||||
getReceiverRegistration().mReceiver.onReceive(mContext, intent);
|
||||
|
||||
// Package TEST_PACKAGE removed
|
||||
assertFalse(mTileRequestTracker.shouldBeDenied(USER_ID, TEST_COMPONENT));
|
||||
// Package "other" not removed
|
||||
assertTrue(mTileRequestTracker.shouldBeDenied(USER_ID, TEST_COMPONENT_OTHER_PACKAGE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPackageUpdateDoesntRemoveDenials() {
|
||||
for (int i = 1; i <= TileRequestTracker.MAX_NUM_DENIALS; i++) {
|
||||
mTileRequestTracker.addDenial(USER_ID, TEST_COMPONENT);
|
||||
}
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_PACKAGE_REMOVED);
|
||||
intent.putExtra(Intent.EXTRA_REPLACING, true);
|
||||
intent.putExtra(Intent.EXTRA_UID, USER_UID);
|
||||
intent.setData(Uri.parse("package:" + TEST_PACKAGE));
|
||||
getReceiverRegistration().mReceiver.onReceive(mContext, intent);
|
||||
|
||||
assertTrue(mTileRequestTracker.shouldBeDenied(USER_ID, TEST_COMPONENT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClearPackageDataRemovesDenials() {
|
||||
for (int i = 1; i <= TileRequestTracker.MAX_NUM_DENIALS; i++) {
|
||||
mTileRequestTracker.addDenial(USER_ID, TEST_COMPONENT);
|
||||
}
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED);
|
||||
intent.putExtra(Intent.EXTRA_UID, USER_UID);
|
||||
intent.setData(Uri.parse("package:" + TEST_PACKAGE));
|
||||
getReceiverRegistration().mReceiver.onReceive(mContext, intent);
|
||||
|
||||
assertFalse(mTileRequestTracker.shouldBeDenied(USER_ID, TEST_COMPONENT));
|
||||
}
|
||||
|
||||
private NoBroadcastContextWrapper.BroadcastReceiverRegistration getReceiverRegistration() {
|
||||
assertEquals(1, mContext.mRegistrationList.size());
|
||||
return mContext.mRegistrationList.get(0);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user