summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/PropertyInvalidatedCache.java40
1 files changed, 37 insertions, 3 deletions
diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java
index 5b99c72dc55e..3110e18985b0 100644
--- a/core/java/android/app/PropertyInvalidatedCache.java
+++ b/core/java/android/app/PropertyInvalidatedCache.java
@@ -25,6 +25,7 @@ import android.os.SystemProperties;
import android.util.Log;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import java.util.HashMap;
import java.util.LinkedHashMap;
@@ -159,6 +160,13 @@ import java.util.concurrent.atomic.AtomicLong;
* this local case, there's no IPC, so use of the cache is (depending on exact
* circumstance) unnecessary.
*
+ * For security, there is a whitelist of processes that are allowed to invalidate a cache.
+ * The whitelist includes normal runtime processes but does not include test processes.
+ * Test processes must call {@code PropertyInvalidatedCache.disableForTestMode()} to disable
+ * all cache activity in that process.
+ *
+ * Caching can be disabled completely by initializing {@code sEnabled} to false and rebuilding.
+ *
* @param <Query> The class used to index cache entries: must be hashable and comparable
* @param <Result> The class holding cache entries; use a boxed primitive if possible
*
@@ -170,9 +178,14 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
private static final String TAG = "PropertyInvalidatedCache";
private static final boolean DEBUG = false;
- private static final boolean ENABLE = true;
private static final boolean VERIFY = false;
+ /**
+ * If sEnabled is false then all cache operations are stubbed out. Set
+ * it to false inside test processes.
+ */
+ private static boolean sEnabled = true;
+
private static final Object sCorkLock = new Object();
/**
@@ -300,7 +313,7 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
* Return whether the cache is disabled in this process.
*/
public final boolean isDisabledLocal() {
- return mDisabled;
+ return mDisabled || !sEnabled;
}
/**
@@ -308,7 +321,7 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
*/
public Result query(Query query) {
// Let access to mDisabled race: it's atomic anyway.
- long currentNonce = (ENABLE && !mDisabled) ? getCurrentNonce() : NONCE_DISABLED;
+ long currentNonce = (!isDisabledLocal()) ? getCurrentNonce() : NONCE_DISABLED;
for (;;) {
if (currentNonce == NONCE_DISABLED || currentNonce == NONCE_UNSET) {
if (DEBUG) {
@@ -419,6 +432,9 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
* @param name Name of the cache-key property to invalidate
*/
public static void disableSystemWide(@NonNull String name) {
+ if (!sEnabled) {
+ return;
+ }
SystemProperties.set(name, Long.toString(NONCE_DISABLED));
}
@@ -437,6 +453,14 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
* @param name Name of the cache-key property to invalidate
*/
public static void invalidateCache(@NonNull String name) {
+ if (!sEnabled) {
+ if (DEBUG) {
+ Log.w(TAG, String.format(
+ "cache invalidate %s suppressed", name));
+ }
+ return;
+ }
+
// Take the cork lock so invalidateCache() racing against corkInvalidations() doesn't
// clobber a cork-written NONCE_UNSET with a cache key we compute before the cork.
// The property service is single-threaded anyway, so we don't lose any concurrency by
@@ -676,4 +700,14 @@ public abstract class PropertyInvalidatedCache<Query, Result> {
public String queryToString(Query query) {
return Objects.toString(query);
}
+
+ /**
+ * Disable all caches in the local process. Once disabled it is not
+ * possible to re-enable caching in the current process.
+ */
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+ public static void disableForTestMode() {
+ Log.d(TAG, "disabling all caches in the process");
+ sEnabled = false;
+ }
}