Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2536)

Unified Diff: base/test/android/javatests/src/org/chromium/base/test/BaseChromiumRunnerCommon.java

Issue 2839983002: [Android] Enable multidex for release builds of chrome_public_test_apk. (RELAND) (Closed)
Patch Set: roll deps Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/test/android/javatests/src/org/chromium/base/test/BaseChromiumRunnerCommon.java
diff --git a/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumRunnerCommon.java b/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumRunnerCommon.java
new file mode 100644
index 0000000000000000000000000000000000000000..fcda91039be63d15930700cc63a94204b9dda9b0
--- /dev/null
+++ b/base/test/android/javatests/src/org/chromium/base/test/BaseChromiumRunnerCommon.java
@@ -0,0 +1,162 @@
+// Copyright 2017 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.base.test;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.SharedPreferences;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+
+import org.chromium.android.support.PackageManagerWrapper;
+import org.chromium.base.Log;
+import org.chromium.base.annotations.MainDex;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.Comparator;
+
+/**
+ * Functionality common to the JUnit3 and JUnit4 runners.
+ */
+@MainDex
+class BaseChromiumRunnerCommon {
+ private static final String TAG = "base_test";
+
+ /**
+ * A ContextWrapper that allows multidex test APKs to extract secondary dexes into
+ * the APK under test's data directory.
+ */
+ @MainDex
+ static class MultiDexContextWrapper extends ContextWrapper {
+ private Context mAppContext;
+
+ MultiDexContextWrapper(Context instrContext, Context appContext) {
+ super(instrContext);
+ mAppContext = appContext;
+ }
+
+ @Override
+ public File getFilesDir() {
+ return mAppContext.getFilesDir();
+ }
+
+ @Override
+ public SharedPreferences getSharedPreferences(String name, int mode) {
+ return mAppContext.getSharedPreferences(name, mode);
+ }
+
+ @Override
+ public PackageManager getPackageManager() {
+ return new PackageManagerWrapper(super.getPackageManager()) {
+ @Override
+ public ApplicationInfo getApplicationInfo(String packageName, int flags) {
+ try {
+ ApplicationInfo ai = super.getApplicationInfo(packageName, flags);
+ if (packageName.equals(getPackageName())) {
+ ApplicationInfo appAi =
+ super.getApplicationInfo(mAppContext.getPackageName(), flags);
+ File dataDir = new File(appAi.dataDir, "test-multidex");
+ if (!dataDir.exists() && !dataDir.mkdirs()) {
+ throw new IOException(String.format(
+ "Unable to create test multidex directory \"%s\"",
+ dataDir.getPath()));
+ }
+ ai.dataDir = dataDir.getPath();
+ }
+ return ai;
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to get application info for %s", packageName, e);
+ }
+ return null;
+ }
+ };
+ }
+ }
+
+ /**
+ * Ensure all test dex entries precede app dex entries.
+ *
+ * @param cl ClassLoader to modify. Assumed to be a derivative of
+ * {@link dalvik.system.BaseDexClassLoader}. If this isn't
+ * the case, reordering will fail.
+ */
+ static void reorderDexPathElements(ClassLoader cl, Context context, Context targetContext) {
+ try {
+ Log.i(TAG,
+ "Reordering dex files. If you're building a multidex test APK and see a "
+ + "class resolving to an unexpected implementation, this may be why.");
+ Field pathListField = findField(cl, "pathList");
+ Object dexPathList = pathListField.get(cl);
+ Field dexElementsField = findField(dexPathList, "dexElements");
+ Object[] dexElementsList = (Object[]) dexElementsField.get(dexPathList);
+ Arrays.sort(dexElementsList,
+ new DexListReorderingComparator(
+ context.getPackageName(), targetContext.getPackageName()));
+ dexElementsField.set(dexPathList, dexElementsList);
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to reorder dex elements for testing.", e);
+ }
+ }
+
+ /**
+ * Comparator for sorting dex list entries.
+ *
+ * Using this to sort a list of dex list entries will result in the following order:
+ * - Strings that contain neither the test package nor the app package in lexicographical
+ * order.
+ * - Strings that contain the test package in lexicographical order.
+ * - Strings that contain the app package but not the test package in lexicographical order.
+ */
+ private static class DexListReorderingComparator implements Comparator<Object>, Serializable {
+ private String mTestPackage;
+ private String mAppPackage;
+
+ public DexListReorderingComparator(String testPackage, String appPackage) {
+ mTestPackage = testPackage;
+ mAppPackage = appPackage;
+ }
+
+ @Override
+ public int compare(Object o1, Object o2) {
+ String s1 = o1.toString();
+ String s2 = o2.toString();
+ if (s1.contains(mTestPackage)) {
+ if (!s2.contains(mTestPackage)) {
+ if (s2.contains(mAppPackage)) {
+ return -1;
+ } else {
+ return 1;
+ }
+ }
+ } else if (s1.contains(mAppPackage)) {
+ if (s2.contains(mTestPackage)) {
+ return 1;
+ } else if (!s2.contains(mAppPackage)) {
+ return 1;
+ }
+ } else if (s2.contains(mTestPackage) || s2.contains(mAppPackage)) {
+ return -1;
+ }
+ return s1.compareTo(s2);
+ }
+ }
+
+ private static Field findField(Object instance, String name) throws NoSuchFieldException {
+ for (Class<?> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {
+ try {
+ Field f = clazz.getDeclaredField(name);
+ f.setAccessible(true);
+ return f;
+ } catch (NoSuchFieldException e) {
+ }
+ }
+ throw new NoSuchFieldException(
+ "Unable to find field " + name + " in " + instance.getClass());
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698