OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.incrementalinstall; | 5 package org.chromium.incrementalinstall; |
6 | 6 |
| 7 import android.annotation.SuppressLint; |
7 import android.content.Context; | 8 import android.content.Context; |
8 import android.os.Build; | 9 import android.os.Build; |
9 import android.util.Log; | 10 import android.util.Log; |
10 | 11 |
11 import java.io.File; | 12 import java.io.File; |
12 import java.io.FileInputStream; | 13 import java.io.FileInputStream; |
13 import java.io.FileNotFoundException; | 14 import java.io.FileNotFoundException; |
14 import java.io.FileOutputStream; | 15 import java.io.FileOutputStream; |
15 import java.io.IOException; | 16 import java.io.IOException; |
16 import java.util.List; | 17 import java.util.List; |
(...skipping 16 matching lines...) Expand all Loading... |
33 mClassLoader = context.getClassLoader(); | 34 mClassLoader = context.getClassLoader(); |
34 mLibcoreOs = Reflect.getField(Class.forName("libcore.io.Libcore"), "os")
; | 35 mLibcoreOs = Reflect.getField(Class.forName("libcore.io.Libcore"), "os")
; |
35 mProcessUid = (Integer) Reflect.invokeMethod(mLibcoreOs, "getuid"); | 36 mProcessUid = (Integer) Reflect.invokeMethod(mLibcoreOs, "getuid"); |
36 mIsPrimaryProcess = context.getApplicationInfo().uid == mProcessUid; | 37 mIsPrimaryProcess = context.getApplicationInfo().uid == mProcessUid; |
37 Log.i(TAG, "uid=" + mProcessUid + " (isPrimary=" + mIsPrimaryProcess + "
)"); | 38 Log.i(TAG, "uid=" + mProcessUid + " (isPrimary=" + mIsPrimaryProcess + "
)"); |
38 } | 39 } |
39 | 40 |
40 /** | 41 /** |
41 * Loads all dex files within |dexDir| into the app's ClassLoader. | 42 * Loads all dex files within |dexDir| into the app's ClassLoader. |
42 */ | 43 */ |
| 44 @SuppressLint({ |
| 45 "SetWorldReadable", |
| 46 "SetWorldWritable", |
| 47 }) |
43 void loadDexFiles(File dexDir) throws ReflectiveOperationException, FileNotF
oundException { | 48 void loadDexFiles(File dexDir) throws ReflectiveOperationException, FileNotF
oundException { |
44 Log.i(TAG, "Installing dex files from: " + dexDir); | 49 Log.i(TAG, "Installing dex files from: " + dexDir); |
45 File[] dexFilesArr = dexDir.listFiles(); | 50 File[] dexFilesArr = dexDir.listFiles(); |
46 if (dexFilesArr == null) { | 51 if (dexFilesArr == null) { |
47 throw new FileNotFoundException("Dex dir does not exist: " + dexDir)
; | 52 throw new FileNotFoundException("Dex dir does not exist: " + dexDir)
; |
48 } | 53 } |
49 // The optimized dex files will be owned by this process' user. | 54 // The optimized dex files will be owned by this process' user. |
50 // Store them within the app's data dir rather than on /data/local/tmp | 55 // Store them within the app's data dir rather than on /data/local/tmp |
51 // so that they are still deleted (by the OS) when we uninstall | 56 // so that they are still deleted (by the OS) when we uninstall |
52 // (even on a non-rooted device). | 57 // (even on a non-rooted device). |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 | 98 |
94 Object dexPathList = Reflect.getField(mClassLoader, "pathList"); | 99 Object dexPathList = Reflect.getField(mClassLoader, "pathList"); |
95 Object[] dexElements = (Object[]) Reflect.getField(dexPathList, "dexElem
ents"); | 100 Object[] dexElements = (Object[]) Reflect.getField(dexPathList, "dexElem
ents"); |
96 dexElements = addDexElements(dexFilesArr, optimizedDir, dexElements); | 101 dexElements = addDexElements(dexFilesArr, optimizedDir, dexElements); |
97 Reflect.setField(dexPathList, "dexElements", dexElements); | 102 Reflect.setField(dexPathList, "dexElements", dexElements); |
98 } | 103 } |
99 | 104 |
100 /** | 105 /** |
101 * Sets up all libraries within |libDir| to be loadable by System.loadLibrar
y(). | 106 * Sets up all libraries within |libDir| to be loadable by System.loadLibrar
y(). |
102 */ | 107 */ |
| 108 @SuppressLint("SetWorldReadable") |
103 void importNativeLibs(File libDir) throws ReflectiveOperationException, IOEx
ception { | 109 void importNativeLibs(File libDir) throws ReflectiveOperationException, IOEx
ception { |
104 Log.i(TAG, "Importing native libraries from: " + libDir); | 110 Log.i(TAG, "Importing native libraries from: " + libDir); |
105 if (!libDir.exists()) { | 111 if (!libDir.exists()) { |
106 Log.i(TAG, "No native libs exist."); | 112 Log.i(TAG, "No native libs exist."); |
107 return; | 113 return; |
108 } | 114 } |
109 // The library copying is not necessary on older devices, but we do it a
nyways to | 115 // The library copying is not necessary on older devices, but we do it a
nyways to |
110 // simplify things (it's fast compared to dexing). | 116 // simplify things (it's fast compared to dexing). |
111 // https://code.google.com/p/android/issues/detail?id=79480 | 117 // https://code.google.com/p/android/issues/detail?id=79480 |
112 File localLibsDir = new File(mAppFilesSubDir, "lib"); | 118 File localLibsDir = new File(mAppFilesSubDir, "lib"); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 File dest = new File(dstDir, f.getName()); | 184 File dest = new File(dstDir, f.getName()); |
179 if (!copyIfModified(f, dest)) { | 185 if (!copyIfModified(f, dest)) { |
180 numNotChanged++; | 186 numNotChanged++; |
181 } | 187 } |
182 } | 188 } |
183 if (numNotChanged > 0) { | 189 if (numNotChanged > 0) { |
184 Log.i(TAG, numNotChanged + " libs already up to date."); | 190 Log.i(TAG, numNotChanged + " libs already up to date."); |
185 } | 191 } |
186 } | 192 } |
187 | 193 |
| 194 @SuppressLint("SetWorldReadable") |
188 private static boolean copyIfModified(File src, File dest) throws IOExceptio
n { | 195 private static boolean copyIfModified(File src, File dest) throws IOExceptio
n { |
189 long lastModified = src.lastModified(); | 196 long lastModified = src.lastModified(); |
190 if (dest.exists() && dest.lastModified() == lastModified) { | 197 if (dest.exists() && dest.lastModified() == lastModified) { |
191 return false; | 198 return false; |
192 } | 199 } |
193 Log.i(TAG, "Copying " + src + " -> " + dest); | 200 Log.i(TAG, "Copying " + src + " -> " + dest); |
194 FileInputStream istream = new FileInputStream(src); | 201 FileInputStream istream = new FileInputStream(src); |
195 FileOutputStream ostream = new FileOutputStream(dest); | 202 FileOutputStream ostream = new FileOutputStream(dest); |
196 ostream.getChannel().transferFrom(istream.getChannel(), 0, istream.getCh
annel().size()); | 203 ostream.getChannel().transferFrom(istream.getChannel(), 0, istream.getCh
annel().size()); |
197 istream.close(); | 204 istream.close(); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 mClassLoader, ret); | 245 mClassLoader, ret); |
239 } else { | 246 } else { |
240 dexFile = Reflect.invokeMethod(clazz, "loadDexFile", file, optim
izedDirectory); | 247 dexFile = Reflect.invokeMethod(clazz, "loadDexFile", file, optim
izedDirectory); |
241 } | 248 } |
242 ret[curDexElements.length + i] = | 249 ret[curDexElements.length + i] = |
243 Reflect.newInstance(entryClazz, emptyDir, false, file, dexFi
le); | 250 Reflect.newInstance(entryClazz, emptyDir, false, file, dexFi
le); |
244 } | 251 } |
245 return ret; | 252 return ret; |
246 } | 253 } |
247 } | 254 } |
OLD | NEW |