Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(27)

Unified Diff: sky/shell/android/org/domokit/sky/shell/ResourceExtractor.java

Issue 1221153002: Switch SkyShell to its own ResourceExtractor (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sky/shell/BUILD.gn ('k') | sky/shell/android/org/domokit/sky/shell/SkyApplication.java » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sky/shell/android/org/domokit/sky/shell/ResourceExtractor.java
diff --git a/sky/shell/android/org/domokit/sky/shell/ResourceExtractor.java b/sky/shell/android/org/domokit/sky/shell/ResourceExtractor.java
new file mode 100644
index 0000000000000000000000000000000000000000..3976bb9dd2124a87dd48ca0daea638107b405f22
--- /dev/null
+++ b/sky/shell/android/org/domokit/sky/shell/ResourceExtractor.java
@@ -0,0 +1,186 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.domokit.sky.shell;
+
+import android.content.Context;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.res.AssetManager;
+import android.os.AsyncTask;
+import android.util.Log;
+
+import org.chromium.base.PathUtils;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashSet;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * A class to intialize the native code.
+ **/
+public class ResourceExtractor {
+ private static final String TAG = "ResourceExtractor";
+ private static final String TIMESTAMP_PREFIX = "res_timestamp-";
+
+ private class ExtractTask extends AsyncTask<Void, Void, Void> {
+ private static final int BUFFER_SIZE = 16 * 1024;
+
+ public ExtractTask() { }
+
+ private void extractResources() {
+ final File dataDir = new File(PathUtils.getDataDirectory(mContext));
+
+ final String timestamp = checkTimestamp(dataDir);
+ if (timestamp != null) {
+ deleteFiles();
+ }
+
+ final AssetManager manager = mContext.getResources().getAssets();
+ try {
+ byte[] buffer = null;
+ final String[] assets = manager.list("");
+ for (String asset : assets) {
+ if (!mResources.contains(asset))
+ continue;
+ final File output = new File(dataDir, asset);
+ if (output.exists())
+ continue;
+ InputStream is = null;
+ OutputStream os = null;
+ try {
+ is = manager.open(asset);
+ os = new FileOutputStream(output);
+ if (buffer == null) {
+ buffer = new byte[BUFFER_SIZE];
+ }
+
+ int count = 0;
+ while ((count = is.read(buffer, 0, BUFFER_SIZE)) != -1) {
+ os.write(buffer, 0, count);
+ }
+ os.flush();
+ } finally {
+ try {
+ if (is != null) {
+ is.close();
+ }
+ } finally {
+ if (os != null) {
+ os.close();
+ }
+ }
+ }
+ }
+ } catch (IOException e) {
+ Log.w(TAG, "Exception unpacking resources: " + e.getMessage());
+ deleteFiles();
+ return;
+ }
+
+ if (timestamp != null) {
+ try {
+ new File(dataDir, timestamp).createNewFile();
+ } catch (IOException e) {
+ Log.w(TAG, "Failed to write resource timestamp");
+ }
+ }
+ }
+
+ private String checkTimestamp(File dataDir) {
+ PackageManager packageManager = mContext.getPackageManager();
+ PackageInfo packageInfo = null;
+
+ try {
+ packageInfo = packageManager.getPackageInfo(mContext.getPackageName(), 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ return TIMESTAMP_PREFIX;
+ }
+
+ if (packageInfo == null) {
+ return TIMESTAMP_PREFIX;
+ }
+
+ String expectedTimestamp =
+ TIMESTAMP_PREFIX + packageInfo.versionCode + "-" + packageInfo.lastUpdateTime;
+
+ final String[] existingTimestamps = getExistingTimestamps(dataDir);
+ if (existingTimestamps.length != 1
+ || !expectedTimestamp.equals(existingTimestamps[0])) {
+ return expectedTimestamp;
+ }
+
+ return null;
+ }
+
+ @Override
+ protected Void doInBackground(Void... unused) {
+ extractResources();
+ return null;
+ }
+ }
+
+ private final Context mContext;
+ private final HashSet<String> mResources;
+ private ExtractTask mExtractTask;
+
+ public ResourceExtractor(Context context) {
+ mContext = context;
+ mResources = new HashSet<String>();
+ }
+
+ public void addResources(String[] resources) {
+ for (String resource : resources) {
+ mResources.add(resource);
+ }
+ }
+
+ public void start() {
+ assert mExtractTask == null;
+ mExtractTask = new ExtractTask();
+ mExtractTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
+ }
+
+ public void waitForCompletion() {
+ assert mExtractTask != null;
+
+ try {
+ mExtractTask.get();
+ } catch (CancellationException e) {
+ deleteFiles();
+ } catch (ExecutionException e2) {
+ deleteFiles();
+ } catch (InterruptedException e3) {
+ deleteFiles();
+ }
+ }
+
+ private String[] getExistingTimestamps(File dataDir) {
+ return dataDir.list(new FilenameFilter() {
+ @Override
+ public boolean accept(File dir, String name) {
+ return name.startsWith(TIMESTAMP_PREFIX);
+ }
+ });
+ }
+
+ private void deleteFiles() {
+ final File dataDir = new File(PathUtils.getDataDirectory(mContext));
+ for (String resource : mResources) {
+ final File file = new File(dataDir, resource);
+ if (file.exists()) {
+ file.delete();
+ }
+ }
+ for (String timestamp : getExistingTimestamps(dataDir)) {
+ new File(dataDir, timestamp).delete();
+ }
+ }
+}
« no previous file with comments | « sky/shell/BUILD.gn ('k') | sky/shell/android/org/domokit/sky/shell/SkyApplication.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698