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

Side by Side Diff: mojo/shell/android/apk/src/org/chromium/mojo/shell/FileHelper.java

Issue 1049993002: Get mojo_shell building inside chromium checkout. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix presubmit Created 5 years, 8 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.mojo.shell;
6
7 import android.content.Context;
8 import android.content.pm.PackageInfo;
9 import android.content.pm.PackageManager;
10 import android.util.Log;
11
12 import java.io.BufferedInputStream;
13 import java.io.BufferedOutputStream;
14 import java.io.File;
15 import java.io.FileInputStream;
16 import java.io.FileNotFoundException;
17 import java.io.FileOutputStream;
18 import java.io.FilenameFilter;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.OutputStream;
22 import java.util.zip.ZipEntry;
23 import java.util.zip.ZipInputStream;
24
25 /**
26 * Helper methods for file extraction from APK assets and zip archives.
27 */
28 class FileHelper {
29 public static final String TAG = "MojoFileHelper";
30
31 // Size of the buffer used in streaming file operations.
32 private static final int BUFFER_SIZE = 1024 * 1024;
33 // Prefix used when naming temporary files.
34 private static final String TEMP_FILE_PREFIX = "temp-";
35 // Prefix used when naming timestamp files.
36 private static final String TIMESTAMP_PREFIX = "asset_timestamp-";
37
38 /**
39 * Looks for a timestamp file on disk that indicates the version of the APK that the resource
40 * assets were extracted from. Returns null if a timestamp was found and it indicates that the
41 * resources match the current APK. Otherwise returns a String that represen ts the filename of a
42 * timestamp to create.
43 */
44 private static String checkAssetTimestamp(Context context, File outputDir) {
45 PackageManager pm = context.getPackageManager();
46 PackageInfo pi = null;
47
48 try {
49 pi = pm.getPackageInfo(context.getPackageName(), 0);
50 } catch (PackageManager.NameNotFoundException e) {
51 return TIMESTAMP_PREFIX;
52 }
53
54 if (pi == null) {
55 return TIMESTAMP_PREFIX;
56 }
57
58 String expectedTimestamp = TIMESTAMP_PREFIX + pi.versionCode + "-" + pi. lastUpdateTime;
59
60 String[] timestamps = outputDir.list(new FilenameFilter() {
61 @Override
62 public boolean accept(File dir, String name) {
63 return name.startsWith(TIMESTAMP_PREFIX);
64 }
65 });
66
67 if (timestamps.length != 1) {
68 // If there's no timestamp, nuke to be safe as we can't tell the age of the files.
69 // If there's multiple timestamps, something's gone wrong so nuke.
70 return expectedTimestamp;
71 }
72
73 if (!expectedTimestamp.equals(timestamps[0])) {
74 return expectedTimestamp;
75 }
76
77 // Timestamp file is already up-to date.
78 return null;
79 }
80
81 public static File extractFromAssets(Context context, String assetName, File outputDirectory,
82 boolean useTempFile) throws IOException, FileNotFoundException {
83 String timestampToCreate = null;
84 if (!useTempFile) {
85 timestampToCreate = checkAssetTimestamp(context, outputDirectory);
86 if (timestampToCreate != null) {
87 for (File child : outputDirectory.listFiles()) {
88 deleteRecursively(child);
89 }
90 }
91 }
92
93 File outputFile;
94 if (useTempFile) {
95 // Make the original filename part of the temp file name.
96 // TODO(ppi): do we need to sanitize the suffix?
97 String suffix = "-" + assetName;
98 outputFile = File.createTempFile(TEMP_FILE_PREFIX, suffix, outputDir ectory);
99 } else {
100 outputFile = new File(outputDirectory, assetName);
101 if (outputFile.exists()) {
102 return outputFile;
103 }
104 }
105
106 BufferedInputStream inputStream = new BufferedInputStream(
107 context.getAssets().open(assetName));
108 try {
109 writeStreamToFile(inputStream, outputFile);
110 } finally {
111 inputStream.close();
112 }
113
114 if (timestampToCreate != null) {
115 try {
116 new File(outputDirectory, timestampToCreate).createNewFile();
117 } catch (IOException e) {
118 // In the worst case we don't write a timestamp, so we'll re-ext ract the asset next
119 // time.
120 Log.w(TAG, "Failed to write asset timestamp!");
121 }
122 }
123
124 return outputFile;
125 }
126
127 /**
128 * Extracts the file of the given extension from the archive. Throws FileNot FoundException if no
129 * matching file is found.
130 */
131 static File extractFromArchive(File archive, String suffixToMatch,
132 File outputDirectory) throws IOException, FileNotFoundException {
133 ZipInputStream zip = new ZipInputStream(new BufferedInputStream(new File InputStream(
134 archive)));
135 ZipEntry entry;
136 while ((entry = zip.getNextEntry()) != null) {
137 if (entry.getName().endsWith(suffixToMatch)) {
138 // Make the original filename part of the temp file name.
139 // TODO(ppi): do we need to sanitize the suffix?
140 String suffix = "-" + new File(entry.getName()).getName();
141 File extractedFile = File.createTempFile(TEMP_FILE_PREFIX, suffi x,
142 outputDirectory);
143 writeStreamToFile(zip, extractedFile);
144 zip.close();
145 return extractedFile;
146 }
147 }
148 zip.close();
149 throw new FileNotFoundException();
150 }
151
152 /**
153 * Deletes a file or directory. Directory will be deleted even if not empty.
154 */
155 static void deleteRecursively(File file) {
156 if (file.isDirectory()) {
157 for (File child : file.listFiles()) {
158 deleteRecursively(child);
159 }
160 }
161 if (!file.delete()) {
162 Log.w(TAG, "Unable to delete file: " + file.getAbsolutePath());
163 }
164 }
165
166 private static void writeStreamToFile(InputStream inputStream, File outputFi le)
167 throws IOException {
168 byte[] buffer = new byte[BUFFER_SIZE];
169 OutputStream outputStream = new BufferedOutputStream(new FileOutputStrea m(outputFile));
170 try {
171 int read;
172 while ((read = inputStream.read(buffer, 0, BUFFER_SIZE)) > 0) {
173 outputStream.write(buffer, 0, read);
174 }
175 } finally {
176 outputStream.close();
177 }
178 }
179 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698