Commit 428de580 authored by Nate Fischer's avatar Nate Fischer Committed by Commit Bot

AW: do not allow proguard to optimize ApiHelper classes

We recently introduced a series of ApiHelperFor* classes to help us
ensure the WebView APK's classes pass compile-time verification in order
to avoid runtime verification (which causes logspam and startup
penalties). However, proguard was inlining these classes in our release
builds, which re-introduced the class verification issues.

This adds an annotation to prevent inlining. The @DoNotInline
annotation is used to configure Proguard.

R=torne@chromium.org

      (tested on L,M,NMR1 with standalone webview and monochrome)
      android-webview-google -v --pageset-repeat=1
      (no startup penalty on L device)
      "StatusRetryVerificationAtRuntime" (ensure the fixed classes no
      longer show up)

Bug: 791099
Bug: 838702
Test: adb logcat | grep 'Failed resolution of'
Test: tools/perf/run_benchmark system_health.webview_startup --browser \
Test: use oatdump after installing APK. Then, grep for
Change-Id: I7e85718916313f03287e5f2d5fe8f51a02661f11
Reviewed-on: https://chromium-review.googlesource.com/1109464Reviewed-by: default avatarRichard Coles <torne@chromium.org>
Reviewed-by: default avatarBo <boliu@chromium.org>
Reviewed-by: default avataragrieve <agrieve@chromium.org>
Commit-Queue: Nate Fischer <ntfschr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#569848}
parent 682d8524
...@@ -14,6 +14,7 @@ import android.webkit.WebViewClient; ...@@ -14,6 +14,7 @@ import android.webkit.WebViewClient;
import org.chromium.android_webview.AwContentsClient; import org.chromium.android_webview.AwContentsClient;
import org.chromium.android_webview.AwWebResourceResponse; import org.chromium.android_webview.AwWebResourceResponse;
import org.chromium.base.annotations.DoNotInline;
/** /**
* Utility class to use new APIs that were added in M (API level 23). These need to exist in a * Utility class to use new APIs that were added in M (API level 23). These need to exist in a
...@@ -21,6 +22,7 @@ import org.chromium.android_webview.AwWebResourceResponse; ...@@ -21,6 +22,7 @@ import org.chromium.android_webview.AwWebResourceResponse;
* encountering the new APIs. * encountering the new APIs.
*/ */
@DoNotInline
@TargetApi(Build.VERSION_CODES.M) @TargetApi(Build.VERSION_CODES.M)
public final class ApiHelperForM { public final class ApiHelperForM {
private ApiHelperForM() {} private ApiHelperForM() {}
......
...@@ -13,12 +13,14 @@ import android.webkit.WebView; ...@@ -13,12 +13,14 @@ import android.webkit.WebView;
import android.webkit.WebViewClient; import android.webkit.WebViewClient;
import org.chromium.android_webview.AwContentsClient; import org.chromium.android_webview.AwContentsClient;
import org.chromium.base.annotations.DoNotInline;
/** /**
* Utility class to use new APIs that were added in N (API level 24). These need to exist in a * Utility class to use new APIs that were added in N (API level 24). These need to exist in a
* separate class so that Android framework can successfully verify WebView classes without * separate class so that Android framework can successfully verify WebView classes without
* encountering the new APIs. * encountering the new APIs.
*/ */
@DoNotInline
@TargetApi(Build.VERSION_CODES.N) @TargetApi(Build.VERSION_CODES.N)
public final class ApiHelperForN { public final class ApiHelperForN {
private ApiHelperForN() {} private ApiHelperForN() {}
......
...@@ -11,12 +11,14 @@ import android.webkit.WebView; ...@@ -11,12 +11,14 @@ import android.webkit.WebView;
import android.webkit.WebViewClient; import android.webkit.WebViewClient;
import org.chromium.android_webview.AwRenderProcessGoneDetail; import org.chromium.android_webview.AwRenderProcessGoneDetail;
import org.chromium.base.annotations.DoNotInline;
/** /**
* Utility class to use new APIs that were added in O (API level 26). These need to exist in a * Utility class to use new APIs that were added in O (API level 26). These need to exist in a
* separate class so that Android framework can successfully verify WebView classes without * separate class so that Android framework can successfully verify WebView classes without
* encountering the new APIs. * encountering the new APIs.
*/ */
@DoNotInline
@TargetApi(Build.VERSION_CODES.O) @TargetApi(Build.VERSION_CODES.O)
public final class ApiHelperForO { public final class ApiHelperForO {
private ApiHelperForO() {} private ApiHelperForO() {}
...@@ -39,4 +41,4 @@ public final class ApiHelperForO { ...@@ -39,4 +41,4 @@ public final class ApiHelperForO {
} }
}); });
} }
} }
\ No newline at end of file
...@@ -12,12 +12,14 @@ import android.webkit.WebViewClient; ...@@ -12,12 +12,14 @@ import android.webkit.WebViewClient;
import org.chromium.android_webview.AwContentsClient; import org.chromium.android_webview.AwContentsClient;
import org.chromium.android_webview.AwSafeBrowsingResponse; import org.chromium.android_webview.AwSafeBrowsingResponse;
import org.chromium.base.Callback; import org.chromium.base.Callback;
import org.chromium.base.annotations.DoNotInline;
/** /**
* Utility class to use new APIs that were added in OMR1 (API level 27). These need to exist in a * Utility class to use new APIs that were added in OMR1 (API level 27). These need to exist in a
* separate class so that Android framework can successfully verify WebView classes without * separate class so that Android framework can successfully verify WebView classes without
* encountering the new APIs. * encountering the new APIs.
*/ */
@DoNotInline
@TargetApi(Build.VERSION_CODES.O_MR1) @TargetApi(Build.VERSION_CODES.O_MR1)
public final class ApiHelperForOMR1 { public final class ApiHelperForOMR1 {
private ApiHelperForOMR1() {} private ApiHelperForOMR1() {}
......
...@@ -2848,6 +2848,7 @@ if (is_android) { ...@@ -2848,6 +2848,7 @@ if (is_android) {
"android/java/src/org/chromium/base/annotations/AccessedByNative.java", "android/java/src/org/chromium/base/annotations/AccessedByNative.java",
"android/java/src/org/chromium/base/annotations/CalledByNative.java", "android/java/src/org/chromium/base/annotations/CalledByNative.java",
"android/java/src/org/chromium/base/annotations/CalledByNativeUnchecked.java", "android/java/src/org/chromium/base/annotations/CalledByNativeUnchecked.java",
"android/java/src/org/chromium/base/annotations/DoNotInline.java",
"android/java/src/org/chromium/base/annotations/JNIAdditionalImport.java", "android/java/src/org/chromium/base/annotations/JNIAdditionalImport.java",
"android/java/src/org/chromium/base/annotations/JNINamespace.java", "android/java/src/org/chromium/base/annotations/JNINamespace.java",
"android/java/src/org/chromium/base/annotations/MainDex.java", "android/java/src/org/chromium/base/annotations/MainDex.java",
......
// Copyright 2018 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;
/**
* The annotated method or class should never be inlined.
*
* The annotated method (or methods on the annotated class) are guaranteed not to be inlined by
* Proguard. Other optimizations may still apply.
*/
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface DoNotInline {}
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
-keep @interface org.chromium.base.annotations.AccessedByNative -keep @interface org.chromium.base.annotations.AccessedByNative
-keep @interface org.chromium.base.annotations.CalledByNative -keep @interface org.chromium.base.annotations.CalledByNative
-keep @interface org.chromium.base.annotations.CalledByNativeUnchecked -keep @interface org.chromium.base.annotations.CalledByNativeUnchecked
-keep @interface org.chromium.base.annotations.DoNotInline
-keep @interface org.chromium.base.annotations.RemovableInRelease -keep @interface org.chromium.base.annotations.RemovableInRelease
-keep @interface org.chromium.base.annotations.UsedByReflection -keep @interface org.chromium.base.annotations.UsedByReflection
...@@ -46,6 +47,15 @@ ...@@ -46,6 +47,15 @@
@org.chromium.base.annotations.RemovableInRelease <methods>; @org.chromium.base.annotations.RemovableInRelease <methods>;
} }
# Never inline classes or methods with this annotation, but allow shrinking and
# obfuscation.
-keepnames,allowobfuscation @org.chromium.base.annotations.DoNotInline class * {
*;
}
-keepclassmembernames,allowobfuscation class * {
@org.chromium.base.annotations.DoNotInline <methods>;
}
# Keep all CREATOR fields within Parcelable that are kept. # Keep all CREATOR fields within Parcelable that are kept.
-keepclassmembers class org.chromium.** implements android.os.Parcelable { -keepclassmembers class org.chromium.** implements android.os.Parcelable {
public static *** CREATOR; public static *** CREATOR;
......
...@@ -9,6 +9,7 @@ import android.os.Build; ...@@ -9,6 +9,7 @@ import android.os.Build;
import android.view.ActionMode; import android.view.ActionMode;
import android.view.View; import android.view.View;
import org.chromium.base.annotations.DoNotInline;
import org.chromium.content.browser.selection.FloatingActionModeCallback; import org.chromium.content.browser.selection.FloatingActionModeCallback;
import org.chromium.content.browser.selection.SelectionPopupControllerImpl; import org.chromium.content.browser.selection.SelectionPopupControllerImpl;
...@@ -18,6 +19,7 @@ import org.chromium.content.browser.selection.SelectionPopupControllerImpl; ...@@ -18,6 +19,7 @@ import org.chromium.content.browser.selection.SelectionPopupControllerImpl;
* encountering the new APIs. * encountering the new APIs.
*/ */
@DoNotInline
@TargetApi(Build.VERSION_CODES.M) @TargetApi(Build.VERSION_CODES.M)
public final class ApiHelperForM { public final class ApiHelperForM {
private ApiHelperForM() {} private ApiHelperForM() {}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment