Index: webapk/shell_apk/javatests/src/org/chromium/webapk/shell_apk/DexLoaderTest.java |
diff --git a/webapk/shell_apk/javatests/src/org/chromium/webapk/shell_apk/DexLoaderTest.java b/webapk/shell_apk/javatests/src/org/chromium/webapk/shell_apk/DexLoaderTest.java |
deleted file mode 100644 |
index db04700b6fb5c9464630b2d10472db440e73df58..0000000000000000000000000000000000000000 |
--- a/webapk/shell_apk/javatests/src/org/chromium/webapk/shell_apk/DexLoaderTest.java |
+++ /dev/null |
@@ -1,319 +0,0 @@ |
-// Copyright 2016 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-package org.chromium.webapk.shell_apk; |
- |
-import android.content.ComponentName; |
-import android.content.Context; |
-import android.content.Intent; |
-import android.content.ServiceConnection; |
-import android.os.FileObserver; |
-import android.os.IBinder; |
-import android.os.RemoteException; |
-import android.test.InstrumentationTestCase; |
-import android.test.suitebuilder.annotation.MediumTest; |
- |
-import dalvik.system.DexFile; |
- |
-import org.chromium.base.FileUtils; |
-import org.chromium.content.browser.test.util.CallbackHelper; |
-import org.chromium.webapk.lib.common.WebApkUtils; |
-import org.chromium.webapk.shell_apk.test.dex_optimizer.IDexOptimizerService; |
- |
-import java.io.File; |
-import java.util.ArrayList; |
-import java.util.Arrays; |
- |
-public class DexLoaderTest extends InstrumentationTestCase { |
- /** |
- * Package of APK to load dex file from and package which provides DexOptimizerService. |
- */ |
- private static final String DEX_OPTIMIZER_SERVICE_PACKAGE = |
- "org.chromium.webapk.shell_apk.test.dex_optimizer"; |
- |
- /** |
- * Class which implements DexOptimizerService. |
- */ |
- private static final String DEX_OPTIMIZER_SERVICE_CLASS_NAME = |
- "org.chromium.webapk.shell_apk.test.dex_optimizer.DexOptimizerServiceImpl"; |
- |
- /** |
- * Name of the dex file in DexOptimizer.apk. |
- */ |
- private static final String DEX_ASSET_NAME = "canary.dex"; |
- |
- /** |
- * Class to load to check whether dex is valid. |
- */ |
- private static final String CANARY_CLASS_NAME = |
- "org.chromium.webapk.shell_apk.test.canary.Canary"; |
- |
- private Context mContext; |
- private Context mRemoteContext; |
- private File mRemoteDexFile; |
- private File mLocalDexDir; |
- private IDexOptimizerService mDexOptimizerService; |
- private ServiceConnection mServiceConnection; |
- |
- /** |
- * Monitors read files and modified files in the directory passed to the constructor. |
- */ |
- private class FileMonitor extends FileObserver { |
- public ArrayList<String> mReadPaths = new ArrayList<String>(); |
- public ArrayList<String> mModifiedPaths = new ArrayList<String>(); |
- |
- public FileMonitor(File directory) { |
- super(directory.getPath()); |
- } |
- |
- @Override |
- public void onEvent(int event, String path) { |
- switch (event) { |
- case FileObserver.ACCESS: |
- mReadPaths.add(path); |
- break; |
- case FileObserver.CREATE: |
- case FileObserver.DELETE: |
- case FileObserver.DELETE_SELF: |
- case FileObserver.MODIFY: |
- mModifiedPaths.add(path); |
- break; |
- default: |
- break; |
- } |
- } |
- } |
- |
- @Override |
- protected void setUp() { |
- mContext = getInstrumentation().getTargetContext(); |
- |
- mRemoteContext = WebApkUtils.getHostBrowserContext(mContext); |
- if (mRemoteContext == null) { |
- fail("Failed to get remote context."); |
- } |
- |
- mLocalDexDir = mContext.getDir("dex", Context.MODE_PRIVATE); |
- if (mLocalDexDir.exists()) { |
- FileUtils.recursivelyDeleteFile(mLocalDexDir); |
- if (mLocalDexDir.exists()) { |
- fail("Could not delete local dex directory."); |
- } |
- } |
- |
- connectToDexOptimizerService(); |
- |
- try { |
- if (!mDexOptimizerService.deleteDexDirectory()) { |
- fail("Could not delete remote dex directory."); |
- } |
- } catch (RemoteException e) { |
- e.printStackTrace(); |
- fail("Remote crashed during setup."); |
- } |
- } |
- |
- @Override |
- public void tearDown() { |
- mContext.unbindService(mServiceConnection); |
- } |
- |
- /** |
- * Test that {@DexLoader#load()} can create a ClassLoader from a dex and optimized dex in |
- * another app's data directory. |
- */ |
- @MediumTest |
- public void testLoadFromRemoteDataDir() { |
- // Extract the dex file into another app's data directory and optimize the dex. |
- String remoteDexFilePath = null; |
- try { |
- remoteDexFilePath = mDexOptimizerService.extractAndOptimizeDex(); |
- } catch (RemoteException e) { |
- e.printStackTrace(); |
- fail("Remote crashed."); |
- } |
- |
- if (remoteDexFilePath == null) { |
- fail("Could not extract and optimize dex."); |
- } |
- |
- // Check that the Android OS knows about the optimized dex file for |
- // {@link remoteDexFilePath}. |
- File remoteDexFile = new File(remoteDexFilePath); |
- assertFalse(isDexOptNeeded(remoteDexFile)); |
- |
- ClassLoader loader = DexLoader.load( |
- mRemoteContext, DEX_ASSET_NAME, CANARY_CLASS_NAME, remoteDexFile, mLocalDexDir); |
- assertNotNull(loader); |
- assertTrue(canLoadCanaryClass(loader)); |
- |
- // Check that {@link DexLoader#load()} did not use the fallback path. |
- assertFalse(mLocalDexDir.exists()); |
- } |
- |
- /** |
- * That that {@link DexLoader#load()} falls back to extracting the dex from the APK to the |
- * local data directory and creating the ClassLoader from the extracted dex if creating the |
- * ClassLoader from the cached data in the remote Context's data directory fails. |
- */ |
- @MediumTest |
- public void testLoadFromLocalDataDir() { |
- ClassLoader loader = DexLoader.load( |
- mRemoteContext, DEX_ASSET_NAME, CANARY_CLASS_NAME, null, mLocalDexDir); |
- assertNotNull(loader); |
- assertTrue(canLoadCanaryClass(loader)); |
- |
- // Check that the dex file was extracted to the local data directory and that a directory |
- // was created for the optimized dex. |
- assertTrue(mLocalDexDir.exists()); |
- File[] localDexDirFiles = mLocalDexDir.listFiles(); |
- Arrays.sort(mLocalDexDir.listFiles()); |
- assertEquals(2, localDexDirFiles.length); |
- assertEquals(DEX_ASSET_NAME, localDexDirFiles[0].getName()); |
- assertFalse(localDexDirFiles[0].isDirectory()); |
- assertEquals("optimized", localDexDirFiles[1].getName()); |
- assertTrue(localDexDirFiles[1].isDirectory()); |
- } |
- |
- /** |
- * Test that {@link DexLoader#load()} does not extract the dex file from the APK if the dex file |
- * was extracted in a previous call to {@link DexLoader#load()} |
- */ |
- @MediumTest |
- public void testPreviouslyLoadedFromLocalDataDir() { |
- mLocalDexDir.mkdir(); |
- |
- { |
- // Load dex the first time. This should extract the dex file from the APK's assets and |
- // generate the optimized dex file. |
- FileMonitor localDexDirMonitor = new FileMonitor(mLocalDexDir); |
- localDexDirMonitor.startWatching(); |
- ClassLoader loader = DexLoader.load( |
- mRemoteContext, DEX_ASSET_NAME, CANARY_CLASS_NAME, null, mLocalDexDir); |
- localDexDirMonitor.stopWatching(); |
- |
- assertNotNull(loader); |
- assertTrue(canLoadCanaryClass(loader)); |
- |
- assertTrue(localDexDirMonitor.mReadPaths.contains(DEX_ASSET_NAME)); |
- assertTrue(localDexDirMonitor.mModifiedPaths.contains(DEX_ASSET_NAME)); |
- } |
- { |
- // Load dex a second time. We should use the already extracted dex file. |
- FileMonitor localDexDirMonitor = new FileMonitor(mLocalDexDir); |
- localDexDirMonitor.startWatching(); |
- ClassLoader loader = DexLoader.load( |
- mRemoteContext, DEX_ASSET_NAME, CANARY_CLASS_NAME, null, mLocalDexDir); |
- localDexDirMonitor.stopWatching(); |
- |
- // The returned ClassLoader should be valid. |
- assertNotNull(loader); |
- assertTrue(canLoadCanaryClass(loader)); |
- |
- // We should not have modified any files and have used the already extracted dex file. |
- assertTrue(localDexDirMonitor.mReadPaths.contains(DEX_ASSET_NAME)); |
- assertTrue(localDexDirMonitor.mModifiedPaths.isEmpty()); |
- } |
- } |
- |
- /** |
- * Test that {@link DexLoader#load()} re-extracts the dex file from the APK after a call to |
- * {@link DexLoader#deleteCachedDexes()}. |
- */ |
- @MediumTest |
- public void testLoadAfterDeleteCachedDexes() { |
- mLocalDexDir.mkdir(); |
- |
- { |
- // Load dex the first time. This should extract the dex file from the APK's assets and |
- // generate the optimized dex file. |
- FileMonitor localDexDirMonitor = new FileMonitor(mLocalDexDir); |
- localDexDirMonitor.startWatching(); |
- ClassLoader loader = DexLoader.load( |
- mRemoteContext, DEX_ASSET_NAME, CANARY_CLASS_NAME, null, mLocalDexDir); |
- localDexDirMonitor.stopWatching(); |
- |
- assertNotNull(loader); |
- assertTrue(canLoadCanaryClass(loader)); |
- |
- assertTrue(localDexDirMonitor.mReadPaths.contains(DEX_ASSET_NAME)); |
- assertTrue(localDexDirMonitor.mModifiedPaths.contains(DEX_ASSET_NAME)); |
- } |
- |
- DexLoader.deleteCachedDexes(mLocalDexDir); |
- |
- { |
- // Load dex a second time. |
- FileMonitor localDexDirMonitor = new FileMonitor(mLocalDexDir); |
- localDexDirMonitor.startWatching(); |
- ClassLoader loader = DexLoader.load( |
- mRemoteContext, DEX_ASSET_NAME, CANARY_CLASS_NAME, null, mLocalDexDir); |
- localDexDirMonitor.stopWatching(); |
- |
- // The returned ClassLoader should be valid. |
- assertNotNull(loader); |
- assertTrue(canLoadCanaryClass(loader)); |
- |
- // We should have re-extracted the dex from the APK's assets. |
- assertTrue(localDexDirMonitor.mReadPaths.contains(DEX_ASSET_NAME)); |
- assertTrue(localDexDirMonitor.mModifiedPaths.contains(DEX_ASSET_NAME)); |
- } |
- } |
- |
- /** |
- * Connects to the DexOptimizerService. |
- */ |
- private void connectToDexOptimizerService() { |
- Intent intent = new Intent(); |
- intent.setComponent( |
- new ComponentName(DEX_OPTIMIZER_SERVICE_PACKAGE, DEX_OPTIMIZER_SERVICE_CLASS_NAME)); |
- final CallbackHelper connectedCallback = new CallbackHelper(); |
- |
- mServiceConnection = new ServiceConnection() { |
- @Override |
- public void onServiceConnected(ComponentName name, IBinder service) { |
- mDexOptimizerService = IDexOptimizerService.Stub.asInterface(service); |
- connectedCallback.notifyCalled(); |
- } |
- |
- @Override |
- public void onServiceDisconnected(ComponentName name) {} |
- }; |
- |
- try { |
- mContext.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); |
- } catch (SecurityException e) { |
- e.printStackTrace(); |
- fail(); |
- } |
- |
- try { |
- connectedCallback.waitForCallback(0); |
- } catch (Exception e) { |
- e.printStackTrace(); |
- fail("Could not connect to remote."); |
- } |
- } |
- |
- /** Returns whether the Android OS thinks that a dex file needs to be re-optimized */ |
- private boolean isDexOptNeeded(File dexFile) { |
- try { |
- return DexFile.isDexOptNeeded(dexFile.getPath()); |
- } catch (Exception e) { |
- e.printStackTrace(); |
- fail(); |
- return false; |
- } |
- } |
- |
- /** Returns whether the ClassLoader can load {@link CANARY_CLASS_NAME} */ |
- private boolean canLoadCanaryClass(ClassLoader loader) { |
- try { |
- loader.loadClass(CANARY_CLASS_NAME); |
- return true; |
- } catch (Exception e) { |
- return false; |
- } |
- } |
-} |