Skip to content

Commit

Permalink
[Android] Add gyp support for multidex.
Browse files Browse the repository at this point in the history
Note that this does not enable multidex builds yet.

BUG=272790

Review URL: https://codereview.chromium.org/1278573002

Cr-Commit-Position: refs/heads/master@{#345357}
  • Loading branch information
jbudorick authored and Commit bot committed Aug 25, 2015
1 parent d9be58b commit e40294e
Show file tree
Hide file tree
Showing 25 changed files with 457 additions and 16 deletions.
20 changes: 19 additions & 1 deletion base/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -1591,6 +1591,7 @@ if (is_android) {
]

deps = [
"//third_party/android_tools:android_support_multidex_java",
"//third_party/jsr-305:jsr_305_javalib",
]

Expand Down Expand Up @@ -1622,12 +1623,29 @@ if (is_android) {
DEPRECATED_java_in_dir = "test/android/javatests/src"
}

# TODO(jbudorick): Remove this once we roll to robolectric 3.0 and pull
# in the multidex shadow library. crbug.com/522043
# GYP: //base.gyp:base_junit_test_support
java_library("base_junit_test_support") {
testonly = true
java_files = [ "test/android/junit/src/org/chromium/base/test/shadows/ShadowMultiDex.java" ]
deps = [
"//third_party/android_tools:android_support_multidex_java",
"//third_party/robolectric:android-all-4.3_r2-robolectric-0",
"//third_party/robolectric:robolectric_java",
]
}

# GYP: //base.gyp:base_junit_tests
junit_binary("base_junit_tests") {
java_files = [ "android/junit/src/org/chromium/base/LogTest.java" ]
java_files = [
"android/junit/src/org/chromium/base/BaseChromiumApplicationTest.java",
"android/junit/src/org/chromium/base/LogTest.java",
]
deps = [
":base_java",
":base_java_test_support",
":base_junit_test_support",
]
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import android.view.KeyEvent;
import android.view.Window;

import org.chromium.base.multidex.ChromiumMultiDex;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
Expand All @@ -20,6 +22,15 @@
* Basic application functionality that should be shared among all browser applications.
*/
public class BaseChromiumApplication extends Application {

private static final String TAG = "cr.base";

@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
ChromiumMultiDex.install(this);
}

/**
* Interface to be implemented by listeners for window focus events.
*/
Expand Down
21 changes: 21 additions & 0 deletions base/android/java/src/org/chromium/base/annotations/MainDex.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// 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.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* An annotation that signals that a class should be kept in the main dex file.
*
* This generally means it's used by renderer processes, which can't load secondary dexes
* on K and below.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface MainDex {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// 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.content.Context;
import android.os.Build;
import android.os.Process;
import android.support.multidex.MultiDex;

import org.chromium.base.Log;

import java.lang.reflect.InvocationTargetException;

/**
* Performs multidex installation for non-isolated processes.
*/
public class ChromiumMultiDex {

private static final String TAG = "cr.base.multidex";

/**
* Installs secondary dexes if possible.
*
* 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.
*
* @param context The application context.
*/
public static void install(Context context) {
try {
// 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 && processIsIsolated()) {
Log.i(TAG, "Skipping multidex installation: inside isolated process.");
} else {
MultiDex.install(context);
Log.i(TAG, "Completed multidex installation.");
}
} catch (NoSuchMethodException e) {
Log.wtf(TAG, "Failed multidex installation", e);
} catch (IllegalAccessException e) {
Log.wtf(TAG, "Failed multidex installation", e);
} catch (InvocationTargetException e) {
Log.wtf(TAG, "Failed multidex installation", e);
}
}

// Calls Process.isIsolated, a private Android API.
private static boolean processIsIsolated()
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
return (boolean) Process.class.getMethod("isIsolated").invoke(null);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import junit.framework.Assert;

import org.chromium.base.BaseChromiumApplication.WindowFocusChangedListener;
import org.chromium.base.test.shadows.ShadowMultiDex;
import org.chromium.testing.local.LocalRobolectricTestRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand All @@ -25,10 +26,12 @@

/** Unit tests for {@link BaseChromiumApplication}. */
@RunWith(LocalRobolectricTestRunner.class)
@Config(manifest = Config.NONE, application = BaseChromiumApplication.class,
shadows = {BaseChromiumApplicationTest.TrackingShadowActivity.class})
@Config(manifest = Config.NONE,
application = BaseChromiumApplication.class,
shadows = {BaseChromiumApplicationTest.TrackingShadowActivity.class, ShadowMultiDex.class})
public class BaseChromiumApplicationTest {

/** Shadow that tracks calls to onWindowFocusChanged and dispatchKeyEvent. */
@Implements(Activity.class)
public static class TrackingShadowActivity extends ShadowActivity {
private int mWindowFocusCalls;
Expand Down
19 changes: 19 additions & 0 deletions base/base.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -1450,6 +1450,7 @@
'base_java_library_process_type',
'base_java_memory_pressure_level',
'base_native_libraries_gen',
'../third_party/android_tools/android_tools.gyp:android_support_multidex_javalib',
'../third_party/jsr-305/jsr-305.gyp:jsr_305_javalib',
],
'includes': [ '../build/java.gypi' ],
Expand Down Expand Up @@ -1506,13 +1507,31 @@
},
'includes': [ '../build/java.gypi' ],
},
{
# TODO(jbudorick): Remove this once we roll to robolectric 3.0 and pull
# in the multidex shadow library. crbug.com/522043
# GN: //base:base_junit_test_support
'target_name': 'base_junit_test_support',
'type': 'none',
'dependencies': [
'../testing/android/junit/junit_test.gyp:junit_test_support',
'../third_party/android_tools/android_tools.gyp:android_support_multidex_javalib',
],
'variables': {
'src_paths': [
'../base/test/android/junit/',
],
},
'includes': [ '../build/host_jar.gypi' ]
},
{
# GN: //base:base_junit_tests
'target_name': 'base_junit_tests',
'type': 'none',
'dependencies': [
'base_java',
'base_java_test_support',
'base_junit_test_support',
'../testing/android/junit/junit_test.gyp:junit_test_support',
],
'variables': {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.os.Bundle;
import android.test.AndroidTestRunner;
import android.test.InstrumentationTestRunner;
import android.text.TextUtils;
Expand All @@ -17,6 +18,7 @@

import org.chromium.base.Log;
import org.chromium.base.SysUtils;
import org.chromium.base.multidex.ChromiumMultiDex;
import org.chromium.base.test.BaseTestResult.SkipCheck;
import org.chromium.base.test.util.MinAndroidSdkLevel;
import org.chromium.base.test.util.Restriction;
Expand All @@ -31,6 +33,12 @@
public class BaseInstrumentationTestRunner extends InstrumentationTestRunner {
private static final String TAG = "cr.base.test";

@Override
public void onCreate(Bundle arguments) {
ChromiumMultiDex.install(getTargetContext());
super.onCreate(arguments);
}

@Override
protected AndroidTestRunner getAndroidTestRunner() {
AndroidTestRunner runner = new AndroidTestRunner() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// 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.test.shadows;

import android.content.Context;
import android.support.multidex.MultiDex;

import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;

/** Do-nothing shadow for {@link android.support.multidex.MultiDex}. */
@Implements(MultiDex.class)
public class ShadowMultiDex {

@Implementation
public static void install(Context context) {
}

}
33 changes: 31 additions & 2 deletions build/android/ant/apk-package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@
<property name="resource.package.file.name" value="${RESOURCE_PACKAGED_APK_NAME}" />

<property name="intermediate.dex.file" location="${DEX_FILE_PATH}" />
<condition property="multidex.enabled" value="true">
<equals arg1="${MULTIDEX_ENABLED}" arg2="1"/>
</condition>

<!-- Macro that enables passing a variable list of external jar files
to ApkBuilder. -->
Expand All @@ -70,13 +73,32 @@
hascode="${HAS_CODE}"
previousBuildType="/"
buildType="${build.is.packaging.debug}/${build.is.signing.debug}">
<dex path="${intermediate.dex.file}"/>
<dex path="${intermediate.dex.file}" />
<nativefolder path="${native.libs.absolute.dir}" />
<extra-jars/>
</apkbuilder>
</sequential>
</macrodef>

<macrodef name="multidex-package-helper">
<element name="extra-jars" optional="yes" />
<sequential>
<apkbuilder
outfolder="${out.absolute.dir}"
resourcefile="${resource.package.file.name}"
apkfilepath="${out.packaged.file}"
debugpackaging="${build.is.packaging.debug}"
debugsigning="${build.is.signing.debug}"
verbose="${verbose}"
hascode="false"
previousBuildType="/"
buildType="${build.is.packaging.debug}/${build.is.signing.debug}">
<zip path="${intermediate.dex.file}" />
<nativefolder path="${native.libs.absolute.dir}" />
<extra-jars/>
</apkbuilder>
</sequential>
</macrodef>

<!-- Packages the application. -->
<target name="-package">
Expand All @@ -89,7 +111,14 @@
</package-helper>
</then>
<else>
<package-helper />
<if condition="${multidex.enabled}">
<then>
<multidex-package-helper />
</then>
<else>
<package-helper />
</else>
</if>
</else>
</if>
</target>
Expand Down
5 changes: 5 additions & 0 deletions build/android/apkbuilder_action.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@
'-DDEX_FILE_PATH=<(dex_path)',
]
}],
['enable_multidex == 1', {
'action': [
'-DMULTIDEX_ENABLED=1',
]
}]
],
'action': [
'python', '<(DEPTH)/build/android/gyp/ant.py',
Expand Down
Loading

0 comments on commit e40294e

Please sign in to comment.