Clear old secondary dex dir when multidex becomes supported.
There may be a need for clearing those unused extracted files after an OTA
bringing Art L on the device.
Bug: 10447095
Change-Id: I80b9c0afa2bd8dfa0cf04e96fb04ba2527da0fe5
diff --git a/library/src/android/support/multidex/MultiDex.java b/library/src/android/support/multidex/MultiDex.java
index cd38112..68462c2 100644
--- a/library/src/android/support/multidex/MultiDex.java
+++ b/library/src/android/support/multidex/MultiDex.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.util.Log;
@@ -88,6 +89,12 @@
Log.i(TAG, "install");
if (IS_VM_MULTIDEX_CAPABLE) {
Log.i(TAG, "VM has multidex support, MultiDex support library is disabled.");
+ try {
+ clearOldDexDir(context);
+ } catch (Throwable t) {
+ Log.w(TAG, "Something went wrong when trying to clear old MultiDex extraction, "
+ + "continuing without cleaning.", t);
+ }
return;
}
@@ -97,28 +104,9 @@
}
try {
- PackageManager pm;
- String packageName;
- try {
- pm = context.getPackageManager();
- packageName = context.getPackageName();
- } catch (RuntimeException e) {
- /* Ignore those exceptions so that we don't break tests relying on Context like
- * a android.test.mock.MockContext or a android.content.ContextWrapper with a null
- * base Context.
- */
- Log.w(TAG, "Failure while trying to obtain ApplicationInfo from Context. " +
- "Must be running in test mode. Skip patching.", e);
- return;
- }
- if (pm == null || packageName == null) {
- // This is most likely a mock context, so just return without patching.
- return;
- }
- ApplicationInfo applicationInfo =
- pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
+ ApplicationInfo applicationInfo = getApplicationInfo(context);
if (applicationInfo == null) {
- // This is from a mock context, so just return without patching.
+ // Looks like running on a test Context, so just return without patching.
return;
}
@@ -188,6 +176,31 @@
Log.i(TAG, "install done");
}
+ private static ApplicationInfo getApplicationInfo(Context context)
+ throws NameNotFoundException {
+ PackageManager pm;
+ String packageName;
+ try {
+ pm = context.getPackageManager();
+ packageName = context.getPackageName();
+ } catch (RuntimeException e) {
+ /* Ignore those exceptions so that we don't break tests relying on Context like
+ * a android.test.mock.MockContext or a android.content.ContextWrapper with a null
+ * base Context.
+ */
+ Log.w(TAG, "Failure while trying to obtain ApplicationInfo from Context. " +
+ "Must be running in test mode. Skip patching.", e);
+ return null;
+ }
+ if (pm == null || packageName == null) {
+ // This is most likely a mock context, so just return without patching.
+ return null;
+ }
+ ApplicationInfo applicationInfo =
+ pm.getApplicationInfo(packageName, PackageManager.GET_META_DATA);
+ return applicationInfo;
+ }
+
/**
* Identifies if the current VM has a native support for multidex, meaning there is no need for
* additional installation by this library.
@@ -320,6 +333,45 @@
jlrField.set(instance, combined);
}
+ private static void clearOldDexDir(Context context) throws Exception {
+ ApplicationInfo applicationInfo = getApplicationInfo(context);
+ if (applicationInfo == null) {
+ // Looks like running on a test Context, so just return.
+ return;
+ }
+
+ synchronized (installedApk) {
+ String apkPath = applicationInfo.sourceDir;
+ if (installedApk.contains(apkPath)) {
+ return;
+ }
+ installedApk.add(apkPath);
+ }
+ File dexDir = new File(context.getFilesDir(), SECONDARY_FOLDER_NAME);
+ if (dexDir.isDirectory()) {
+ Log.i(TAG, "Clearing old secondary dex dir (" + dexDir.getPath() + ").");
+ File[] files = dexDir.listFiles();
+ if (files == null) {
+ Log.w(TAG, "Failed to list secondary dex dir content (" + dexDir.getPath() + ").");
+ return;
+ }
+ for (File oldFile : files) {
+ Log.i(TAG, "Trying to delete old file " + oldFile.getPath() + " of size "
+ + oldFile.length());
+ if (!oldFile.delete()) {
+ Log.w(TAG, "Failed to delete old file " + oldFile.getPath());
+ } else {
+ Log.i(TAG, "Deleted old file " + oldFile.getPath());
+ }
+ }
+ if (!dexDir.delete()) {
+ Log.w(TAG, "Failed to delete secondary dex dir " + dexDir.getPath());
+ } else {
+ Log.i(TAG, "Deleted old secondary dex dir " + dexDir.getPath());
+ }
+ }
+ }
+
/**
* Installer for platform versions 19.
*/