OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 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.webapk.shell_apk.test.dex_optimizer; |
| 6 |
| 7 import android.app.Service; |
| 8 import android.content.Context; |
| 9 import android.content.Intent; |
| 10 import android.os.IBinder; |
| 11 |
| 12 import org.chromium.base.FileUtils; |
| 13 import org.chromium.webapk.lib.client.DexOptimizer; |
| 14 |
| 15 import java.io.File; |
| 16 import java.io.FileOutputStream; |
| 17 import java.io.IOException; |
| 18 import java.io.InputStream; |
| 19 import java.io.OutputStream; |
| 20 |
| 21 public class DexOptimizerServiceImpl extends Service { |
| 22 private static int sCounter = 0; |
| 23 |
| 24 public IBinder onBind(Intent intent) { |
| 25 return new IDexOptimizerService.Stub() { |
| 26 private static final String DEX_ASSET_NAME = "canary.dex"; |
| 27 private static final String DEX_DIR = "dex"; |
| 28 |
| 29 @Override |
| 30 public boolean deleteDexDirectory() { |
| 31 File dir = getDir(DEX_DIR, Context.MODE_PRIVATE); |
| 32 FileUtils.recursivelyDeleteFile(dir); |
| 33 return !dir.exists(); |
| 34 } |
| 35 |
| 36 @Override |
| 37 public String extractAndOptimizeDex() { |
| 38 // DexClassLoader does not generate an optimized dex if a DexCla
ssLoader was |
| 39 // previously constructed for the exact same dex path (presumabl
y due to |
| 40 // cached state in Android). This restriction does not seem to h
old if |
| 41 // DexOptimizerService is restarted. Hack around this restrictio
n by extracting the |
| 42 // dex from the APK to a different file every time. The hack is
okay because |
| 43 // deleting a dex file and immediately recreating an identical o
ne is only done in |
| 44 // tests. |
| 45 String dexName = "canary" + sCounter + ".dex"; |
| 46 ++sCounter; |
| 47 |
| 48 File dexFile = new File(getDir(DEX_DIR, Context.MODE_PRIVATE), d
exName); |
| 49 if (!extractAsset(DEX_ASSET_NAME, dexFile)) { |
| 50 return null; |
| 51 } |
| 52 |
| 53 // Make dex file world readable. |
| 54 try { |
| 55 dexFile.setReadable(true, false); |
| 56 } catch (Exception e) { |
| 57 return null; |
| 58 } |
| 59 |
| 60 if (!DexOptimizer.optimize(dexFile)) { |
| 61 return null; |
| 62 } |
| 63 return dexFile.getPath(); |
| 64 } |
| 65 |
| 66 |
| 67 /** |
| 68 * Extracts an asset from the app's APK to a file. |
| 69 * @param assetName Name of the asset to extract. |
| 70 * @param dest File to extract the asset to. |
| 71 * @return true on success. |
| 72 */ |
| 73 public boolean extractAsset(String assetName, File dest) { |
| 74 try (InputStream inputStream = getAssets().open(assetName); |
| 75 OutputStream outputStream = new FileOutputStream(dest)) { |
| 76 byte[] buffer = new byte[16 * 1024]; |
| 77 int c; |
| 78 while ((c = inputStream.read(buffer, 0, buffer.length)) != -
1) { |
| 79 outputStream.write(buffer, 0, c); |
| 80 } |
| 81 } catch (IOException e) { |
| 82 return false; |
| 83 } |
| 84 return true; |
| 85 } |
| 86 }; |
| 87 } |
| 88 } |
OLD | NEW |