| Index: shell/android/apk/src/org/chromium/mojo/shell/FileHelper.java
|
| diff --git a/shell/android/apk/src/org/chromium/mojo/shell/FileHelper.java b/shell/android/apk/src/org/chromium/mojo/shell/FileHelper.java
|
| index adc747e4756970f5033091c2aa36c4c04d0ec9f4..8af64d5e610693aafaa4bf763e7f9ffa0787f9b2 100644
|
| --- a/shell/android/apk/src/org/chromium/mojo/shell/FileHelper.java
|
| +++ b/shell/android/apk/src/org/chromium/mojo/shell/FileHelper.java
|
| @@ -5,6 +5,9 @@
|
| package org.chromium.mojo.shell;
|
|
|
| import android.content.Context;
|
| +import android.content.pm.PackageInfo;
|
| +import android.content.pm.PackageManager;
|
| +import android.util.Log;
|
|
|
| import java.io.BufferedInputStream;
|
| import java.io.BufferedOutputStream;
|
| @@ -12,6 +15,7 @@ import java.io.File;
|
| import java.io.FileInputStream;
|
| import java.io.FileNotFoundException;
|
| import java.io.FileOutputStream;
|
| +import java.io.FilenameFilter;
|
| import java.io.IOException;
|
| import java.io.InputStream;
|
| import java.io.OutputStream;
|
| @@ -22,13 +26,67 @@ import java.util.zip.ZipInputStream;
|
| * Helper methods for file extraction from APK assets and zip archives.
|
| */
|
| class FileHelper {
|
| + public static final String TAG = "MojoFileHelper";
|
| +
|
| // Size of the buffer used in streaming file operations.
|
| private static final int BUFFER_SIZE = 1024 * 1024;
|
| // Prefix used when naming temporary files.
|
| private static final String TEMP_FILE_PREFIX = "temp-";
|
|
|
| - static File extractFromAssets(Context context, String assetName, File outputDirectory,
|
| + // Looks for a timestamp file on disk that indicates the version of the APK that
|
| + // the resource paks were extracted from. Returns null if a timestamp was found
|
| + // and it indicates that the resources match the current APK. Otherwise returns
|
| + // a String that represents the filename of a timestamp to create.
|
| + private static String checkAssetTimestamp(Context context, File outputDir) {
|
| + final String timestampPrefix = "asset_timestamp-";
|
| + PackageManager pm = context.getPackageManager();
|
| + PackageInfo pi = null;
|
| +
|
| + try {
|
| + pi = pm.getPackageInfo(context.getPackageName(), 0);
|
| + } catch (PackageManager.NameNotFoundException e) {
|
| + return timestampPrefix;
|
| + }
|
| +
|
| + if (pi == null) {
|
| + return timestampPrefix;
|
| + }
|
| +
|
| + String expectedTimestamp = timestampPrefix + pi.versionCode + "-" + pi.lastUpdateTime;
|
| +
|
| + String[] timestamps = outputDir.list(new FilenameFilter() {
|
| + @Override
|
| + public boolean accept(File dir, String name) {
|
| + return name.startsWith(timestampPrefix);
|
| + }
|
| + });
|
| +
|
| + if (timestamps.length != 1) {
|
| + // If there's no timestamp, nuke to be safe as we can't tell the age of the files.
|
| + // If there's multiple timestamps, something's gone wrong so nuke.
|
| + return expectedTimestamp;
|
| + }
|
| +
|
| + if (!expectedTimestamp.equals(timestamps[0])) {
|
| + return expectedTimestamp;
|
| + }
|
| +
|
| + // timestamp file is already up-to date.
|
| + return null;
|
| + }
|
| +
|
| + public static File extractFromAssets(Context context, String assetName, File outputDirectory,
|
| boolean useTempFile) throws IOException, FileNotFoundException {
|
| + String timestampFile = null;
|
| + if (!useTempFile) {
|
| + timestampFile = checkAssetTimestamp(context, outputDirectory);
|
| + if (timestampFile != null) {
|
| + for (File child : outputDirectory.listFiles()) {
|
| + deleteRecursively(child);
|
| + }
|
| + }
|
| + }
|
| +
|
| File outputFile;
|
| if (useTempFile) {
|
| // Make the original filename part of the temp file name.
|
| @@ -37,12 +95,28 @@ class FileHelper {
|
| outputFile = File.createTempFile(TEMP_FILE_PREFIX, suffix, outputDirectory);
|
| } else {
|
| outputFile = new File(outputDirectory, assetName);
|
| + if (outputFile.exists()) {
|
| + return outputFile;
|
| + }
|
| }
|
|
|
| BufferedInputStream inputStream = new BufferedInputStream(
|
| context.getAssets().open(assetName));
|
| - writeStreamToFile(inputStream, outputFile);
|
| - inputStream.close();
|
| + try {
|
| + writeStreamToFile(inputStream, outputFile);
|
| + } finally {
|
| + inputStream.close();
|
| + }
|
| +
|
| + if (timestampFile != null) {
|
| + try {
|
| + new File(outputDirectory, timestampFile).createNewFile();
|
| + } catch (IOException e) {
|
| + // Worst case we don't write a timestamp, so we'll re-extract the asset next time.
|
| + Log.w(TAG, "Failed to write asset timestamp!");
|
| + }
|
| + }
|
| +
|
| return outputFile;
|
| }
|
|
|
| @@ -87,10 +161,13 @@ class FileHelper {
|
| throws IOException {
|
| byte[] buffer = new byte[BUFFER_SIZE];
|
| OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(outputFile));
|
| - int read;
|
| - while ((read = inputStream.read(buffer, 0, BUFFER_SIZE)) > 0) {
|
| - outputStream.write(buffer, 0, read);
|
| + try {
|
| + int read;
|
| + while ((read = inputStream.read(buffer, 0, BUFFER_SIZE)) > 0) {
|
| + outputStream.write(buffer, 0, read);
|
| + }
|
| + } finally {
|
| + outputStream.close();
|
| }
|
| - outputStream.close();
|
| }
|
| }
|
|
|