Control modTime of extracted files.

And use it to clean more accuratly old extracted files.

Fix bug 11232823

Change-Id: I23678ae07a8df955276ece7b8c0cdddef907992b
diff --git a/library/src/android/support/multidex/MultiDexExtractor.java b/library/src/android/support/multidex/MultiDexExtractor.java
index 220f2aa..c4547dd 100644
--- a/library/src/android/support/multidex/MultiDexExtractor.java
+++ b/library/src/android/support/multidex/MultiDexExtractor.java
@@ -16,15 +16,11 @@
 
 package android.support.multidex;
 
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.util.Log;
-
 import java.io.Closeable;
 import java.io.File;
+import java.io.FileFilter;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
-import java.io.FilenameFilter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
@@ -33,6 +29,10 @@
 import java.util.zip.ZipFile;
 import java.util.zip.ZipOutputStream;
 
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.util.Log;
+
 /**
  * Exposes application secondary dex files as files in the application data
  * directory.
@@ -67,10 +67,12 @@
     static List<File> load(Context context, ApplicationInfo applicationInfo, File dexDir)
             throws IOException {
 
-        String extractedFilePrefix = new File(applicationInfo.sourceDir).getName()
+        File sourceApk = new File(applicationInfo.sourceDir);
+        long lastModified = sourceApk.lastModified();
+        String extractedFilePrefix = sourceApk.getName()
                 + EXTRACTED_NAME_EXT;
 
-        prepareDexDir(dexDir, extractedFilePrefix);
+        prepareDexDir(dexDir, extractedFilePrefix, lastModified);
 
         final List<File> files = new ArrayList<File>();
         ZipFile apk = new ZipFile(applicationInfo.sourceDir);
@@ -85,7 +87,8 @@
                 files.add(extractedFile);
 
                 if (!extractedFile.isFile()) {
-                    extract(context, apk, dexFile, extractedFile, extractedFilePrefix);
+                    extract(context, apk, dexFile, extractedFile, extractedFilePrefix,
+                            lastModified);
                 }
                 secondaryNumber++;
                 dexFile = apk.getEntry(DEX_PREFIX + secondaryNumber + DEX_SUFFIX);
@@ -101,18 +104,20 @@
         return files;
     }
 
-    private static void prepareDexDir(File dexDir, final String extractedFilePrefix)
-            throws IOException {
+    private static void prepareDexDir(File dexDir, final String extractedFilePrefix,
+            final long sourceLastModified) throws IOException {
         dexDir.mkdir();
         if (!dexDir.isDirectory()) {
             throw new IOException("Failed to create dex directory " + dexDir.getPath());
         }
 
         // Clean possible old files
-        FilenameFilter filter = new FilenameFilter() {
+        FileFilter filter = new FileFilter() {
+
             @Override
-            public boolean accept(File dir, String name) {
-                return !name.startsWith(extractedFilePrefix);
+            public boolean accept(File pathname) {
+                return (!pathname.getName().startsWith(extractedFilePrefix))
+                    || (pathname.lastModified() < sourceLastModified);
             }
         };
         File[] files = dexDir.listFiles(filter);
@@ -129,7 +134,8 @@
 
     private static void extract(
             Context context, ZipFile apk, ZipEntry dexFile, File extractTo,
-            String extractedFilePrefix) throws IOException, FileNotFoundException {
+            String extractedFilePrefix, long sourceLastModified)
+                    throws IOException, FileNotFoundException {
 
         InputStream in = apk.getInputStream(dexFile);
         ZipOutputStream out = null;
@@ -151,6 +157,10 @@
             } finally {
                 closeQuietly(out);
             }
+            if (!tmp.setLastModified(sourceLastModified)) {
+                Log.e(TAG, "Failed to set time of \"" + tmp.getAbsolutePath() + "\"." +
+                        " This may cause problems with later updates of the apk.");
+            }
             Log.i(TAG, "Renaming to " + extractTo.getPath());
             if (!tmp.renameTo(extractTo)) {
                 throw new IOException("Failed to rename \"" + tmp.getAbsolutePath() + "\" to \"" +