summaryrefslogtreecommitdiff
path: root/chromium/weblayer/browser/java
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-03-11 11:32:04 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-03-18 13:40:17 +0000
commit31ccca0778db85c159634478b4ec7997f6704860 (patch)
tree3d33fc3afd9d5ec95541e1bbe074a9cf8da12a0e /chromium/weblayer/browser/java
parent248b70b82a40964d5594eb04feca0fa36716185d (diff)
downloadqtwebengine-chromium-31ccca0778db85c159634478b4ec7997f6704860.tar.gz
BASELINE: Update Chromium to 80.0.3987.136
Change-Id: I98e1649aafae85ba3a83e67af00bb27ef301db7b Reviewed-by: Jüri Valdmann <juri.valdmann@qt.io>
Diffstat (limited to 'chromium/weblayer/browser/java')
-rw-r--r--chromium/weblayer/browser/java/BUILD.gn23
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserFragmentImpl.java10
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java17
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/ChildProcessServiceImpl.java4
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/CrashReporterControllerImpl.java6
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/LocaleChangedBroadcastReceiver.java41
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/NavigationControllerImpl.java11
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/NavigationImpl.java8
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/ProfileImpl.java4
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/RemoteFragmentImpl.java15
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java9
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/TopControlsContainerView.java1
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerFactoryImpl.java10
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java44
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/StrictModeWorkaround.java95
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/WebLayerVersion.java12
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/metrics/UmaUtils.java36
17 files changed, 314 insertions, 32 deletions
diff --git a/chromium/weblayer/browser/java/BUILD.gn b/chromium/weblayer/browser/java/BUILD.gn
index 6b5e736a49f..6539297a740 100644
--- a/chromium/weblayer/browser/java/BUILD.gn
+++ b/chromium/weblayer/browser/java/BUILD.gn
@@ -11,8 +11,8 @@ android_resources("weblayer_resources") {
custom_package = "org.chromium.weblayer_private"
}
-generate_locale_config_srcjar("weblayer_locale_config") {
- java_package = weblayer_locale_config_java_package
+generate_product_config_srcjar("weblayer_product_config") {
+ java_package = weblayer_product_config_java_package
}
java_cpp_enum("generated_enums") {
@@ -25,8 +25,9 @@ java_cpp_enum("generated_enums") {
android_library("java") {
java_files = [
- "org/chromium/weblayer_private/BrowserImpl.java",
+ "org/chromium/weblayer_private/ActionModeCallback.java",
"org/chromium/weblayer_private/BrowserFragmentImpl.java",
+ "org/chromium/weblayer_private/BrowserImpl.java",
"org/chromium/weblayer_private/BrowserViewController.java",
"org/chromium/weblayer_private/ChildProcessServiceImpl.java",
"org/chromium/weblayer_private/ContentView.java",
@@ -35,15 +36,15 @@ android_library("java") {
"org/chromium/weblayer_private/DownloadCallbackProxy.java",
"org/chromium/weblayer_private/ErrorPageCallbackProxy.java",
"org/chromium/weblayer_private/ExternalNavigationHandler.java",
- "org/chromium/weblayer_private/ActionModeCallback.java",
+ "org/chromium/weblayer_private/FragmentAndroidPermissionDelegate.java",
+ "org/chromium/weblayer_private/FragmentWindowAndroid.java",
"org/chromium/weblayer_private/FullscreenCallbackProxy.java",
+ "org/chromium/weblayer_private/LocaleChangedBroadcastReceiver.java",
"org/chromium/weblayer_private/MinidumpUploader.java",
"org/chromium/weblayer_private/NavigationControllerImpl.java",
"org/chromium/weblayer_private/NavigationImpl.java",
"org/chromium/weblayer_private/NewTabCallbackProxy.java",
"org/chromium/weblayer_private/ProfileImpl.java",
- "org/chromium/weblayer_private/FragmentAndroidPermissionDelegate.java",
- "org/chromium/weblayer_private/FragmentWindowAndroid.java",
"org/chromium/weblayer_private/ProfileManager.java",
"org/chromium/weblayer_private/RemoteFragmentImpl.java",
"org/chromium/weblayer_private/TabCallbackProxy.java",
@@ -52,6 +53,7 @@ android_library("java") {
"org/chromium/weblayer_private/WebContentsGestureStateTracker.java",
"org/chromium/weblayer_private/WebLayerFactoryImpl.java",
"org/chromium/weblayer_private/WebLayerImpl.java",
+ "org/chromium/weblayer_private/metrics/UmaUtils.java",
]
deps = [
@@ -65,6 +67,7 @@ android_library("java") {
"//components/embedder_support/android:application_java",
"//components/embedder_support/android:web_contents_delegate_java",
"//components/minidump_uploader:minidump_uploader_java",
+ "//components/spellcheck/browser/android:java",
"//components/version_info/android:version_constants_java",
"//content/public/android:content_java",
"//third_party/android_deps:com_android_support_support_compat_java",
@@ -72,9 +75,9 @@ android_library("java") {
]
srcjar_deps = [
":generated_enums",
- ":weblayer_locale_config",
+ ":weblayer_product_config",
]
- jar_excluded_patterns = [ "*/LocaleConfig.class" ]
+ jar_excluded_patterns = [ "*/ProductConfig.class" ]
annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
# Needed for android.webkit.WebView(Delegate|Factory)
@@ -89,6 +92,7 @@ generate_jni("jni") {
"org/chromium/weblayer_private/ErrorPageCallbackProxy.java",
"org/chromium/weblayer_private/ExternalNavigationHandler.java",
"org/chromium/weblayer_private/FullscreenCallbackProxy.java",
+ "org/chromium/weblayer_private/LocaleChangedBroadcastReceiver.java",
"org/chromium/weblayer_private/NavigationControllerImpl.java",
"org/chromium/weblayer_private/NavigationImpl.java",
"org/chromium/weblayer_private/NewTabCallbackProxy.java",
@@ -97,6 +101,7 @@ generate_jni("jni") {
"org/chromium/weblayer_private/TabImpl.java",
"org/chromium/weblayer_private/TopControlsContainerView.java",
"org/chromium/weblayer_private/WebLayerImpl.java",
+ "org/chromium/weblayer_private/metrics/UmaUtils.java",
]
}
@@ -109,7 +114,7 @@ android_library("interfaces_java") {
"org/chromium/weblayer_private/interfaces/NavigationState.java",
"org/chromium/weblayer_private/interfaces/NewTabType.java",
"org/chromium/weblayer_private/interfaces/ObjectWrapper.java",
- "org/chromium/weblayer_private/interfaces/WebLayerVersion.java",
+ "org/chromium/weblayer_private/interfaces/StrictModeWorkaround.java",
]
deps = [
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserFragmentImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserFragmentImpl.java
index 7e0e6477aa2..fa8ae19f94e 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserFragmentImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserFragmentImpl.java
@@ -15,6 +15,7 @@ import org.chromium.weblayer_private.interfaces.IBrowser;
import org.chromium.weblayer_private.interfaces.IBrowserFragment;
import org.chromium.weblayer_private.interfaces.IRemoteFragment;
import org.chromium.weblayer_private.interfaces.IRemoteFragmentClient;
+import org.chromium.weblayer_private.interfaces.StrictModeWorkaround;
/**
* Implementation of RemoteFragmentImpl which forwards logic to BrowserImpl.
@@ -34,6 +35,7 @@ public class BrowserFragmentImpl extends RemoteFragmentImpl {
@Override
public void onAttach(Context context) {
+ StrictModeWorkaround.apply();
super.onAttach(context);
mContext = ClassLoaderContextWrapperFactory.get(context);
if (mBrowser != null) { // On first creation, onAttach is called before onCreate
@@ -43,6 +45,7 @@ public class BrowserFragmentImpl extends RemoteFragmentImpl {
@Override
public void onCreate(Bundle savedInstanceState) {
+ StrictModeWorkaround.apply();
super.onCreate(savedInstanceState);
mBrowser = new BrowserImpl(mProfile, savedInstanceState);
if (mContext != null) {
@@ -52,22 +55,26 @@ public class BrowserFragmentImpl extends RemoteFragmentImpl {
@Override
public View onCreateView() {
+ StrictModeWorkaround.apply();
return mBrowser.getFragmentView();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ StrictModeWorkaround.apply();
mBrowser.onActivityResult(requestCode, resultCode, data);
}
@Override
public void onRequestPermissionsResult(
int requestCode, String[] permissions, int[] grantResults) {
+ StrictModeWorkaround.apply();
mBrowser.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
@Override
public void onDestroy() {
+ StrictModeWorkaround.apply();
super.onDestroy();
mBrowser.destroy();
mBrowser = null;
@@ -75,6 +82,7 @@ public class BrowserFragmentImpl extends RemoteFragmentImpl {
@Override
public void onDetach() {
+ StrictModeWorkaround.apply();
super.onDetach();
// mBrowser != null if fragment is retained, otherwise onDestroy is called first.
if (mBrowser != null) {
@@ -87,11 +95,13 @@ public class BrowserFragmentImpl extends RemoteFragmentImpl {
return new IBrowserFragment.Stub() {
@Override
public IRemoteFragment asRemoteFragment() {
+ StrictModeWorkaround.apply();
return BrowserFragmentImpl.this;
}
@Override
public IBrowser getBrowser() {
+ StrictModeWorkaround.apply();
if (mBrowser == null) {
throw new RuntimeException("Browser is available only between"
+ " BrowserFragment's onCreate() and onDestroy().");
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java
index 08449086bee..b4fb4a85c62 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java
@@ -20,6 +20,7 @@ import org.chromium.weblayer_private.interfaces.IObjectWrapper;
import org.chromium.weblayer_private.interfaces.IProfile;
import org.chromium.weblayer_private.interfaces.ITab;
import org.chromium.weblayer_private.interfaces.ObjectWrapper;
+import org.chromium.weblayer_private.interfaces.StrictModeWorkaround;
import java.util.ArrayList;
import java.util.List;
@@ -33,6 +34,7 @@ public class BrowserImpl extends IBrowser.Stub {
private FragmentWindowAndroid mWindowAndroid;
private ArrayList<TabImpl> mTabs = new ArrayList<TabImpl>();
private IBrowserClient mClient;
+ private LocaleChangedBroadcastReceiver mLocaleReceiver;
public BrowserImpl(ProfileImpl profile, Bundle savedInstanceState) {
mProfile = profile;
@@ -54,6 +56,8 @@ public class BrowserImpl extends IBrowser.Stub {
addTab(tab);
boolean set_active_result = setActiveTab(tab);
assert set_active_result;
+
+ mLocaleReceiver = new LocaleChangedBroadcastReceiver(context);
}
public void onFragmentDetached() {
@@ -75,11 +79,13 @@ public class BrowserImpl extends IBrowser.Stub {
@Override
public void setTopView(IObjectWrapper viewWrapper) {
+ StrictModeWorkaround.apply();
getViewController().setTopView(ObjectWrapper.unwrap(viewWrapper, View.class));
}
@Override
public void setSupportsEmbedding(boolean enable, IObjectWrapper valueCallback) {
+ StrictModeWorkaround.apply();
getViewController().setSupportsEmbedding(enable,
(ValueCallback<Boolean>) ObjectWrapper.unwrap(valueCallback, ValueCallback.class));
}
@@ -94,11 +100,13 @@ public class BrowserImpl extends IBrowser.Stub {
@Override
public IProfile getProfile() {
+ StrictModeWorkaround.apply();
return mProfile;
}
@Override
public void addTab(ITab iTab) {
+ StrictModeWorkaround.apply();
TabImpl tab = (TabImpl) iTab;
if (tab.getBrowser() == this) return;
addTabImpl(tab);
@@ -134,6 +142,7 @@ public class BrowserImpl extends IBrowser.Stub {
@Override
public boolean setActiveTab(ITab controller) {
+ StrictModeWorkaround.apply();
TabImpl tab = (TabImpl) controller;
if (tab != null && tab.getBrowser() != this) return false;
mViewController.setActiveTab(tab);
@@ -153,21 +162,25 @@ public class BrowserImpl extends IBrowser.Stub {
@Override
public List getTabs() {
+ StrictModeWorkaround.apply();
return new ArrayList(mTabs);
}
@Override
public int getActiveTabId() {
+ StrictModeWorkaround.apply();
return getActiveTab() != null ? getActiveTab().getId() : 0;
}
@Override
public void setClient(IBrowserClient client) {
+ StrictModeWorkaround.apply();
mClient = client;
}
@Override
public void destroyTab(ITab iTab) {
+ StrictModeWorkaround.apply();
detachTab(iTab);
((TabImpl) iTab).destroy();
}
@@ -177,6 +190,10 @@ public class BrowserImpl extends IBrowser.Stub {
}
public void destroy() {
+ if (mLocaleReceiver != null) {
+ mLocaleReceiver.destroy();
+ mLocaleReceiver = null;
+ }
if (mViewController != null) {
mViewController.destroy();
for (TabImpl tab : mTabs) {
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/ChildProcessServiceImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/ChildProcessServiceImpl.java
index ebfecb29e94..2a8a0d0b70b 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/ChildProcessServiceImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/ChildProcessServiceImpl.java
@@ -16,6 +16,7 @@ import org.chromium.content_public.app.ChildProcessServiceFactory;
import org.chromium.weblayer_private.interfaces.IChildProcessService;
import org.chromium.weblayer_private.interfaces.IObjectWrapper;
import org.chromium.weblayer_private.interfaces.ObjectWrapper;
+import org.chromium.weblayer_private.interfaces.StrictModeWorkaround;
/**
* Implementation of IChildProcessService.
@@ -33,17 +34,20 @@ public final class ChildProcessServiceImpl extends IChildProcessService.Stub {
@Override
public void onCreate() {
+ StrictModeWorkaround.apply();
mService.onCreate();
}
@Override
public void onDestroy() {
+ StrictModeWorkaround.apply();
mService.onDestroy();
mService = null;
}
@Override
public IObjectWrapper onBind(IObjectWrapper intent) {
+ StrictModeWorkaround.apply();
return ObjectWrapper.wrap(mService.onBind(ObjectWrapper.unwrap(intent, Intent.class)));
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/CrashReporterControllerImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/CrashReporterControllerImpl.java
index ce39d8ef129..1ce07c0b2e1 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/CrashReporterControllerImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/CrashReporterControllerImpl.java
@@ -21,6 +21,7 @@ import org.chromium.components.minidump_uploader.CrashFileManager;
import org.chromium.weblayer_private.interfaces.ICrashReporterController;
import org.chromium.weblayer_private.interfaces.ICrashReporterControllerClient;
import org.chromium.weblayer_private.interfaces.IObjectWrapper;
+import org.chromium.weblayer_private.interfaces.StrictModeWorkaround;
import java.io.File;
import java.io.FileInputStream;
@@ -73,6 +74,7 @@ public final class CrashReporterControllerImpl extends ICrashReporterController.
@Override
public void deleteCrash(String localId) {
+ StrictModeWorkaround.apply();
AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
deleteCrashOnBackgroundThread(localId);
try {
@@ -85,6 +87,7 @@ public final class CrashReporterControllerImpl extends ICrashReporterController.
@Override
public void uploadCrash(String localId) {
+ StrictModeWorkaround.apply();
AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
File minidumpFile = getCrashFileManager().getCrashFileWithLocalId(localId);
MinidumpUploader.Result result = new MinidumpUploader().upload(minidumpFile);
@@ -107,6 +110,7 @@ public final class CrashReporterControllerImpl extends ICrashReporterController.
@Override
public @Nullable Bundle getCrashKeys(String localId) {
+ StrictModeWorkaround.apply();
JSONObject data = readSidecar(localId);
if (data == null) {
return null;
@@ -126,6 +130,7 @@ public final class CrashReporterControllerImpl extends ICrashReporterController.
@Override
public void checkForPendingCrashReports() {
+ StrictModeWorkaround.apply();
AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
try {
mClient.onPendingCrashReports(getPendingMinidumpsOnBackgroundThread());
@@ -137,6 +142,7 @@ public final class CrashReporterControllerImpl extends ICrashReporterController.
@Override
public void setClient(ICrashReporterControllerClient client) {
+ StrictModeWorkaround.apply();
mClient = client;
if (mIsNativeInitialized) {
processNewMinidumps();
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/LocaleChangedBroadcastReceiver.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/LocaleChangedBroadcastReceiver.java
new file mode 100644
index 00000000000..76811caba70
--- /dev/null
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/LocaleChangedBroadcastReceiver.java
@@ -0,0 +1,41 @@
+// Copyright 2019 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.weblayer_private;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+
+import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.annotations.NativeMethods;
+
+/**
+ * Triggered when Android's locale changes.
+ */
+@JNINamespace("weblayer::i18n")
+public class LocaleChangedBroadcastReceiver extends BroadcastReceiver {
+ private final Context mContext;
+
+ public LocaleChangedBroadcastReceiver(Context context) {
+ mContext = context;
+ mContext.registerReceiver(this, new IntentFilter(Intent.ACTION_LOCALE_CHANGED));
+ }
+
+ public void destroy() {
+ mContext.unregisterReceiver(this);
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (!Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) return;
+ LocaleChangedBroadcastReceiverJni.get().localeChanged();
+ }
+
+ @NativeMethods
+ interface Natives {
+ void localeChanged();
+ }
+}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/NavigationControllerImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/NavigationControllerImpl.java
index 3fb45d58fb1..9362f44b59c 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/NavigationControllerImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/NavigationControllerImpl.java
@@ -11,6 +11,7 @@ import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.weblayer_private.interfaces.INavigationController;
import org.chromium.weblayer_private.interfaces.INavigationControllerClient;
+import org.chromium.weblayer_private.interfaces.StrictModeWorkaround;
/**
* Acts as the bridge between java and the C++ implementation of of NavigationController.
@@ -32,60 +33,70 @@ public final class NavigationControllerImpl extends INavigationController.Stub {
@Override
public void navigate(String uri) {
+ StrictModeWorkaround.apply();
NavigationControllerImplJni.get().navigate(
mNativeNavigationController, NavigationControllerImpl.this, uri);
}
@Override
public void goBack() {
+ StrictModeWorkaround.apply();
NavigationControllerImplJni.get().goBack(
mNativeNavigationController, NavigationControllerImpl.this);
}
@Override
public void goForward() {
+ StrictModeWorkaround.apply();
NavigationControllerImplJni.get().goForward(
mNativeNavigationController, NavigationControllerImpl.this);
}
@Override
public boolean canGoBack() {
+ StrictModeWorkaround.apply();
return NavigationControllerImplJni.get().canGoBack(
mNativeNavigationController, NavigationControllerImpl.this);
}
@Override
public boolean canGoForward() {
+ StrictModeWorkaround.apply();
return NavigationControllerImplJni.get().canGoForward(
mNativeNavigationController, NavigationControllerImpl.this);
}
@Override
public void reload() {
+ StrictModeWorkaround.apply();
NavigationControllerImplJni.get().reload(
mNativeNavigationController, NavigationControllerImpl.this);
}
@Override
public void stop() {
+ StrictModeWorkaround.apply();
NavigationControllerImplJni.get().stop(
mNativeNavigationController, NavigationControllerImpl.this);
}
@Override
public int getNavigationListSize() {
+ StrictModeWorkaround.apply();
return NavigationControllerImplJni.get().getNavigationListSize(
mNativeNavigationController, NavigationControllerImpl.this);
}
@Override
public int getNavigationListCurrentIndex() {
+ StrictModeWorkaround.apply();
return NavigationControllerImplJni.get().getNavigationListCurrentIndex(
mNativeNavigationController, NavigationControllerImpl.this);
}
@Override
public String getNavigationEntryDisplayUri(int index) {
+ StrictModeWorkaround.apply();
return NavigationControllerImplJni.get().getNavigationEntryDisplayUri(
mNativeNavigationController, NavigationControllerImpl.this, index);
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/NavigationImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/NavigationImpl.java
index dca8e88bf87..a2083951d0d 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/NavigationImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/NavigationImpl.java
@@ -15,6 +15,7 @@ import org.chromium.weblayer_private.interfaces.INavigation;
import org.chromium.weblayer_private.interfaces.INavigationControllerClient;
import org.chromium.weblayer_private.interfaces.LoadError;
import org.chromium.weblayer_private.interfaces.NavigationState;
+import org.chromium.weblayer_private.interfaces.StrictModeWorkaround;
import java.util.Arrays;
import java.util.List;
@@ -61,6 +62,7 @@ public final class NavigationImpl extends INavigation.Stub {
@Override
@NavigationState
public int getState() {
+ StrictModeWorkaround.apply();
throwIfNativeDestroyed();
return implTypeToJavaType(
NavigationImplJni.get().getState(mNativeNavigationImpl, NavigationImpl.this));
@@ -68,12 +70,14 @@ public final class NavigationImpl extends INavigation.Stub {
@Override
public String getUri() {
+ StrictModeWorkaround.apply();
throwIfNativeDestroyed();
return NavigationImplJni.get().getUri(mNativeNavigationImpl, NavigationImpl.this);
}
@Override
public List<String> getRedirectChain() {
+ StrictModeWorkaround.apply();
throwIfNativeDestroyed();
return Arrays.asList(NavigationImplJni.get().getRedirectChain(
mNativeNavigationImpl, NavigationImpl.this));
@@ -81,6 +85,7 @@ public final class NavigationImpl extends INavigation.Stub {
@Override
public int getHttpStatusCode() {
+ StrictModeWorkaround.apply();
throwIfNativeDestroyed();
return NavigationImplJni.get().getHttpStatusCode(
mNativeNavigationImpl, NavigationImpl.this);
@@ -88,18 +93,21 @@ public final class NavigationImpl extends INavigation.Stub {
@Override
public boolean isSameDocument() {
+ StrictModeWorkaround.apply();
throwIfNativeDestroyed();
return NavigationImplJni.get().isSameDocument(mNativeNavigationImpl, NavigationImpl.this);
}
@Override
public boolean isErrorPage() {
+ StrictModeWorkaround.apply();
throwIfNativeDestroyed();
return NavigationImplJni.get().isErrorPage(mNativeNavigationImpl, NavigationImpl.this);
}
@Override
public int getLoadError() {
+ StrictModeWorkaround.apply();
throwIfNativeDestroyed();
return implLoadErrorToLoadError(
NavigationImplJni.get().getLoadError(mNativeNavigationImpl, NavigationImpl.this));
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/ProfileImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/ProfileImpl.java
index d734d7bb0c3..7fc36e3ef44 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/ProfileImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/ProfileImpl.java
@@ -13,6 +13,7 @@ import org.chromium.weblayer_private.interfaces.BrowsingDataType;
import org.chromium.weblayer_private.interfaces.IObjectWrapper;
import org.chromium.weblayer_private.interfaces.IProfile;
import org.chromium.weblayer_private.interfaces.ObjectWrapper;
+import org.chromium.weblayer_private.interfaces.StrictModeWorkaround;
import java.util.ArrayList;
import java.util.List;
@@ -37,6 +38,7 @@ public final class ProfileImpl extends IProfile.Stub {
@Override
public void destroy() {
+ StrictModeWorkaround.apply();
ProfileImplJni.get().deleteProfile(mNativeProfile);
mNativeProfile = 0;
mOnDestroyCallback.run();
@@ -45,12 +47,14 @@ public final class ProfileImpl extends IProfile.Stub {
@Override
public String getName() {
+ StrictModeWorkaround.apply();
return mName;
}
@Override
public void clearBrowsingData(@NonNull @BrowsingDataType int[] dataTypes, long fromMillis,
long toMillis, @NonNull IObjectWrapper completionCallback) {
+ StrictModeWorkaround.apply();
Runnable callback = ObjectWrapper.unwrap(completionCallback, Runnable.class);
ProfileImplJni.get().clearBrowsingData(
mNativeProfile, mapBrowsingDataTypes(dataTypes), fromMillis, toMillis, callback);
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/RemoteFragmentImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/RemoteFragmentImpl.java
index 1b4a6b9c85d..3dc3a0bce35 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/RemoteFragmentImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/RemoteFragmentImpl.java
@@ -17,6 +17,7 @@ import org.chromium.weblayer_private.interfaces.IObjectWrapper;
import org.chromium.weblayer_private.interfaces.IRemoteFragment;
import org.chromium.weblayer_private.interfaces.IRemoteFragmentClient;
import org.chromium.weblayer_private.interfaces.ObjectWrapper;
+import org.chromium.weblayer_private.interfaces.StrictModeWorkaround;
/**
* Base for the classes controlling a Fragment that exists in another ClassLoader. Extending this
@@ -176,72 +177,86 @@ public abstract class RemoteFragmentImpl extends IRemoteFragment.Stub {
@Override
public final IObjectWrapper handleOnCreateView() {
+ StrictModeWorkaround.apply();
return ObjectWrapper.wrap(onCreateView());
}
@Override
public final void handleOnStart() {
+ StrictModeWorkaround.apply();
onStart();
}
@Override
public final void handleOnCreate(IObjectWrapper savedInstanceState) {
+ StrictModeWorkaround.apply();
onCreate(ObjectWrapper.unwrap(savedInstanceState, Bundle.class));
}
@Override
public final void handleOnAttach(IObjectWrapper context) {
+ StrictModeWorkaround.apply();
onAttach(ObjectWrapper.unwrap(context, Context.class));
}
@Override
public final void handleOnActivityCreated(IObjectWrapper savedInstanceState) {
+ StrictModeWorkaround.apply();
onActivityCreated(ObjectWrapper.unwrap(savedInstanceState, Bundle.class));
}
@Override
public final void handleOnResume() {
+ StrictModeWorkaround.apply();
onResume();
}
@Override
public final void handleOnPause() {
+ StrictModeWorkaround.apply();
onPause();
}
@Override
public final void handleOnStop() {
+ StrictModeWorkaround.apply();
onStop();
}
@Override
public final void handleOnDestroyView() {
+ StrictModeWorkaround.apply();
onDestroyView();
}
@Override
public final void handleOnDetach() {
+ StrictModeWorkaround.apply();
onDetach();
}
@Override
public final void handleOnDestroy() {
+ StrictModeWorkaround.apply();
onDestroy();
}
@Override
public final void handleOnSaveInstanceState(IObjectWrapper outState) {
+ StrictModeWorkaround.apply();
onSaveInstaceState(ObjectWrapper.unwrap(outState, Bundle.class));
}
@Override
public final void handleOnActivityResult(int requestCode, int resultCode, IObjectWrapper data) {
+ StrictModeWorkaround.apply();
onActivityResult(requestCode, resultCode, ObjectWrapper.unwrap(data, Intent.class));
}
@Override
public final void handleOnRequestPermissionsResult(
int requestCode, String[] permissions, int[] grantResults) {
+ StrictModeWorkaround.apply();
onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java
index ae439d4b688..c12c33da899 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java
@@ -25,6 +25,7 @@ import org.chromium.weblayer_private.interfaces.IObjectWrapper;
import org.chromium.weblayer_private.interfaces.ITab;
import org.chromium.weblayer_private.interfaces.ITabClient;
import org.chromium.weblayer_private.interfaces.ObjectWrapper;
+import org.chromium.weblayer_private.interfaces.StrictModeWorkaround;
/**
* Implementation of ITab.
@@ -126,6 +127,7 @@ public final class TabImpl extends ITab.Stub {
@Override
public void setNewTabsEnabled(boolean enable) {
+ StrictModeWorkaround.apply();
if (enable && mNewTabCallbackProxy == null) {
mNewTabCallbackProxy = new NewTabCallbackProxy(this);
} else if (!enable && mNewTabCallbackProxy != null) {
@@ -136,6 +138,7 @@ public final class TabImpl extends ITab.Stub {
@Override
public int getId() {
+ StrictModeWorkaround.apply();
return mId;
}
@@ -167,6 +170,7 @@ public final class TabImpl extends ITab.Stub {
@Override
public NavigationControllerImpl createNavigationController(INavigationControllerClient client) {
+ StrictModeWorkaround.apply();
// This should only be called once.
assert mNavigationController == null;
mNavigationController = new NavigationControllerImpl(this, client);
@@ -175,12 +179,14 @@ public final class TabImpl extends ITab.Stub {
@Override
public void setClient(ITabClient client) {
+ StrictModeWorkaround.apply();
mClient = client;
mTabCallbackProxy = new TabCallbackProxy(mNativeTab, client);
}
@Override
public void setDownloadCallbackClient(IDownloadCallbackClient client) {
+ StrictModeWorkaround.apply();
if (client != null) {
if (mDownloadCallbackProxy == null) {
mDownloadCallbackProxy = new DownloadCallbackProxy(mNativeTab, client);
@@ -195,6 +201,7 @@ public final class TabImpl extends ITab.Stub {
@Override
public void setErrorPageCallbackClient(IErrorPageCallbackClient client) {
+ StrictModeWorkaround.apply();
if (client != null) {
if (mErrorPageCallbackProxy == null) {
mErrorPageCallbackProxy = new ErrorPageCallbackProxy(mNativeTab, client);
@@ -209,6 +216,7 @@ public final class TabImpl extends ITab.Stub {
@Override
public void setFullscreenCallbackClient(IFullscreenCallbackClient client) {
+ StrictModeWorkaround.apply();
if (client != null) {
if (mFullscreenCallbackProxy == null) {
mFullscreenCallbackProxy = new FullscreenCallbackProxy(mNativeTab, client);
@@ -223,6 +231,7 @@ public final class TabImpl extends ITab.Stub {
@Override
public void executeScript(String script, boolean useSeparateIsolate, IObjectWrapper callback) {
+ StrictModeWorkaround.apply();
Callback<String> nativeCallback = new Callback<String>() {
@Override
public void onResult(String result) {
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/TopControlsContainerView.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/TopControlsContainerView.java
index c2c1f9d5d25..a51e0e55640 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/TopControlsContainerView.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/TopControlsContainerView.java
@@ -8,7 +8,6 @@ import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Rect;
import android.view.View;
-import android.view.ViewGroup.LayoutParams;
import android.view.ViewParent;
import android.widget.FrameLayout;
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerFactoryImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerFactoryImpl.java
index 68b11bcb5f2..ff6ed1b8c0d 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerFactoryImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerFactoryImpl.java
@@ -10,7 +10,6 @@ import org.chromium.base.annotations.UsedByReflection;
import org.chromium.components.version_info.VersionConstants;
import org.chromium.weblayer_private.interfaces.IWebLayer;
import org.chromium.weblayer_private.interfaces.IWebLayerFactory;
-import org.chromium.weblayer_private.interfaces.WebLayerVersion;
/**
* Factory used to create WebLayer as well as verify compatibility.
@@ -20,7 +19,6 @@ import org.chromium.weblayer_private.interfaces.WebLayerVersion;
public final class WebLayerFactoryImpl extends IWebLayerFactory.Stub {
private final int mClientMajorVersion;
private final String mClientVersion;
- private final int mClientWeblayerVersion;
/**
* This function is called by the client using reflection.
@@ -34,14 +32,12 @@ public final class WebLayerFactoryImpl extends IWebLayerFactory.Stub {
@UsedByReflection("WebLayer")
public static IBinder create(
String clientVersion, int clientMajorVersion, int clientWebLayerVersion) {
- return new WebLayerFactoryImpl(clientVersion, clientMajorVersion, clientWebLayerVersion);
+ return new WebLayerFactoryImpl(clientVersion, clientMajorVersion);
}
- private WebLayerFactoryImpl(
- String clientVersion, int clientMajorVersion, int clientWeblayerVersion) {
+ private WebLayerFactoryImpl(String clientVersion, int clientMajorVersion) {
mClientMajorVersion = clientMajorVersion;
mClientVersion = clientVersion;
- mClientWeblayerVersion = clientWeblayerVersion;
}
/**
@@ -50,7 +46,7 @@ public final class WebLayerFactoryImpl extends IWebLayerFactory.Stub {
*/
@Override
public boolean isClientSupported() {
- return mClientWeblayerVersion == WebLayerVersion.sVersionNumber;
+ return Math.abs(mClientMajorVersion - getImplementationMajorVersion()) <= 3;
}
/**
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java
index 5ba843f2e25..b5038bc8bdf 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java
@@ -4,7 +4,9 @@
package org.chromium.weblayer_private;
+import android.annotation.TargetApi;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.res.AssetManager;
import android.net.Uri;
@@ -20,6 +22,7 @@ import org.chromium.base.BuildInfo;
import org.chromium.base.CommandLine;
import org.chromium.base.ContentUriUtils;
import org.chromium.base.ContextUtils;
+import org.chromium.base.Log;
import org.chromium.base.PathUtils;
import org.chromium.base.StrictModeContext;
import org.chromium.base.annotations.JNINamespace;
@@ -38,6 +41,8 @@ import org.chromium.weblayer_private.interfaces.IProfile;
import org.chromium.weblayer_private.interfaces.IRemoteFragmentClient;
import org.chromium.weblayer_private.interfaces.IWebLayer;
import org.chromium.weblayer_private.interfaces.ObjectWrapper;
+import org.chromium.weblayer_private.interfaces.StrictModeWorkaround;
+import org.chromium.weblayer_private.metrics.UmaUtils;
import java.io.File;
import java.lang.reflect.Constructor;
@@ -90,8 +95,8 @@ public final class WebLayerImpl extends IWebLayer.Stub {
}
@Override
- public void loadAsync(
- IObjectWrapper appContextWrapper, IObjectWrapper loadedCallbackWrapper) {
+ public void loadAsync(IObjectWrapper appContextWrapper, IObjectWrapper loadedCallbackWrapper) {
+ StrictModeWorkaround.apply();
init(appContextWrapper);
final ValueCallback<Boolean> loadedCallback = (ValueCallback<Boolean>) ObjectWrapper.unwrap(
@@ -115,6 +120,7 @@ public final class WebLayerImpl extends IWebLayer.Stub {
@Override
public void loadSync(IObjectWrapper appContextWrapper) {
+ StrictModeWorkaround.apply();
init(appContextWrapper);
BrowserStartupController.get(LibraryProcessType.PROCESS_WEBLAYER)
@@ -129,6 +135,8 @@ public final class WebLayerImpl extends IWebLayer.Stub {
}
mInited = true;
+ UmaUtils.recordMainEntryPointTime();
+
Context appContext = minimalInitForContext(appContextWrapper);
PackageInfo packageInfo = WebViewFactory.getLoadedPackageInfo();
@@ -136,13 +144,14 @@ public final class WebLayerImpl extends IWebLayer.Stub {
// Contexts, ideally we would find a better way to do this.
addWebViewAssetPath(appContext, packageInfo);
+ applySplitApkWorkaround(packageInfo.applicationInfo, appContext.getResources().getAssets());
BuildInfo.setBrowserPackageInfo(packageInfo);
int resourcesPackageId = getPackageId(appContext, packageInfo.packageName);
// TODO: The call to onResourcesLoaded() can be slow, we may need to parallelize this with
// other expensive startup tasks.
R.onResourcesLoaded(resourcesPackageId);
- ResourceBundle.setAvailablePakLocales(new String[] {}, LocaleConfig.UNCOMPRESSED_LOCALES);
+ ResourceBundle.setAvailablePakLocales(new String[] {}, ProductConfig.UNCOMPRESSED_LOCALES);
ChildProcessCreationParams.set(appContext.getPackageName(), false /* isExternalService */,
LibraryProcessType.PROCESS_WEBLAYER_CHILD, true /* bindToCaller */,
@@ -172,6 +181,7 @@ public final class WebLayerImpl extends IWebLayer.Stub {
@Override
public IBrowserFragment createBrowserFragmentImpl(
IRemoteFragmentClient fragmentClient, IObjectWrapper fragmentArgs) {
+ StrictModeWorkaround.apply();
Bundle unwrappedArgs = ObjectWrapper.unwrap(fragmentArgs, Bundle.class);
BrowserFragmentImpl fragment =
new BrowserFragmentImpl(mProfileManager, fragmentClient, unwrappedArgs);
@@ -180,6 +190,7 @@ public final class WebLayerImpl extends IWebLayer.Stub {
@Override
public IProfile getProfile(String profileName) {
+ StrictModeWorkaround.apply();
return mProfileManager.getProfile(profileName);
}
@@ -248,6 +259,33 @@ public final class WebLayerImpl extends IWebLayer.Stub {
}
}
+ /** Adds assets from split APKs on Android versions where this is broken. */
+ @TargetApi(Build.VERSION_CODES.LOLLIPOP)
+ private static void applySplitApkWorkaround(
+ ApplicationInfo applicationInfo, AssetManager assetManager) {
+ // Q already handles this correctly.
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ return;
+ }
+
+ if (applicationInfo.splitSourceDirs != null) {
+ try {
+ Method addAssetPath;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ addAssetPath = AssetManager.class.getMethod(
+ "addAssetPathAsSharedLibrary", String.class);
+ } else {
+ addAssetPath = AssetManager.class.getMethod("addAssetPath", String.class);
+ }
+ for (String path : applicationInfo.splitSourceDirs) {
+ addAssetPath.invoke(assetManager, path);
+ }
+ } catch (ReflectiveOperationException e) {
+ Log.e(TAG, "Unable to load assets from split APK.", e);
+ }
+ }
+ }
+
@NativeMethods
interface Natives {
void setRemoteDebuggingEnabled(boolean enabled);
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/StrictModeWorkaround.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/StrictModeWorkaround.java
new file mode 100644
index 00000000000..9776d1a1107
--- /dev/null
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/StrictModeWorkaround.java
@@ -0,0 +1,95 @@
+// Copyright 2019 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.weblayer_private.interfaces;
+
+import android.os.Parcel;
+import android.os.StrictMode;
+import android.util.Log;
+
+import java.lang.reflect.Field;
+
+/**
+ * Workaround to unset PENALTY_GATHER in StrictMode.
+ * Normally the serialization code to set the PENALTY_GATHER bit in each AIDL
+ * call and the IPC code unsets the bit. WebLayer only uses AIDL for
+ * serialization, but not IPC; this leaves the PENALTY_GATHER bit always set,
+ * causing any StrictMode violations to be gathered and serialized in ever AIDL
+ * call but never reported.
+ * StrictModeWorkaround.apply will unset the PENALTY_GATHER bit and should be
+ * called at the beginning of the implementation of an AIDL call.
+ */
+public final class StrictModeWorkaround {
+ private static final String TAG = "StrictModeWorkaround";
+
+ private static final int PENALTY_GATHER;
+ private static final Field sThreadPolicyMaskField;
+ static {
+ Field field;
+ int mask;
+ try {
+ field = StrictMode.ThreadPolicy.class.getDeclaredField("mask");
+ field.setAccessible(true);
+
+ int currentMask = getCurrentPolicyMask(field);
+ try {
+ setCurrentPolicyMask(field, 0);
+
+ // The value of PENALTY_GATHER has changed between Android
+ // versions. Instead of hard coding them, try to get the value
+ // from Parcel directly.
+ Parcel parcel = Parcel.obtain();
+ // The value of the token does not matter.
+ parcel.writeInterfaceToken(TAG);
+ parcel.setDataPosition(0);
+ mask = parcel.readInt();
+ parcel.recycle();
+ } finally {
+ setCurrentPolicyMask(field, currentMask);
+ }
+ } catch (NoSuchFieldException | SecurityException e) {
+ Log.w(TAG, "StrictMode reflection exception", e);
+ field = null;
+ mask = 0;
+ } catch (RuntimeException e) {
+ Log.w(TAG, "StrictMode run time exception", e);
+ field = null;
+ mask = 0;
+ }
+ sThreadPolicyMaskField = field;
+ PENALTY_GATHER = mask;
+ }
+
+ private static int getCurrentPolicyMask(Field field) {
+ StrictMode.ThreadPolicy policy = StrictMode.getThreadPolicy();
+ try {
+ return field.getInt(policy);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private static void setCurrentPolicyMask(Field field, int newPolicyMask) {
+ StrictMode.ThreadPolicy policy = StrictMode.getThreadPolicy();
+ try {
+ field.setInt(policy, newPolicyMask);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ StrictMode.setThreadPolicy(policy);
+ }
+
+ public static void apply() {
+ if (sThreadPolicyMaskField == null) return;
+ try {
+ int currentPolicyMask = getCurrentPolicyMask(sThreadPolicyMaskField);
+ if ((currentPolicyMask & PENALTY_GATHER) == 0) {
+ return;
+ }
+ setCurrentPolicyMask(sThreadPolicyMaskField, currentPolicyMask & ~PENALTY_GATHER);
+ } catch (RuntimeException e) {
+ // Ignore exceptions.
+ }
+ }
+}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/WebLayerVersion.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/WebLayerVersion.java
deleted file mode 100644
index 381431a1019..00000000000
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/WebLayerVersion.java
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2019 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.weblayer_private.interfaces;
-
-/**
- * Holds the current version number of WebLayer.
- *
- * Whenever any AIDL file is changed, sVersionNumber must be incremented.
- * */
-public final class WebLayerVersion { public static final int sVersionNumber = 20; }
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/metrics/UmaUtils.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/metrics/UmaUtils.java
new file mode 100644
index 00000000000..05945544a10
--- /dev/null
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/metrics/UmaUtils.java
@@ -0,0 +1,36 @@
+// Copyright 2019 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.weblayer_private.metrics;
+
+import android.os.SystemClock;
+
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.annotations.MainDex;
+
+/**
+ * Utilities to support startup metrics
+ */
+@JNINamespace("weblayer")
+public class UmaUtils {
+ private static long sApplicationStartTimeMs;
+
+ /**
+ * Record the time in the application lifecycle at which WebLayer code first runs.
+ */
+ @MainDex
+ public static void recordMainEntryPointTime() {
+ // We can't simply pass this down through a JNI call, since the JNI for weblayer
+ // isn't initialized until we start the native content browser component, and we
+ // then need the start time in the C++ side before we return to Java. As such we
+ // save it in a static that the C++ can fetch once it has initialized the JNI.
+ sApplicationStartTimeMs = SystemClock.uptimeMillis();
+ }
+
+ @CalledByNative
+ public static long getMainEntryPointTicks() {
+ return sApplicationStartTimeMs;
+ }
+}