diff options
author | jbudorick <jbudorick@chromium.org> | 2016-01-15 17:21:51 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-01-16 01:23:53 +0000 |
commit | 070dd8c416495cb051617b05681353e096c463b7 (patch) | |
tree | ba18422b1d9700af664abf1459ae2d450c92a9ce /base/android | |
parent | 5f578079ddfe10de97b27d179d0c2b1718d119c3 (diff) | |
download | chromium_src-070dd8c416495cb051617b05681353e096c463b7.zip chromium_src-070dd8c416495cb051617b05681353e096c463b7.tar.gz chromium_src-070dd8c416495cb051617b05681353e096c463b7.tar.bz2 |
[Android] Rework multidex and enable multidex for unit_tests_apk. (RELAND 2)
this is a reland of https://codereview.chromium.org/1590243003/
BUG=272790
TBR=thakis@chromium.org,yfriedman@chromium.org,phajdan.jr@chromium.org
Review URL: https://codereview.chromium.org/1594653002
Cr-Commit-Position: refs/heads/master@{#369906}
Diffstat (limited to 'base/android')
3 files changed, 126 insertions, 105 deletions
diff --git a/base/android/java/src/org/chromium/base/BaseChromiumApplication.java b/base/android/java/src/org/chromium/base/BaseChromiumApplication.java index e4e6e20..f842a18 100644 --- a/base/android/java/src/org/chromium/base/BaseChromiumApplication.java +++ b/base/android/java/src/org/chromium/base/BaseChromiumApplication.java @@ -10,7 +10,7 @@ import android.content.Context; import android.os.Bundle; import android.view.Window; -import org.chromium.base.multidex.ChromiumMultiDex; +import org.chromium.base.multidex.ChromiumMultiDexInstaller; /** * Basic application functionality that should be shared among all browser applications. @@ -31,7 +31,7 @@ public class BaseChromiumApplication extends Application { @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); - ChromiumMultiDex.install(this); + ChromiumMultiDexInstaller.install(this); } /** diff --git a/base/android/java/src/org/chromium/base/multidex/ChromiumMultiDexInstaller.java b/base/android/java/src/org/chromium/base/multidex/ChromiumMultiDexInstaller.java new file mode 100644 index 0000000..e4b30b9 --- /dev/null +++ b/base/android/java/src/org/chromium/base/multidex/ChromiumMultiDexInstaller.java @@ -0,0 +1,114 @@ +// Copyright 2015 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.multidex; + +import android.app.ActivityManager; +import android.app.ActivityManager.RunningAppProcessInfo; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.os.Build; +import android.support.multidex.MultiDex; + +import org.chromium.base.Log; +import org.chromium.base.VisibleForTesting; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Performs multidex installation for non-isolated processes. + */ +public class ChromiumMultiDexInstaller { + + private static final String TAG = "base_multidex"; + + /** + * Suffix for the meta-data tag in the AndroidManifext.xml that determines whether loading + * secondary dexes should be skipped for a given process name. + */ + private static final String IGNORE_MULTIDEX_KEY = ".ignore_multidex"; + + /** + * Installs secondary dexes if possible/necessary. + * + * Isolated processes (e.g. renderer processes) can't load secondary dex files on + * K and below, so we don't even try in that case. + * + * In release builds of app apks (as opposed to test apks), this is a no-op because: + * - multidex isn't necessary in release builds because we run proguard there and + * thus aren't threatening to hit the dex limit; and + * - calling MultiDex.install, even in the absence of secondary dexes, causes a + * significant regression in start-up time (crbug.com/525695). + * + * @param context The application context. + */ + @VisibleForTesting + public static void install(Context context) { + if (!ChromiumMultiDex.isMultidexEnabled()) return; + + // TODO(jbudorick): Back out this version check once support for K & below works. + // http://crbug.com/512357 + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP + && !shouldInstallMultiDex(context)) { + Log.i(TAG, "Skipping multidex installation: not needed for process."); + } else { + MultiDex.install(context); + Log.i(TAG, "Completed multidex installation."); + } + } + + private static String getProcessName(Context context) { + try { + String currentProcessName = null; + int pid = android.os.Process.myPid(); + + ActivityManager manager = + (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + for (RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) { + if (processInfo.pid == pid) { + currentProcessName = processInfo.processName; + break; + } + } + + return currentProcessName; + } catch (SecurityException ex) { + return null; + } + } + + // Determines whether MultiDex should be installed for the current process. Isolated + // Processes should skip MultiDex as they can not actually access the files on disk. + // Privileged processes need ot have all of their dependencies in the MainDex for + // performance reasons. + private static boolean shouldInstallMultiDex(Context context) { + try { + Method isIsolatedMethod = + android.os.Process.class.getMethod("isIsolated"); + Object retVal = isIsolatedMethod.invoke(null); + if (retVal != null && retVal instanceof Boolean && ((Boolean) retVal)) { + return false; + } + } catch (IllegalAccessException | IllegalArgumentException + | InvocationTargetException | NoSuchMethodException e) { + // Ignore and fall back to checking the app processes. + } + + String currentProcessName = getProcessName(context); + if (currentProcessName == null) return true; + + PackageManager packageManager = context.getPackageManager(); + try { + ApplicationInfo appInfo = packageManager.getApplicationInfo(context.getPackageName(), + PackageManager.GET_META_DATA); + if (appInfo == null || appInfo.metaData == null) return true; + return !appInfo.metaData.getBoolean(currentProcessName + IGNORE_MULTIDEX_KEY, false); + } catch (PackageManager.NameNotFoundException e) { + return true; + } + } + +} diff --git a/base/android/java/templates/ChromiumMultiDex.template b/base/android/java/templates/ChromiumMultiDex.template index 5580489..7e70701 100644 --- a/base/android/java/templates/ChromiumMultiDex.template +++ b/base/android/java/templates/ChromiumMultiDex.template @@ -4,115 +4,22 @@ package org.chromium.base.multidex; -import android.app.ActivityManager; -import android.app.ActivityManager.RunningAppProcessInfo; -import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.os.Build; -import android.os.Process; -import android.support.multidex.MultiDex; - -import org.chromium.base.Log; -import org.chromium.base.VisibleForTesting; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - /** - * Performs multidex installation for non-isolated processes. + * Multidex configuration. Generated on a per-target basis. */ -public class ChromiumMultiDex { +class ChromiumMultiDex { - private static final String TAG = "base_multidex"; - - /** - * Suffix for the meta-data tag in the AndroidManifext.xml that determines whether loading - * secondary dexes should be skipped for a given process name. - */ - private static final String IGNORE_MULTIDEX_KEY = ".ignore_multidex"; - - /** - * Installs secondary dexes if possible/necessary. - * - * Isolated processes (e.g. renderer processes) can't load secondary dex files on - * K and below, so we don't even try in that case. + /** Whether multidex is enabled for this target. * - * In release builds, this is a no-op because: - * - multidex isn't necessary in release builds because we run proguard there and - * thus aren't threatening to hit the dex limit; and - * - calling MultiDex.install, even in the absence of secondary dexes, causes a - * significant regression in start-up time (crbug.com/525695). - * - * @param context The application context. + * This has to be a function instead of a static final boolean s.t. the initial false value + * doesn't get optimized into {@link ChromiumMultiDexInstaller} at base_java compile time. */ - @VisibleForTesting -#if defined(MULTIDEX_CONFIGURATION_Debug) - public static void install(Context context) { - // TODO(jbudorick): Back out this version check once support for K & below works. - // http://crbug.com/512357 - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP - && !shouldInstallMultiDex(context)) { - Log.i(TAG, "Skipping multidex installation: not needed for process."); - } else { - MultiDex.install(context); - Log.i(TAG, "Completed multidex installation."); - } - } - - private static String getProcessName(Context context) { - try { - String currentProcessName = null; - int pid = android.os.Process.myPid(); - - ActivityManager manager = - (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); - for (RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) { - if (processInfo.pid == pid) { - currentProcessName = processInfo.processName; - break; - } - } - - return currentProcessName; - } catch (SecurityException ex) { - return null; - } - } - - // Determines whether MultiDex should be installed for the current process. Isolated - // Processes should skip MultiDex as they can not actually access the files on disk. - // Privileged processes need ot have all of their dependencies in the MainDex for - // performance reasons. - private static boolean shouldInstallMultiDex(Context context) { - try { - Method isIsolatedMethod = - android.os.Process.class.getMethod("isIsolated"); - Object retVal = isIsolatedMethod.invoke(null); - if (retVal != null && retVal instanceof Boolean && ((Boolean) retVal)) { - return false; - } - } catch (IllegalAccessException | IllegalArgumentException - | InvocationTargetException | NoSuchMethodException e) { - // Ignore and fall back to checking the app processes. - } - - String currentProcessName = getProcessName(context); - if (currentProcessName == null) return true; - - PackageManager packageManager = context.getPackageManager(); - try { - ApplicationInfo appInfo = packageManager.getApplicationInfo(context.getPackageName(), - PackageManager.GET_META_DATA); - if (appInfo == null || appInfo.metaData == null) return true; - return !appInfo.metaData.getBoolean(currentProcessName + IGNORE_MULTIDEX_KEY, false); - } catch (PackageManager.NameNotFoundException e) { - return true; - } - } + static boolean isMultidexEnabled() { +#if defined(ENABLE_MULTIDEX) + return true; #else - public static void install(Context context) { - } + return false; #endif + } } |