summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2016-06-01 23:03:38 +0000
committerandroid-build-merger <android-build-merger@google.com>2016-06-01 23:03:38 +0000
commitf02954ccd5f536577fa4564ede76c5ec61fbbf88 (patch)
treeffef88d2adca584df661fb8ac5d709f867bbc0e5 /core/java/android
parent60585d12e717d6dd02c89cf177159dbb1c7b4fc9 (diff)
parent380f3b12a4725a0534d62ada7c6f3bd67ebd0d01 (diff)
Merge "Release AssetManagers when ejecting storage." into nyc-dev
am: 380f3b12a4 * commit '380f3b12a4725a0534d62ada7c6f3bd67ebd0d01': Release AssetManagers when ejecting storage. Change-Id: I54282cfcf53279f87e66cc1263ae9663fe94bc04
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/ResourcesManager.java28
-rw-r--r--core/java/android/content/res/ResourcesKey.java20
2 files changed, 45 insertions, 3 deletions
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 25a8b66a42aa..31d254dc5b2b 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -29,7 +29,6 @@ import android.content.res.ResourcesImpl;
import android.content.res.ResourcesKey;
import android.hardware.display.DisplayManagerGlobal;
import android.os.IBinder;
-import android.os.LocaleList;
import android.os.Trace;
import android.util.ArrayMap;
import android.util.DisplayMetrics;
@@ -38,13 +37,12 @@ import android.util.Pair;
import android.util.Slog;
import android.view.Display;
import android.view.DisplayAdjustments;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
import java.util.Objects;
import java.util.WeakHashMap;
import java.util.function.Predicate;
@@ -120,6 +118,30 @@ public class ResourcesManager {
}
}
+ /**
+ * Invalidate and destroy any resources that reference content under the
+ * given filesystem path. Typically used when unmounting a storage device to
+ * try as hard as possible to release any open FDs.
+ */
+ public void invalidatePath(String path) {
+ synchronized (this) {
+ int count = 0;
+ for (int i = 0; i < mResourceImpls.size();) {
+ final ResourcesKey key = mResourceImpls.keyAt(i);
+ if (key.isPathReferenced(path)) {
+ final ResourcesImpl res = mResourceImpls.removeAt(i).get();
+ if (res != null) {
+ res.flushLayoutCache();
+ }
+ count++;
+ } else {
+ i++;
+ }
+ }
+ Log.i(TAG, "Invalidated " + count + " asset managers that referenced " + path);
+ }
+ }
+
public Configuration getConfiguration() {
synchronized (this) {
return mResConfiguration;
diff --git a/core/java/android/content/res/ResourcesKey.java b/core/java/android/content/res/ResourcesKey.java
index e89449283c5e..64b6bf1b6dcd 100644
--- a/core/java/android/content/res/ResourcesKey.java
+++ b/core/java/android/content/res/ResourcesKey.java
@@ -77,6 +77,26 @@ public final class ResourcesKey {
return !Configuration.EMPTY.equals(mOverrideConfiguration);
}
+ public boolean isPathReferenced(String path) {
+ if (mResDir != null && mResDir.startsWith(path)) {
+ return true;
+ } else {
+ return anyStartsWith(mSplitResDirs, path) || anyStartsWith(mOverlayDirs, path)
+ || anyStartsWith(mLibDirs, path);
+ }
+ }
+
+ private static boolean anyStartsWith(String[] list, String prefix) {
+ if (list != null) {
+ for (String s : list) {
+ if (s != null && s.startsWith(prefix)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
@Override
public int hashCode() {
return mHash;