Chromium Code Reviews| 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 { |
|
nyquist
2016/02/10 07:08:32
Optional nit: Add a super-tiny comment as to what
agrieve
2016/02/10 16:47:15
Electing not to since it's private and is clear fr
| |
| 180 long lastModified = src.lastModified(); | 190 long lastModified = src.lastModified(); |
| 181 if (!dest.exists() || dest.lastModified() != lastModified) { | 191 if (!dest.exists() || dest.lastModified() != lastModified) { |
|
nyquist
2016/02/10 07:08:32
Optional nit: Would it be easier to read with some
agrieve
2016/02/10 16:47:15
Done.
| |
| 182 Log.i(TAG, "Copying " + src + " -> " + dest); | 192 Log.i(TAG, "Copying " + src + " -> " + dest); |
| 183 FileInputStream istream = new FileInputStream(src); | 193 FileInputStream istream = new FileInputStream(src); |
| 184 FileOutputStream ostream = new FileOutputStream(dest); | 194 FileOutputStream ostream = new FileOutputStream(dest); |
| 185 ostream.getChannel().transferFrom(istream.getChannel(), 0, istream.g etChannel().size()); | 195 ostream.getChannel().transferFrom(istream.getChannel(), 0, istream.g etChannel().size()); |
| 186 istream.close(); | 196 istream.close(); |
| 187 ostream.close(); | 197 ostream.close(); |
| 188 dest.setReadable(true, false); | 198 dest.setReadable(true, false); |
| 189 dest.setExecutable(true, false); | 199 dest.setExecutable(true, false); |
| 190 dest.setLastModified(lastModified); | 200 dest.setLastModified(lastModified); |
| 191 } else { | 201 return true; |
| 192 Log.i(TAG, "Up-to-date: " + dest); | |
| 193 } | 202 } |
| 203 return false; | |
| 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 |