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.content.Context; | 7 import android.content.Context; |
8 import android.os.Build; | 8 import android.os.Build; |
9 import android.util.Log; | 9 import android.util.Log; |
10 | 10 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 Object[] additionalElements = makeDexElements(dexFilesArr, optimizedDir)
; | 96 Object[] additionalElements = makeDexElements(dexFilesArr, optimizedDir)
; |
97 Reflect.setField( | 97 Reflect.setField( |
98 dexPathList, "dexElements", Reflect.concatArrays(dexElements, ad
ditionalElements)); | 98 dexPathList, "dexElements", Reflect.concatArrays(dexElements, ad
ditionalElements)); |
99 } | 99 } |
100 | 100 |
101 /** | 101 /** |
102 * Sets up all libraries within |libDir| to be loadable by System.loadLibrar
y(). | 102 * Sets up all libraries within |libDir| to be loadable by System.loadLibrar
y(). |
103 */ | 103 */ |
104 void importNativeLibs(File libDir) throws ReflectiveOperationException, IOEx
ception { | 104 void importNativeLibs(File libDir) throws ReflectiveOperationException, IOEx
ception { |
105 Log.i(TAG, "Importing native libraries from: " + libDir); | 105 Log.i(TAG, "Importing native libraries from: " + libDir); |
| 106 if (!libDir.exists()) { |
| 107 Log.i(TAG, "No native libs exist."); |
| 108 return; |
| 109 } |
106 // The library copying is not necessary on older devices, but we do it a
nyways to | 110 // The library copying is not necessary on older devices, but we do it a
nyways to |
107 // simplify things (it's fast compared to dexing). | 111 // simplify things (it's fast compared to dexing). |
108 // https://code.google.com/p/android/issues/detail?id=79480 | 112 // https://code.google.com/p/android/issues/detail?id=79480 |
109 File localLibsDir = new File(mAppFilesSubDir, "lib"); | 113 File localLibsDir = new File(mAppFilesSubDir, "lib"); |
110 File copyLibsLockFile = new File(mAppFilesSubDir, "libcopy.lock"); | 114 File copyLibsLockFile = new File(mAppFilesSubDir, "libcopy.lock"); |
111 if (mIsPrimaryProcess) { | 115 if (mIsPrimaryProcess) { |
112 // Primary process: Copies native libraries into the app's data dire
ctory. | 116 // Primary process: Copies native libraries into the app's data dire
ctory. |
113 ensureAppFilesSubDirExists(); | 117 ensureAppFilesSubDirExists(); |
114 LockFile lockFile = LockFile.acquireRuntimeLock(copyLibsLockFile); | 118 LockFile lockFile = LockFile.acquireRuntimeLock(copyLibsLockFile); |
115 if (lockFile == null) { | 119 if (lockFile == null) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 return; | 166 return; |
163 } | 167 } |
164 Object[] additionalElements = makeNativePathElements(newDirs); | 168 Object[] additionalElements = makeNativePathElements(newDirs); |
165 Reflect.setField( | 169 Reflect.setField( |
166 dexPathList, "nativeLibraryPathElements", | 170 dexPathList, "nativeLibraryPathElements", |
167 Reflect.concatArrays(nativeLibraryPathElements, additionalElemen
ts)); | 171 Reflect.concatArrays(nativeLibraryPathElements, additionalElemen
ts)); |
168 } | 172 } |
169 | 173 |
170 private static void copyChangedFiles(File srcDir, File dstDir) throws IOExce
ption { | 174 private static void copyChangedFiles(File srcDir, File dstDir) throws IOExce
ption { |
171 // No need to delete stale libs since libraries are loaded explicitly. | 175 // No need to delete stale libs since libraries are loaded explicitly. |
| 176 int numNotChanged = 0; |
172 for (File f : srcDir.listFiles()) { | 177 for (File f : srcDir.listFiles()) { |
173 // Note: Tried using hardlinks, but resulted in EACCES exceptions. | 178 // Note: Tried using hardlinks, but resulted in EACCES exceptions. |
174 File dest = new File(dstDir, f.getName()); | 179 File dest = new File(dstDir, f.getName()); |
175 copyIfModified(f, dest); | 180 if (!copyIfModified(f, dest)) { |
| 181 numNotChanged++; |
| 182 } |
| 183 } |
| 184 if (numNotChanged > 0) { |
| 185 Log.i(TAG, numNotChanged + " libs already up-to-date."); |
176 } | 186 } |
177 } | 187 } |
178 | 188 |
179 private static void copyIfModified(File src, File dest) throws IOException { | 189 private static boolean copyIfModified(File src, File dest) throws IOExceptio
n { |
180 long lastModified = src.lastModified(); | 190 long lastModified = src.lastModified(); |
181 if (!dest.exists() || dest.lastModified() != lastModified) { | 191 if (dest.exists() && dest.lastModified() == lastModified) { |
182 Log.i(TAG, "Copying " + src + " -> " + dest); | 192 return false; |
183 FileInputStream istream = new FileInputStream(src); | |
184 FileOutputStream ostream = new FileOutputStream(dest); | |
185 ostream.getChannel().transferFrom(istream.getChannel(), 0, istream.g
etChannel().size()); | |
186 istream.close(); | |
187 ostream.close(); | |
188 dest.setReadable(true, false); | |
189 dest.setExecutable(true, false); | |
190 dest.setLastModified(lastModified); | |
191 } else { | |
192 Log.i(TAG, "Up-to-date: " + dest); | |
193 } | 193 } |
| 194 Log.i(TAG, "Copying " + src + " -> " + dest); |
| 195 FileInputStream istream = new FileInputStream(src); |
| 196 FileOutputStream ostream = new FileOutputStream(dest); |
| 197 ostream.getChannel().transferFrom(istream.getChannel(), 0, istream.getCh
annel().size()); |
| 198 istream.close(); |
| 199 ostream.close(); |
| 200 dest.setReadable(true, false); |
| 201 dest.setExecutable(true, false); |
| 202 dest.setLastModified(lastModified); |
| 203 return true; |
194 } | 204 } |
195 | 205 |
196 private void ensureAppFilesSubDirExists() { | 206 private void ensureAppFilesSubDirExists() { |
197 mAppFilesSubDir.mkdir(); | 207 mAppFilesSubDir.mkdir(); |
198 mAppFilesSubDir.setExecutable(true, false); | 208 mAppFilesSubDir.setExecutable(true, false); |
199 } | 209 } |
200 | 210 |
201 private void createSymlink(String to, File from) throws ReflectiveOperationE
xception { | 211 private void createSymlink(String to, File from) throws ReflectiveOperationE
xception { |
202 Reflect.invokeMethod(mLibcoreOs, "symlink", to, from.getAbsolutePath()); | 212 Reflect.invokeMethod(mLibcoreOs, "symlink", to, from.getAbsolutePath()); |
203 } | 213 } |
(...skipping 15 matching lines...) Expand all Loading... |
219 Object[] entries = new Object[files.length]; | 229 Object[] entries = new Object[files.length]; |
220 File emptyDir = new File(""); | 230 File emptyDir = new File(""); |
221 for (int i = 0; i < files.length; ++i) { | 231 for (int i = 0; i < files.length; ++i) { |
222 File file = files[i]; | 232 File file = files[i]; |
223 Object dexFile = Reflect.invokeMethod(clazz, "loadDexFile", file, op
timizedDirectory); | 233 Object dexFile = Reflect.invokeMethod(clazz, "loadDexFile", file, op
timizedDirectory); |
224 entries[i] = Reflect.newInstance(entryClazz, emptyDir, false, file,
dexFile); | 234 entries[i] = Reflect.newInstance(entryClazz, emptyDir, false, file,
dexFile); |
225 } | 235 } |
226 return entries; | 236 return entries; |
227 } | 237 } |
228 } | 238 } |
OLD | NEW |