diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 4359495861998..2c2443fb7cb0a 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -14358,6 +14358,7 @@ package android.webkit { method public String getDataDirectorySuffix(); method public String getErrorString(android.content.Context, int); method public int getPackageId(android.content.res.Resources, String); + method @NonNull public long[] getTimestamps(); method @Deprecated public void invokeDrawGlFunctor(android.view.View, long, boolean); method public boolean isMultiProcessEnabled(); method public boolean isTraceTagEnabled(); @@ -14373,6 +14374,12 @@ package android.webkit { method public static android.content.pm.PackageInfo getLoadedPackageInfo(); method public static int loadWebViewNativeLibraryFromPackage(String, ClassLoader); method public static void prepareWebViewInZygote(); + field public static final int ADD_ASSETS_END = 4; // 0x4 + field public static final int ADD_ASSETS_START = 3; // 0x3 + field public static final int CREATE_CONTEXT_END = 2; // 0x2 + field public static final int CREATE_CONTEXT_START = 1; // 0x1 + field public static final int GET_CLASS_LOADER_END = 6; // 0x6 + field public static final int GET_CLASS_LOADER_START = 5; // 0x5 field public static final int LIBLOAD_ADDRESS_SPACE_NOT_RESERVED = 2; // 0x2 field public static final int LIBLOAD_FAILED_JNI_CALL = 7; // 0x7 field public static final int LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES = 4; // 0x4 @@ -14383,6 +14390,11 @@ package android.webkit { field public static final int LIBLOAD_FAILED_WAITING_FOR_WEBVIEW_REASON_UNKNOWN = 8; // 0x8 field public static final int LIBLOAD_SUCCESS = 0; // 0x0 field public static final int LIBLOAD_WRONG_PACKAGE_NAME = 1; // 0x1 + field public static final int NATIVE_LOAD_END = 8; // 0x8 + field public static final int NATIVE_LOAD_START = 7; // 0x7 + field public static final int PROVIDER_CLASS_FOR_NAME_END = 10; // 0xa + field public static final int PROVIDER_CLASS_FOR_NAME_START = 9; // 0x9 + field public static final int WEBVIEW_LOAD_START = 0; // 0x0 } public interface WebViewFactoryProvider { diff --git a/core/java/android/webkit/WebViewDelegate.java b/core/java/android/webkit/WebViewDelegate.java index 950dc7300ba9e..c7eac6c72936b 100644 --- a/core/java/android/webkit/WebViewDelegate.java +++ b/core/java/android/webkit/WebViewDelegate.java @@ -218,4 +218,15 @@ public final class WebViewDelegate { public String getDataDirectorySuffix() { return WebViewFactory.getDataDirectorySuffix(); } + + /** + * Returns an array of startup timestamps. For the specification of array + * see {@link WebViewFactory.Timestamp}. + * This method must be called on the same thread where the + * WebViewChromiumFactoryProvider#create method was invoked. + */ + @NonNull + public long[] getTimestamps() { + return WebViewFactory.getTimestamps(); + } } diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java index b91e7d39f51ca..2e75834f4ec58 100644 --- a/core/java/android/webkit/WebViewFactory.java +++ b/core/java/android/webkit/WebViewFactory.java @@ -16,6 +16,8 @@ package android.webkit; +import android.annotation.IntDef; +import android.annotation.NonNull; import android.annotation.SystemApi; import android.app.ActivityManager; import android.app.AppGlobals; @@ -35,6 +37,8 @@ import android.util.ArraySet; import android.util.Log; import java.io.File; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.reflect.Method; /** @@ -67,6 +71,33 @@ public final class WebViewFactory { private static boolean sWebViewDisabled; private static String sDataDirectorySuffix; // stored here so it can be set without loading WV + // Indices in sTimestamps array. + /** @hide */ + @IntDef(value = { + WEBVIEW_LOAD_START, CREATE_CONTEXT_START, CREATE_CONTEXT_END, + ADD_ASSETS_START, ADD_ASSETS_END, GET_CLASS_LOADER_START, GET_CLASS_LOADER_END, + NATIVE_LOAD_START, NATIVE_LOAD_END, + PROVIDER_CLASS_FOR_NAME_START, PROVIDER_CLASS_FOR_NAME_END}) + @Retention(RetentionPolicy.SOURCE) + public @interface Timestamp { + } + + public static final int WEBVIEW_LOAD_START = 0; + public static final int CREATE_CONTEXT_START = 1; + public static final int CREATE_CONTEXT_END = 2; + public static final int ADD_ASSETS_START = 3; + public static final int ADD_ASSETS_END = 4; + public static final int GET_CLASS_LOADER_START = 5; + public static final int GET_CLASS_LOADER_END = 6; + public static final int NATIVE_LOAD_START = 7; + public static final int NATIVE_LOAD_END = 8; + public static final int PROVIDER_CLASS_FOR_NAME_START = 9; + public static final int PROVIDER_CLASS_FOR_NAME_END = 10; + private static final int TIMESTAMPS_SIZE = 11; + + // WebView startup timestamps. To access elements use {@link Timestamp}. + private static long[] sTimestamps = new long[TIMESTAMPS_SIZE]; + // Error codes for loadWebViewNativeLibraryFromPackage public static final int LIBLOAD_SUCCESS = 0; public static final int LIBLOAD_WRONG_PACKAGE_NAME = 1; @@ -230,6 +261,7 @@ public final class WebViewFactory { // us honest and minimize usage of WebView internals when binding the proxy. if (sProviderInstance != null) return sProviderInstance; + sTimestamps[WEBVIEW_LOAD_START] = System.currentTimeMillis(); final int uid = android.os.Process.myUid(); if (uid == android.os.Process.ROOT_UID || uid == android.os.Process.SYSTEM_UID || uid == android.os.Process.PHONE_UID || uid == android.os.Process.NFC_UID @@ -369,6 +401,7 @@ public final class WebViewFactory { Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "initialApplication.createApplicationContext"); + sTimestamps[CREATE_CONTEXT_START] = System.currentTimeMillis(); try { // Construct an app context to load the Java code into the current app. Context webViewContext = initialApplication.createApplicationContext( @@ -377,6 +410,7 @@ public final class WebViewFactory { sPackageInfo = newPackageInfo; return webViewContext; } finally { + sTimestamps[CREATE_CONTEXT_END] = System.currentTimeMillis(); Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); } } catch (RemoteException | PackageManager.NameNotFoundException e) { @@ -402,20 +436,26 @@ public final class WebViewFactory { Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.getChromiumProviderClass()"); try { + sTimestamps[ADD_ASSETS_START] = System.currentTimeMillis(); for (String newAssetPath : webViewContext.getApplicationInfo().getAllApkPaths()) { initialApplication.getAssets().addAssetPathAsSharedLibrary(newAssetPath); } + sTimestamps[ADD_ASSETS_END] = sTimestamps[GET_CLASS_LOADER_START] = + System.currentTimeMillis(); ClassLoader clazzLoader = webViewContext.getClassLoader(); - Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.loadNativeLibrary()"); + sTimestamps[GET_CLASS_LOADER_END] = sTimestamps[NATIVE_LOAD_START] = + System.currentTimeMillis(); WebViewLibraryLoader.loadNativeLibrary(clazzLoader, getWebViewLibrary(sPackageInfo.applicationInfo)); Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); - Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "Class.forName()"); + sTimestamps[NATIVE_LOAD_END] = sTimestamps[PROVIDER_CLASS_FOR_NAME_START] = + System.currentTimeMillis(); try { return getWebViewProviderClass(clazzLoader); } finally { + sTimestamps[PROVIDER_CLASS_FOR_NAME_END] = System.currentTimeMillis(); Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); } } catch (ClassNotFoundException e) { @@ -477,4 +517,9 @@ public final class WebViewFactory { return IWebViewUpdateService.Stub.asInterface( ServiceManager.getService(WEBVIEW_UPDATE_SERVICE_NAME)); } + + @NonNull + static long[] getTimestamps() { + return sTimestamps; + } }