summaryrefslogtreecommitdiff
path: root/chromium/weblayer/public
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/weblayer/public')
-rw-r--r--chromium/weblayer/public/browser.h8
-rw-r--r--chromium/weblayer/public/java/AndroidManifest.xml11
-rw-r--r--chromium/weblayer/public/java/BUILD.gn14
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/Browser.java21
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/MediaSessionService.java96
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/Navigation.java4
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/NavigationCallback.java10
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/NavigationController.java49
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/Profile.java97
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/ScrollNotificationType.java34
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/SettingType.java39
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/Tab.java306
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/TabCallback.java24
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/WebLayer.java37
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/WebMessage.java34
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/WebMessageCallback.java24
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/WebMessageReplyProxy.java70
-rw-r--r--chromium/weblayer/public/java/res/values-night/colors.xml10
-rw-r--r--chromium/weblayer/public/java/res/values-night/values.xml10
-rw-r--r--chromium/weblayer/public/java/res/values-v27/styles.xml12
-rw-r--r--chromium/weblayer/public/java/res/values-v28/styles.xml18
-rw-r--r--chromium/weblayer/public/java/res/values/colors.xml16
-rw-r--r--chromium/weblayer/public/java/res/values/ids.xml8
-rw-r--r--chromium/weblayer/public/java/res/values/styles.xml13
-rw-r--r--chromium/weblayer/public/java/res/values/values.xml10
-rw-r--r--chromium/weblayer/public/javatests/org/chromium/weblayer/ObserverListTest.java2
-rw-r--r--chromium/weblayer/public/javatests/org/chromium/weblayer/WebViewCompatibilityHelperTest.java3
-rw-r--r--chromium/weblayer/public/javatestutil/BUILD.gn1
-rw-r--r--chromium/weblayer/public/javatestutil/org/chromium/weblayer/TestWebLayer.java39
-rw-r--r--chromium/weblayer/public/js_communication/web_message.cc13
-rw-r--r--chromium/weblayer/public/js_communication/web_message.h21
-rw-r--r--chromium/weblayer/public/js_communication/web_message_host.h26
-rw-r--r--chromium/weblayer/public/js_communication/web_message_host_factory.h35
-rw-r--r--chromium/weblayer/public/js_communication/web_message_reply_proxy.h25
-rw-r--r--chromium/weblayer/public/navigation.h5
-rw-r--r--chromium/weblayer/public/navigation_controller.h5
-rw-r--r--chromium/weblayer/public/navigation_observer.h7
-rw-r--r--chromium/weblayer/public/new_tab_delegate.h4
-rw-r--r--chromium/weblayer/public/profile.h34
-rw-r--r--chromium/weblayer/public/tab.h46
40 files changed, 1200 insertions, 41 deletions
diff --git a/chromium/weblayer/public/browser.h b/chromium/weblayer/public/browser.h
index 44e4c95fc79..8932998183b 100644
--- a/chromium/weblayer/public/browser.h
+++ b/chromium/weblayer/public/browser.h
@@ -46,12 +46,16 @@ class Browser {
virtual ~Browser() {}
- virtual Tab* AddTab(std::unique_ptr<Tab> tab) = 0;
- virtual std::unique_ptr<Tab> RemoveTab(Tab* tab) = 0;
+ virtual void AddTab(Tab* tab) = 0;
+ virtual void DestroyTab(Tab* tab) = 0;
virtual void SetActiveTab(Tab* tab) = 0;
virtual Tab* GetActiveTab() = 0;
virtual std::vector<Tab*> GetTabs() = 0;
+ // Creates a tab attached to this browser. The returned tab is owned by the
+ // browser.
+ virtual Tab* CreateTab() = 0;
+
// Called early on in shutdown, before any tabs have been removed.
virtual void PrepareForShutdown() = 0;
diff --git a/chromium/weblayer/public/java/AndroidManifest.xml b/chromium/weblayer/public/java/AndroidManifest.xml
index 13a2de7a715..90f4ab59033 100644
--- a/chromium/weblayer/public/java/AndroidManifest.xml
+++ b/chromium/weblayer/public/java/AndroidManifest.xml
@@ -13,6 +13,7 @@
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CAMERA"/>
+ <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
@@ -68,9 +69,19 @@
<action android:name="org.chromium.weblayer.downloads.PAUSE"/>
<action android:name="org.chromium.weblayer.downloads.RESUME"/>
<action android:name="org.chromium.weblayer.downloads.CANCEL"/>
+ <!-- this needs to be in sync with IntentUtils.java-->
+ <action android:name="org.chromium.weblayer.intent_utils.ACTIVATE_TAB"/>
<!-- this needs to be in sync with MediaStreamManager.java-->
+ <!-- TODO(estade): deprecated, remove in M88. -->
<action android:name="org.chromium.weblayer.webrtc.ACTIVATE_TAB"/>
</intent-filter>
</receiver>
+
+ <service android:name="org.chromium.weblayer.MediaSessionService"
+ android:exported="false">
+ <intent-filter>
+ <action android:name="android.intent.action.MEDIA_BUTTON" />
+ </intent-filter>
+ </service>
</application>
</manifest>
diff --git a/chromium/weblayer/public/java/BUILD.gn b/chromium/weblayer/public/java/BUILD.gn
index 26cf9072075..71c7c3ca23c 100644
--- a/chromium/weblayer/public/java/BUILD.gn
+++ b/chromium/weblayer/public/java/BUILD.gn
@@ -18,11 +18,18 @@ jinja_template("weblayer_client_manifest") {
}
android_resources("client_resources") {
+ custom_package = "org.chromium.weblayer"
sources = [
+ "res/values-night/colors.xml",
+ "res/values-night/values.xml",
+ "res/values-v27/styles.xml",
+ "res/values-v28/styles.xml",
+ "res/values/colors.xml",
+ "res/values/ids.xml",
"res/values/styles.xml",
+ "res/values/values.xml",
"res/xml/weblayer_file_paths.xml",
]
- deps = [ "//components/browser_ui/styles/android:java_resources" ]
android_manifest = weblayer_client_manifest
android_manifest_dep = ":weblayer_client_manifest"
}
@@ -53,6 +60,7 @@ android_library("java") {
"org/chromium/weblayer/LoadError.java",
"org/chromium/weblayer/MediaCaptureCallback.java",
"org/chromium/weblayer/MediaCaptureController.java",
+ "org/chromium/weblayer/MediaSessionService.java",
"org/chromium/weblayer/NavigateParams.java",
"org/chromium/weblayer/Navigation.java",
"org/chromium/weblayer/NavigationCallback.java",
@@ -63,6 +71,7 @@ android_library("java") {
"org/chromium/weblayer/ObserverList.java",
"org/chromium/weblayer/Profile.java",
"org/chromium/weblayer/RemoteFragment.java",
+ "org/chromium/weblayer/ScrollNotificationType.java",
"org/chromium/weblayer/SettingType.java",
"org/chromium/weblayer/SiteSettingsActivity.java",
"org/chromium/weblayer/SiteSettingsFragment.java",
@@ -75,6 +84,9 @@ android_library("java") {
"org/chromium/weblayer/UrlBarOptions.java",
"org/chromium/weblayer/WebLayer.java",
"org/chromium/weblayer/WebLayerFileProvider.java",
+ "org/chromium/weblayer/WebMessage.java",
+ "org/chromium/weblayer/WebMessageCallback.java",
+ "org/chromium/weblayer/WebMessageReplyProxy.java",
"org/chromium/weblayer/WebViewCompatibilityHelper.java",
_version_constants_java_file,
]
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/Browser.java b/chromium/weblayer/public/java/org/chromium/weblayer/Browser.java
index 1afd12ba996..41ec9e5af4e 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/Browser.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/Browser.java
@@ -236,6 +236,27 @@ public class Browser {
}
/**
+ * Creates a new tab attached to this browser. This will call {@link TabListCallback#onTabAdded}
+ * with the new tab.
+ *
+ * @since 85
+ */
+ public @NonNull Tab createTab() {
+ ThreadCheck.ensureOnUiThread();
+ if (WebLayer.getSupportedMajorVersionInternal() < 85) {
+ throw new UnsupportedOperationException();
+ }
+ try {
+ ITab iTab = mImpl.createTab();
+ Tab tab = Tab.getTabById(iTab.getId());
+ assert tab != null;
+ return tab;
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
+ /**
* Control support for embedding use cases such as animations. This should be enabled when the
* container view of the fragment is animated in any way, needs to be rotated or blended, or
* need to control z-order with other views or other BrowserFragmentImpls. Note embedder should
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/MediaSessionService.java b/chromium/weblayer/public/java/org/chromium/weblayer/MediaSessionService.java
new file mode 100644
index 00000000000..c13b09c1207
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/MediaSessionService.java
@@ -0,0 +1,96 @@
+// Copyright 2020 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;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+import org.chromium.weblayer_private.interfaces.ObjectWrapper;
+
+/**
+ * A foreground {@link Service} for the Web MediaSession API.
+ * This class is a thin wrapper that forwards lifecycle events to the WebLayer implementation, which
+ * in turn manages a system notification and {@link MediaSession}. This service will be in the
+ * foreground when the MediaSession is active.
+ * @since 85
+ */
+public class MediaSessionService extends Service {
+ // A helper to automatically pause the media session when a user removes headphones.
+ private BroadcastReceiver mAudioBecomingNoisyReceiver;
+
+ public MediaSessionService() {
+ if (WebLayer.getSupportedMajorVersionInternal() < 85) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ mAudioBecomingNoisyReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (!AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
+ return;
+ }
+
+ Intent i = new Intent(getApplication(), MediaSessionService.class);
+ i.setAction(intent.getAction());
+ getApplication().startService(i);
+ }
+ };
+
+ IntentFilter filter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
+ registerReceiver(mAudioBecomingNoisyReceiver, filter);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+
+ try {
+ getWebLayer().getImpl().onMediaSessionServiceDestroyed();
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+
+ unregisterReceiver(mAudioBecomingNoisyReceiver);
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ try {
+ getWebLayer().getImpl().onMediaSessionServiceStarted(ObjectWrapper.wrap(this), intent);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+
+ return START_NOT_STICKY;
+ }
+
+ private WebLayer getWebLayer() {
+ WebLayer webLayer;
+ try {
+ webLayer = WebLayer.getLoadedWebLayer(getApplication());
+ } catch (UnsupportedVersionException e) {
+ throw new RuntimeException(e);
+ }
+ if (webLayer == null) {
+ throw new IllegalStateException("WebLayer not initialized");
+ }
+ return webLayer;
+ }
+}
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/Navigation.java b/chromium/weblayer/public/java/org/chromium/weblayer/Navigation.java
index 85c880d09c5..53180286877 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/Navigation.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/Navigation.java
@@ -172,6 +172,10 @@ public class Navigation extends IClientNavigation.Stub {
* NavigationCallback.onNavigationStarted}. When called during start, the header applies to both
* the initial network request as well as redirects.
*
+ * This method may be used to set the referer. If the referer is set in navigation start, it is
+ * reset during the redirect. In other words, if you need to set a referer that applies to
+ * redirects, then this must be called from {@link onNavigationRedirected}.
+ *
* @param name The name of the header. The name must be rfc 2616 compliant.
* @param value The value of the header. The value must not contain '\0', '\n' or '\r'.
*
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/NavigationCallback.java b/chromium/weblayer/public/java/org/chromium/weblayer/NavigationCallback.java
index 6b64268a386..3b85def6ef8 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/NavigationCallback.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/NavigationCallback.java
@@ -4,6 +4,8 @@
package org.chromium.weblayer;
+import android.net.Uri;
+
import androidx.annotation.NonNull;
/**
@@ -112,4 +114,12 @@ public abstract class NavigationCallback {
* non-empty layout has finished. This is *not* called for same-document navigations.
*/
public void onFirstContentfulPaint() {}
+
+ /**
+ * Called after each navigation to indicate that the old page is no longer
+ * being rendered. Note this is not ordered with respect to onFirstContentfulPaint.
+ * @param newNavigationUri Uri of the new navigation.
+ * @since 85
+ */
+ public void onOldPageNoLongerRendered(@NonNull Uri newNavigationUri) {}
}
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/NavigationController.java b/chromium/weblayer/public/java/org/chromium/weblayer/NavigationController.java
index 6267141c69f..d36650ff973 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/NavigationController.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/NavigationController.java
@@ -69,6 +69,9 @@ public class NavigationController {
/**
* Navigates to the previous navigation.
*
+ * Note: this may go back more than a single navigation entry, see {@link
+ * isNavigationEntrySkippable} for more details.
+ *
* @throws IndexOutOfBoundsException If {@link #canGoBack} returns false.
*/
public void goBack() throws IndexOutOfBoundsException {
@@ -103,6 +106,9 @@ public class NavigationController {
/**
* Returns true if there is a navigation before the current one.
*
+ * Note: this may return false even if the current index is not 0, see {@link
+ * isNavigationEntrySkippable} for more details.
+ *
* @return Whether there is a navigation before the current one.
*/
public boolean canGoBack() {
@@ -212,6 +218,7 @@ public class NavigationController {
@NonNull
public Uri getNavigationEntryDisplayUri(int index) throws IndexOutOfBoundsException {
ThreadCheck.ensureOnUiThread();
+ checkNavigationIndex(index);
try {
return Uri.parse(mNavigationController.getNavigationEntryDisplayUri(index));
} catch (RemoteException e) {
@@ -219,12 +226,6 @@ public class NavigationController {
}
}
- private void checkNavigationIndex(int index) throws IndexOutOfBoundsException {
- if (index < 0 || index >= getNavigationListSize()) {
- throw new IndexOutOfBoundsException();
- }
- }
-
/**
* Returns the title of the navigation entry at the supplied index.
*
@@ -246,6 +247,28 @@ public class NavigationController {
}
}
+ /**
+ * Returns whether this entry will be skipped on a call to {@link goBack} or {@link goForward}.
+ * This will be true for certain navigations, such as certain client side redirects and
+ * history.pushState navigations done without user interaction.
+ *
+ * @throws IndexOutOfBoundsException If index is not between 0 and {@link
+ * getNavigationListCurrentIndex}.
+ * @since 85
+ */
+ public boolean isNavigationEntrySkippable(int index) throws IndexOutOfBoundsException {
+ ThreadCheck.ensureOnUiThread();
+ if (WebLayer.getSupportedMajorVersionInternal() < 85) {
+ throw new UnsupportedOperationException();
+ }
+ checkNavigationIndex(index);
+ try {
+ return mNavigationController.isNavigationEntrySkippable(index);
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
public void registerNavigationCallback(@NonNull NavigationCallback callback) {
ThreadCheck.ensureOnUiThread();
mCallbacks.addObserver(callback);
@@ -256,6 +279,12 @@ public class NavigationController {
mCallbacks.removeObserver(callback);
}
+ private void checkNavigationIndex(int index) throws IndexOutOfBoundsException {
+ if (index < 0 || index >= getNavigationListSize()) {
+ throw new IndexOutOfBoundsException();
+ }
+ }
+
private final class NavigationControllerClientImpl extends INavigationControllerClient.Stub {
@Override
public IClientNavigation createClientNavigation(INavigation navigationImpl) {
@@ -326,5 +355,13 @@ public class NavigationController {
callback.onFirstContentfulPaint();
}
}
+
+ @Override
+ public void onOldPageNoLongerRendered(String uri) {
+ StrictModeWorkaround.apply();
+ for (NavigationCallback callback : mCallbacks) {
+ callback.onOldPageNoLongerRendered(Uri.parse(uri));
+ }
+ }
}
}
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/Profile.java b/chromium/weblayer/public/java/org/chromium/weblayer/Profile.java
index 5d0eab7d54d..ed2071ea780 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/Profile.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/Profile.java
@@ -26,6 +26,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
/**
* Profile holds state (typically on disk) needed for browsing. Create a
@@ -117,13 +118,13 @@ public class Profile {
}
/**
-  * Delete all profile data stored on disk. There are a number of edge cases with deleting
-  * profile data:
-  * * This method will throw an exception if there are any existing usage of this Profile. For
-  *   example, all BrowserFragment belonging to this profile must be destroyed.
-  * * This object is considered destroyed after this method returns. Calling any other method
-  *   after will throw exceptions.
-  * * Creating a new profile of the same name before doneCallback runs will throw an exception.
+ * Delete all profile data stored on disk. There are a number of edge cases with deleting
+ * profile data:
+ * * This method will throw an exception if there are any existing usage of this Profile. For
+ * example, all BrowserFragment belonging to this profile must be destroyed.
+ * * This object is considered destroyed after this method returns. Calling any other method
+ * after will throw exceptions.
+ * * Creating a new profile of the same name before doneCallback runs will throw an exception.
* @since 82
*/
public void destroyAndDeleteDataFromDisk(@Nullable Runnable completionCallback) {
@@ -254,6 +255,88 @@ public class Profile {
}
}
+ /**
+ * Asynchronously fetches the set of known Browser persistence-ids. See
+ * {@link WebLayer#createBrowserFragment} for details on the persistence-id.
+ *
+ * @param callback The callback that is supplied the set of ids.
+ *
+ * @throws IllegalStateException If called on an in memory profile.
+ *
+ * @since 85
+ */
+ public void getBrowserPersistenceIds(@NonNull Callback<Set<String>> callback) {
+ ThreadCheck.ensureOnUiThread();
+ if (WebLayer.getSupportedMajorVersionInternal() < 85) {
+ throw new UnsupportedOperationException();
+ }
+ if (mName.isEmpty()) {
+ throw new IllegalStateException(
+ "getBrowserPersistenceIds() is not applicable to in-memory profiles");
+ }
+ try {
+ mImpl.getBrowserPersistenceIds(
+ ObjectWrapper.wrap((ValueCallback<Set<String>>) callback::onResult));
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
+ /**
+ * Asynchronously removes the storage associated with the set of Browser persistence-ids. This
+ * ignores ids actively in use. {@link doneCallback} is supplied the result of the operation. A
+ * value of true means all files were removed. A value of false indicates at least one of the
+ * files could not be removed.
+ *
+ * @param callback The callback that is supplied the result of the operation.
+ *
+ * @throws IllegalStateException If called on an in memory profile.
+ * @throws IllegalArgumentException if {@link ids} contains an empty/null string.
+ *
+ * @since 85
+ */
+ public void removeBrowserPersistenceStorage(
+ @NonNull Set<String> ids, @NonNull Callback<Boolean> callback) {
+ ThreadCheck.ensureOnUiThread();
+ if (WebLayer.getSupportedMajorVersionInternal() < 85) {
+ throw new UnsupportedOperationException();
+ }
+ if (mName.isEmpty()) {
+ throw new IllegalStateException(
+ "removetBrowserPersistenceStorage() is not applicable to in-memory profiles");
+ }
+ try {
+ mImpl.removeBrowserPersistenceStorage(ids.toArray(new String[ids.size()]),
+ ObjectWrapper.wrap((ValueCallback<Boolean>) callback::onResult));
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
+ /**
+ * For cross-origin navigations, the implementation may leverage a separate OS process for
+ * stronger isolation. If an embedder knows that a cross-origin navigation is likely starting
+ * soon, they can call this method as a hint to the implementation to start a fresh OS process.
+ * A subsequent navigation may use this preinitialized process, improving performance. It is
+ * safe to call this multiple times or when it is not certain that the spare renderer will be
+ * used, although calling this too eagerly may reduce performance as unnecessary processes are
+ * created.
+ *
+ * @since 85
+ */
+ public void prepareForPossibleCrossOriginNavigation() {
+ ThreadCheck.ensureOnUiThread();
+ if (WebLayer.getSupportedMajorVersionInternal() < 85) {
+ throw new UnsupportedOperationException();
+ }
+
+ try {
+ mImpl.prepareForPossibleCrossOriginNavigation();
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
static final class DownloadCallbackClientImpl extends IDownloadCallbackClient.Stub {
private final DownloadCallback mCallback;
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/ScrollNotificationType.java b/chromium/weblayer/public/java/org/chromium/weblayer/ScrollNotificationType.java
new file mode 100644
index 00000000000..b99949fe402
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/ScrollNotificationType.java
@@ -0,0 +1,34 @@
+// Copyright 2020 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;
+
+import androidx.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * @hide
+ */
+@IntDef({ScrollNotificationType.DIRECTION_CHANGED_UP,
+ ScrollNotificationType.DIRECTION_CHANGED_DOWN})
+@Retention(RetentionPolicy.SOURCE)
+public @interface ScrollNotificationType {
+ /**
+ * This is the direction toward vertical scroll offset 0. Note direction change notification
+ * is sent on direction change. If there are two consecutive scrolls in the same direction,
+ * the second scroll will not generate a direction change notification. Also the notification
+ * is sent as a result of scroll change; this means for touch scrolls, this is sent (if there
+ * is a direction change) on the first touch move, not touch down.
+ */
+ int DIRECTION_CHANGED_UP =
+ org.chromium.weblayer_private.interfaces.ScrollNotificationType.DIRECTION_CHANGED_UP;
+
+ /**
+ * This is the direction away from vertical scroll offset 0. See notes on DIRECTION_CHANGED_UP.
+ */
+ int DIRECTION_CHANGED_DOWN =
+ org.chromium.weblayer_private.interfaces.ScrollNotificationType.DIRECTION_CHANGED_DOWN;
+}
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/SettingType.java b/chromium/weblayer/public/java/org/chromium/weblayer/SettingType.java
index c5e800e8654..3fbc62492ff 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/SettingType.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/SettingType.java
@@ -12,7 +12,9 @@ import java.lang.annotation.RetentionPolicy;
/**
* @hide
*/
-@IntDef({SettingType.BASIC_SAFE_BROWSING_ENABLED})
+@IntDef({SettingType.BASIC_SAFE_BROWSING_ENABLED, SettingType.UKM_ENABLED,
+ SettingType.EXTENDED_REPORTING_SAFE_BROWSING_ENABLED,
+ SettingType.REAL_TIME_SAFE_BROWSING_ENABLED})
@Retention(RetentionPolicy.SOURCE)
public @interface SettingType {
/**
@@ -21,4 +23,39 @@ public @interface SettingType {
*/
int BASIC_SAFE_BROWSING_ENABLED =
org.chromium.weblayer_private.interfaces.SettingType.BASIC_SAFE_BROWSING_ENABLED;
+ /**
+ * Allows the embedder to enable URL-Keyed Metrics. Disabled by default.
+ */
+ int UKM_ENABLED = org.chromium.weblayer_private.interfaces.SettingType.UKM_ENABLED;
+
+ /**
+ * Allows the embedder to set whether it wants to enable/disable the Extended Reporting
+ * functionality for Safe Browsing (SBER). This functionality helps improve security on the web
+ * for everyone. It sends URLs of some pages you visit, limited system information, and some
+ * page content to Google, to help discover new threats and protect everyone on the web.
+ *
+ * This setting is disabled by default, but can also be enabled by the user by checking a
+ * checkbox in the Safe Browsing interstitial which is displayed when the user encounters a
+ * dangerous web page. The setting persists on disk.
+ *
+ * Note: this setting applies when Safe Browsing is enabled (i.e. BASIC_SAFE_BROWSING_ENABLED
+ * is true).
+ *
+ * @since 85
+ */
+ int EXTENDED_REPORTING_SAFE_BROWSING_ENABLED =
+ org.chromium.weblayer_private.interfaces.SettingType
+ .EXTENDED_REPORTING_SAFE_BROWSING_ENABLED;
+
+ /**
+ * Allows the embedder to set whether it wants to enable/disable the Safe Browsing Real-time URL
+ * checks. This functionality is disabled by default.
+ *
+ * Note: this setting applies when Safe Browsing is enabled (i.e. BASIC_SAFE_BROWSING_ENABLED
+ * is true).
+ *
+ * @since 85
+ */
+ int REAL_TIME_SAFE_BROWSING_ENABLED =
+ org.chromium.weblayer_private.interfaces.SettingType.REAL_TIME_SAFE_BROWSING_ENABLED;
}
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/Tab.java b/chromium/weblayer/public/java/org/chromium/weblayer/Tab.java
index a4ed8ae8009..bed3eee69cd 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/Tab.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/Tab.java
@@ -22,11 +22,14 @@ import org.chromium.weblayer_private.interfaces.IFullscreenCallbackClient;
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.IWebMessageCallbackClient;
+import org.chromium.weblayer_private.interfaces.IWebMessageReplyProxy;
import org.chromium.weblayer_private.interfaces.ObjectWrapper;
import org.chromium.weblayer_private.interfaces.StrictModeWorkaround;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -344,6 +347,292 @@ public class Tab {
}
}
+ /**
+ * Set arbitrary data on the tab. This will be saved and restored with the browser, so it is
+ * important to keep this data as small as possible.
+ *
+ * @param data The data to set, must be smaller than 4K when serialized. A snapshot of this data
+ * is taken, so any changes to the passed in object after this call will not be reflected.
+ *
+ * @throws IllegalArgumentException if the serialzed size of the data exceeds 4K.
+ *
+ * @since 85
+ */
+ public void setData(@NonNull Map<String, String> data) {
+ ThreadCheck.ensureOnUiThread();
+ if (WebLayer.getSupportedMajorVersionInternal() < 85) {
+ throw new UnsupportedOperationException();
+ }
+ try {
+ if (!mImpl.setData(data)) {
+ throw new IllegalArgumentException("Data given to Tab.setData() was too large.");
+ }
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
+ /**
+ * Get arbitrary data set on the tab with setData().
+ *
+ * @return the data or an empty map if no data was set.
+ * @since 85
+ */
+ @NonNull
+ public Map<String, String> getData() {
+ ThreadCheck.ensureOnUiThread();
+ if (WebLayer.getSupportedMajorVersionInternal() < 85) {
+ throw new UnsupportedOperationException();
+ }
+ try {
+ return (Map<String, String>) mImpl.getData();
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
+ /**
+ * Adds a WebMessageCallback and injects a JavaScript object into each frame that the
+ * WebMessageCallback will listen on.
+ *
+ * <p>
+ * The injected JavaScript object will be named {@code jsObjectName} in the global scope. This
+ * will inject the JavaScript object in any frame whose origin matches {@code
+ * allowedOriginRules} for every navigation after this call, and the JavaScript object will be
+ * available immediately when the page begins to load.
+ *
+ * <p>
+ * Each {@code allowedOriginRules} entry must follow the format {@code SCHEME "://" [
+ * HOSTNAME_PATTERN [ ":" PORT ] ]}, each part is explained in the below table:
+ *
+ * <table>
+ * <col width="25%">
+ * <tr><th>Rule</th><th>Description</th><th>Example</th></tr>
+ *
+ * <tr>
+ * <td>http/https with hostname</td>
+ * <td>{@code SCHEME} is http or https; {@code HOSTNAME_PATTERN} is a regular hostname; {@code
+ * PORT} is optional, when not present, the rule will match port {@code 80} for http and port
+ * {@code 443} for https.</td>
+ * <td><ul>
+ * <li>{@code https://foobar.com:8080} - Matches https:// URL on port 8080, whose normalized
+ * host is foobar.com.</li>
+ * <li>{@code https://www.example.com} - Matches https:// URL on port 443, whose normalized host
+ * is www.example.com.</li>
+ * </ul></td>
+ * </tr>
+ *
+ * <tr>
+ * <td>http/https with pattern matching</td>
+ * <td>{@code SCHEME} is http or https; {@code HOSTNAME_PATTERN} is a sub-domain matching
+ * pattern with a leading {@code *.}; {@code PORT} is optional, when not present, the rule will
+ * match port {@code 80} for http and port {@code 443} for https.</td>
+ *
+ * <td><ul>
+ * <li>{@code https://*.example.com} - Matches https://calendar.example.com and
+ * https://foo.bar.example.com but not https://example.com.</li>
+ * <li>{@code https://*.example.com:8080} - Matches https://calendar.example.com:8080</li>
+ * </ul></td>
+ * </tr>
+ *
+ * <tr>
+ * <td>http/https with IP literal</td>
+ * <td>{@code SCHEME} is https or https; {@code HOSTNAME_PATTERN} is IP literal; {@code PORT} is
+ * optional, when not present, the rule will match port {@code 80} for http and port {@code 443}
+ * for https.</td>
+ *
+ * <td><ul>
+ * <li>{@code https://127.0.0.1} - Matches https:// URL on port 443, whose IPv4 address is
+ * 127.0.0.1</li>
+ * <li>{@code https://[::1]} or {@code https://[0:0::1]}- Matches any URL to the IPv6 loopback
+ * address with port 443.</li>
+ * <li>{@code https://[::1]:99} - Matches any https:// URL to the IPv6 loopback on port 99.</li>
+ * </ul></td>
+ * </tr>
+ *
+ * <tr>
+ * <td>Custom scheme</td>
+ * <td>{@code SCHEME} is a custom scheme; {@code HOSTNAME_PATTERN} and {@code PORT} must not be
+ * present.</td>
+ * <td><ul>
+ * <li>{@code my-app-scheme://} - Matches any my-app-scheme:// URL.</li>
+ * </ul></td>
+ * </tr>
+ *
+ * <tr><td>{@code *}</td>
+ * <td>Wildcard rule, matches any origin.</td>
+ * <td><ul><li>{@code *}</li></ul></td>
+ * </table>
+ *
+ * <p>
+ * Note that this is a powerful API, as the JavaScript object will be injected when the frame's
+ * origin matches any one of the allowed origins. The HTTPS scheme is strongly recommended for
+ * security; allowing HTTP origins exposes the injected object to any potential network-based
+ * attackers. If a wildcard {@code "*"} is provided, it will inject the JavaScript object to all
+ * frames. A wildcard should only be used if the app wants <b>any</b> third party web page to be
+ * able to use the injected object. When using a wildcard, the app must treat received messages
+ * as untrustworthy and validate any data carefully.
+ *
+ * <p>
+ * This method can be called multiple times to inject multiple JavaScript objects.
+ *
+ * <p>
+ * Let's say the injected JavaScript object is named {@code myObject}. We will have following
+ * methods on that object once it is available to use:
+ * <pre class="prettyprint">
+ * // message needs to be a JavaScript String.
+ * myObject.postMessage(message)
+ *
+ * // To receive the message posted from the app side. event has a "data" property, which is the
+ * // message string from the app side.
+ * myObject.onmessage(event)
+ *
+ * // To be compatible with DOM EventTarget's addEventListener, it accepts type and listener
+ * // parameters, where type can be only "message" type and listener can only be a JavaScript
+ * // function for myObject. An event object will be passed to listener with a "data" property,
+ * // which is the message string from the app side.
+ * myObject.addEventListener(type, listener)
+ *
+ * // To be compatible with DOM EventTarget's removeEventListener, it accepts type and listener
+ * // parameters, where type can be only "message" type and listener can only be a JavaScript
+ * // function for myObject.
+ * myObject.removeEventListener(type, listener)
+ * </pre>
+ *
+ * <p>
+ * We start the communication between JavaScript and the app from the JavaScript side. In order
+ * to send message from the app to JavaScript, it needs to post a message from JavaScript first,
+ * so the app will have a {@link WebMessageReplyProxy} object to respond. Example:
+ * <pre class="prettyprint">
+ * // Web page (in JavaScript)
+ * myObject.onmessage = function(event) {
+ * // prints "Got it!" when we receive the app's response.
+ * console.log(event.data);
+ * }
+ * myObject.postMessage("I'm ready!");
+ *
+ * // App (in Java)
+ * WebMessageCallback callback = new WebMessageCallback() {
+ * &#064;Override
+ * public void onWebMessageReceived(WebMessageReplyProxy proxy,
+ * WebMessage message) {
+ * // do something about view, message, sourceOrigin and isMainFrame.
+ * proxy.postMessage(new WebMessage("Got it!"));
+ * }
+ * };
+ * tab.registerWebMessageCallback(callback, "myObject", rules);
+ * </pre>
+ *
+ * @param callback The WebMessageCallback to notify of messages.
+ * @param jsObjectName The name to give the injected JavaScript object.
+ * @param allowedOrigins The set of allowed origins.
+ *
+ * @throws IllegalArgumentException if jsObjectName or allowedOrigins is invalid.
+ *
+ * @since 85
+ */
+ public void registerWebMessageCallback(@NonNull WebMessageCallback callback,
+ @NonNull String jsObjectName, @NonNull List<String> allowedOrigins) {
+ ThreadCheck.ensureOnUiThread();
+ if (WebLayer.getSupportedMajorVersionInternal() < 85) {
+ throw new UnsupportedOperationException();
+ }
+ try {
+ mImpl.registerWebMessageCallback(
+ jsObjectName, allowedOrigins, new WebMessageCallbackClientImpl(callback));
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
+ /**
+ * Removes the JavaScript object previously registered by way of registerWebMessageCallback.
+ * This impacts future navigations (not any already loaded navigations).
+ *
+ * @param jsObjectName Name of the JavaScript object.
+ * @since 85
+ */
+ public void unregisterWebMessageCallback(@NonNull String jsObjectName) {
+ ThreadCheck.ensureOnUiThread();
+ if (WebLayer.getSupportedMajorVersionInternal() < 85) {
+ throw new UnsupportedOperationException();
+ }
+ try {
+ mImpl.unregisterWebMessageCallback(jsObjectName);
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
+ /**
+ * Returns true if the content displayed in this tab can be translated.
+ *
+ * @since 85
+ */
+ public boolean canTranslate() {
+ ThreadCheck.ensureOnUiThread();
+ if (WebLayer.getSupportedMajorVersionInternal() < 85) {
+ throw new UnsupportedOperationException();
+ }
+ try {
+ return mImpl.canTranslate();
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
+ /**
+ * Shows the UI which allows the user to translate the content displayed in this tab.
+ *
+ * @since 85
+ */
+ public void showTranslateUi() {
+ ThreadCheck.ensureOnUiThread();
+ if (WebLayer.getSupportedMajorVersionInternal() < 85) {
+ throw new UnsupportedOperationException();
+ }
+ try {
+ mImpl.showTranslateUi();
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
+ private static final class WebMessageCallbackClientImpl extends IWebMessageCallbackClient.Stub {
+ private final WebMessageCallback mCallback;
+ // Maps from id of IWebMessageReplyProxy to WebMessageReplyProxy. This is done to avoid AIDL
+ // creating an implementation of IWebMessageReplyProxy every time onPostMessage() is called.
+ private final Map<Integer, WebMessageReplyProxy> mProxyIdToProxy =
+ new HashMap<Integer, WebMessageReplyProxy>();
+
+ private WebMessageCallbackClientImpl(WebMessageCallback callback) {
+ mCallback = callback;
+ }
+
+ @Override
+ public void onNewReplyProxy(IWebMessageReplyProxy proxy, int proxyId, boolean isMainFrame,
+ String sourceOrigin) {
+ StrictModeWorkaround.apply();
+ assert mProxyIdToProxy.get(proxyId) == null;
+ mProxyIdToProxy.put(
+ proxyId, new WebMessageReplyProxy(proxy, isMainFrame, sourceOrigin));
+ }
+
+ @Override
+ public void onPostMessage(int proxyId, String string) {
+ StrictModeWorkaround.apply();
+ assert mProxyIdToProxy.get(proxyId) != null;
+ mCallback.onWebMessageReceived(mProxyIdToProxy.get(proxyId), new WebMessage(string));
+ }
+
+ @Override
+ public void onReplyProxyDestroyed(int proxyId) {
+ StrictModeWorkaround.apply();
+ assert mProxyIdToProxy.get(proxyId) != null;
+ mProxyIdToProxy.remove(proxyId);
+ }
+ }
+
private final class TabClientImpl extends ITabClient.Stub {
@Override
public void visibleUriChanged(String uriString) {
@@ -437,6 +726,23 @@ public class Tab {
callback.bringTabToFront();
}
}
+
+ @Override
+ public void onBackgroundColorChanged(int color) {
+ StrictModeWorkaround.apply();
+ for (TabCallback callback : mCallbacks) {
+ callback.onBackgroundColorChanged(color);
+ }
+ }
+
+ @Override
+ public void onScrollNotification(
+ @ScrollNotificationType int notificationType, float currentScrollRatio) {
+ StrictModeWorkaround.apply();
+ for (TabCallback callback : mCallbacks) {
+ callback.onScrollNotification(notificationType, currentScrollRatio);
+ }
+ }
}
private static final class ErrorPageCallbackClientImpl extends IErrorPageCallbackClient.Stub {
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/TabCallback.java b/chromium/weblayer/public/java/org/chromium/weblayer/TabCallback.java
index 007a7160453..5b1ecf4298c 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/TabCallback.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/TabCallback.java
@@ -54,4 +54,28 @@ public abstract class TabCallback {
* containing Activity, and the task to be foregrounded.
*/
public void bringTabToFront() {}
+
+ /**
+ * Called when then background color of the page changes. The background color typically comes
+ * from css background-color, but heuristics and blending may be used depending upon the page.
+ * This is mostly useful for filling in gaps around the web page during resize, but it will
+ * not necessarily match the full background of the page.
+ * @param color The new ARGB color of the page background.
+ * @since 85
+ */
+ public void onBackgroundColorChanged(int color) {}
+
+ /**
+ * Notification for scroll of the root of the web page. This is generally sent as a result of
+ * displaying web page. See ScrollNotificationType for more details. ScrollNotificationType is
+ * meant to be extensible and new types may be added in the future. Embedder should take care
+ * to allow unknown values.
+ * @param notificationType type of notification. See ScrollNotificationType for more details.
+ * @param currentScrollRatio value in [0, 1] indicating the current scroll ratio. For example
+ * a web page that is 200 pixels, has a viewport of height 50 pixels
+ * and a scroll offset of 50 pixels will have a ratio of 0.5.
+ * @since 85
+ */
+ public void onScrollNotification(
+ @ScrollNotificationType int notificationType, float currentScrollRatio) {}
}
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/WebLayer.java b/chromium/weblayer/public/java/org/chromium/weblayer/WebLayer.java
index 50eab9dcb31..b47b68ec6cf 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/WebLayer.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/WebLayer.java
@@ -32,6 +32,7 @@ import org.chromium.weblayer_private.interfaces.IWebLayerClient;
import org.chromium.weblayer_private.interfaces.IWebLayerFactory;
import org.chromium.weblayer_private.interfaces.ObjectWrapper;
import org.chromium.weblayer_private.interfaces.StrictModeWorkaround;
+import org.chromium.weblayer_private.interfaces.WebLayerVersionConstants;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@@ -179,6 +180,14 @@ public class WebLayer {
return mImpl;
}
+ static WebLayer getLoadedWebLayer(@NonNull Context appContext)
+ throws UnsupportedVersionException {
+ ThreadCheck.ensureOnUiThread();
+ appContext = appContext.getApplicationContext();
+ checkAvailable(appContext);
+ return getWebLayerLoader(appContext).getLoadedWebLayer();
+ }
+
/**
* Returns the supported version. Using any functions defined in a newer version than
* returned by {@link getSupportedMajorVersion} result in throwing an
@@ -270,17 +279,20 @@ public class WebLayer {
}
Class factoryClass = remoteClassLoader.loadClass(
"org.chromium.weblayer_private.WebLayerFactoryImpl");
- // NOTE: the 20 comes from the previous scheme of incrementing versioning. It must
- // remain at 20 for Chrome version 79.
- // TODO(https://crbug.com/1031830): change 20 to -1 when 83 goes to stable.
mFactory = IWebLayerFactory.Stub.asInterface(
(IBinder) factoryClass
.getMethod("create", String.class, int.class, int.class)
.invoke(null, WebLayerClientVersionConstants.PRODUCT_VERSION,
- WebLayerClientVersionConstants.PRODUCT_MAJOR_VERSION, 20));
+ WebLayerClientVersionConstants.PRODUCT_MAJOR_VERSION, -1));
available = mFactory.isClientSupported();
majorVersion = mFactory.getImplementationMajorVersion();
version = mFactory.getImplementationVersion();
+ // See comment in WebLayerFactoryImpl.isClientSupported() for details on this.
+ if (available
+ && WebLayerClientVersionConstants.PRODUCT_MAJOR_VERSION > majorVersion) {
+ available = WebLayerClientVersionConstants.PRODUCT_MAJOR_VERSION - majorVersion
+ <= WebLayerVersionConstants.MAX_SKEW;
+ }
} catch (Exception e) {
Log.e(TAG, "Unable to create WebLayerFactory", e);
}
@@ -360,6 +372,10 @@ public class WebLayer {
}
}
+ WebLayer getLoadedWebLayer() {
+ return mWebLayer;
+ }
+
@Nullable
private IWebLayer getIWebLayer(@NonNull Context appContext) {
if (mIWebLayer != null) return mIWebLayer;
@@ -668,5 +684,18 @@ public class WebLayer {
// client library because it's referenced in the manifest.
return new Intent(WebLayer.getAppContext(), BroadcastReceiver.class);
}
+
+ @Override
+ public Intent createMediaSessionServiceIntent() {
+ StrictModeWorkaround.apply();
+ return new Intent(WebLayer.getAppContext(), MediaSessionService.class);
+ }
+
+ @Override
+ public int getMediaSessionNotificationId() {
+ StrictModeWorkaround.apply();
+ // The id is part of the public library to avoid conflicts.
+ return R.id.weblayer_media_session_notification;
+ }
}
}
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/WebMessage.java b/chromium/weblayer/public/java/org/chromium/weblayer/WebMessage.java
new file mode 100644
index 00000000000..7fd27bd2bdc
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/WebMessage.java
@@ -0,0 +1,34 @@
+// Copyright 2020 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;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Used when sending and receiving messages to a page.
+ *
+ * @since 85
+ */
+public class WebMessage {
+ private final String mContents;
+
+ /**
+ * Creates a message with the specified contents.
+ *
+ * @param message Contents of the message.
+ */
+ public WebMessage(@NonNull String message) {
+ mContents = message;
+ }
+
+ /**
+ * Returns the contents of the message.
+ *
+ * @return The contents of the message.
+ */
+ public @NonNull String getContents() {
+ return mContents;
+ }
+}
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/WebMessageCallback.java b/chromium/weblayer/public/java/org/chromium/weblayer/WebMessageCallback.java
new file mode 100644
index 00000000000..bf35f5a4b5d
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/WebMessageCallback.java
@@ -0,0 +1,24 @@
+// Copyright 2020 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;
+
+import androidx.annotation.NonNull;
+
+/**
+ * Receives messages from a JavaScript object that was created by calling {@link
+ * Tab#registerWebMessageCallback().
+ *
+ * @since 85
+ */
+public abstract class WebMessageCallback {
+ /**
+ * Called when a message is received from the page.
+ *
+ * @param replyProxy An object that may be used to post a message back to the page.
+ * @param message The message from the page.
+ */
+ public void onWebMessageReceived(
+ @NonNull WebMessageReplyProxy replyProxy, @NonNull WebMessage message) {}
+}
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/WebMessageReplyProxy.java b/chromium/weblayer/public/java/org/chromium/weblayer/WebMessageReplyProxy.java
new file mode 100644
index 00000000000..de9df58d879
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/WebMessageReplyProxy.java
@@ -0,0 +1,70 @@
+// Copyright 2020 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;
+
+import android.os.RemoteException;
+
+import androidx.annotation.NonNull;
+
+import org.chromium.weblayer_private.interfaces.APICallException;
+import org.chromium.weblayer_private.interfaces.IWebMessageReplyProxy;
+
+/**
+ * Used to post a message to a page. WebMessageReplyProxy is created when a page posts a message to
+ * the JavaScript object that was created by way of {@link Tab#registerWebMessageCallback}.
+ *
+ * @since 85
+ */
+public class WebMessageReplyProxy {
+ private final IWebMessageReplyProxy mIReplyProxy;
+ private final boolean mIsMainFrame;
+ private final String mSourceOrigin;
+
+ // Constructor for test mocking.
+ protected WebMessageReplyProxy() {
+ this(null, false, "");
+ }
+
+ WebMessageReplyProxy(
+ IWebMessageReplyProxy iReplyProxy, boolean isMainFrame, String sourceOrigin) {
+ mIReplyProxy = iReplyProxy;
+ mIsMainFrame = isMainFrame;
+ mSourceOrigin = sourceOrigin;
+ }
+
+ /**
+ * Returns true if the connection is to the main frame.
+ *
+ * @return True if the connection is to the main frame.
+ */
+ public boolean isMainFrame() {
+ ThreadCheck.ensureOnUiThread();
+ return mIsMainFrame;
+ }
+
+ /**
+ * Returns the origin of the page.
+ *
+ * @return the origin of the page.
+ */
+ public @NonNull String getSourceOrigin() {
+ ThreadCheck.ensureOnUiThread();
+ return mSourceOrigin;
+ }
+
+ /**
+ * Posts a message to the page.
+ *
+ * @param message The message to send to the page.
+ */
+ public void postMessage(@NonNull WebMessage message) {
+ ThreadCheck.ensureOnUiThread();
+ try {
+ mIReplyProxy.postMessage(message.getContents());
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+}
diff --git a/chromium/weblayer/public/java/res/values-night/colors.xml b/chromium/weblayer/public/java/res/values-night/colors.xml
new file mode 100644
index 00000000000..3846e456aee
--- /dev/null
+++ b/chromium/weblayer/public/java/res/values-night/colors.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2020 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. -->
+
+<resources>
+ <color name="weblayer_default_bg_color">@color/weblayer_default_bg_color_dark</color>
+ <color name="weblayer_bottom_system_nav_color">@android:color/black</color>
+ <color name="weblayer_bottom_system_nav_divider_color">@android:color/black</color>
+</resources>
diff --git a/chromium/weblayer/public/java/res/values-night/values.xml b/chromium/weblayer/public/java/res/values-night/values.xml
new file mode 100644
index 00000000000..5009ad51a2a
--- /dev/null
+++ b/chromium/weblayer/public/java/res/values-night/values.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2020 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. -->
+
+<resources xmlns:tools="http://schemas.android.com/tools">
+ <!-- Status and navigation bar icon styling. -->
+ <bool name="weblayer_window_light_status_bar">false</bool>
+ <bool name="weblayer_window_light_navigation_bar">false</bool>
+</resources>
diff --git a/chromium/weblayer/public/java/res/values-v27/styles.xml b/chromium/weblayer/public/java/res/values-v27/styles.xml
new file mode 100644
index 00000000000..0ffe78b5f62
--- /dev/null
+++ b/chromium/weblayer/public/java/res/values-v27/styles.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2020 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. -->
+
+<resources>
+ <style name="Theme.WebLayer.SiteSettings" parent="Base.Theme.WebLayer.SiteSettings">
+ <item name="android:navigationBarColor">@color/weblayer_bottom_system_nav_color</item>
+ <item name="android:navigationBarDividerColor">@color/weblayer_bottom_system_nav_divider_color</item>
+ <item name="android:windowLightNavigationBar">@bool/weblayer_window_light_navigation_bar</item>
+ </style>
+</resources>
diff --git a/chromium/weblayer/public/java/res/values-v28/styles.xml b/chromium/weblayer/public/java/res/values-v28/styles.xml
new file mode 100644
index 00000000000..0a21de0a4eb
--- /dev/null
+++ b/chromium/weblayer/public/java/res/values-v28/styles.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2020 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. -->
+
+<resources>
+ <style name="Theme.WebLayer.SiteSettings" parent="Base.Theme.WebLayer.SiteSettings">
+ <item name="android:navigationBarColor">@color/weblayer_bottom_system_nav_color</item>
+ <item name="android:navigationBarDividerColor">@color/weblayer_bottom_system_nav_divider_color</item>
+ <item name="android:windowLightNavigationBar">@bool/weblayer_window_light_navigation_bar</item>
+
+ <!-- The windowLightStatusBar attribute was added in API 23, but we
+ avoid using it via XML prior to 28 due to: https://crbug.com/884144
+ and https://crbug.com/1014844 -->
+ <item name="android:statusBarColor">@color/weblayer_default_bg_color</item>
+ <item name="android:windowLightStatusBar">@bool/weblayer_window_light_status_bar</item>
+ </style>
+</resources>
diff --git a/chromium/weblayer/public/java/res/values/colors.xml b/chromium/weblayer/public/java/res/values/colors.xml
new file mode 100644
index 00000000000..bb86aec4897
--- /dev/null
+++ b/chromium/weblayer/public/java/res/values/colors.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2020 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. -->
+
+<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources">
+ <color name="weblayer_default_bg_color">@color/weblayer_default_bg_color_light</color>
+ <color name="weblayer_default_bg_color_light">@android:color/white</color>
+ <color name="weblayer_default_bg_color_dark">@color/weblayer_modern_grey_900</color>
+
+ <color name="weblayer_bottom_system_nav_color">@android:color/white</color>
+ <color name="weblayer_bottom_system_nav_divider_color">@color/weblayer_black_alpha_12</color>
+
+ <color name="weblayer_black_alpha_12">#1F000000</color>
+ <color name="weblayer_modern_grey_900">#202124</color>
+</resources>
diff --git a/chromium/weblayer/public/java/res/values/ids.xml b/chromium/weblayer/public/java/res/values/ids.xml
new file mode 100644
index 00000000000..300c7e62a50
--- /dev/null
+++ b/chromium/weblayer/public/java/res/values/ids.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2020 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. -->
+
+<resources>
+ <item type="id" name="weblayer_media_session_notification" />
+</resources>
diff --git a/chromium/weblayer/public/java/res/values/styles.xml b/chromium/weblayer/public/java/res/values/styles.xml
index 478e0f2bbcd..143124cc560 100644
--- a/chromium/weblayer/public/java/res/values/styles.xml
+++ b/chromium/weblayer/public/java/res/values/styles.xml
@@ -4,21 +4,18 @@
found in the LICENSE file. -->
<resources xmlns:tools="http://schemas.android.com/tools">
- <style name="Theme.WebLayer" parent="Theme.BrowserUI">
+ <style name="Base.Theme.WebLayer.SiteSettings" parent="Theme.AppCompat.DayNight">
<!-- Window Properties -->
- <item name="android:windowBackground">@color/default_bg_color</item>
+ <item name="android:windowBackground">@color/weblayer_default_bg_color</item>
<!-- Action bar color -->
- <item name="colorPrimary">@color/default_bg_color</item>
+ <item name="colorPrimary">@color/weblayer_default_bg_color</item>
<!-- Status bar color -->
+ <item name="colorPrimaryDark">@android:color/black</item>
<item name="android:statusBarColor" tools:targetApi="21">@android:color/black</item>
<item name="android:windowLightStatusBar" tools:targetApi="23">false</item>
- <item name="colorPrimaryDark">@android:color/black</item>
</style>
- <style name="Theme.WebLayer.SiteSettings">
- <item name="windowActionBar">true</item>
- <item name="windowNoTitle">false</item>
- </style>
+ <style name="Theme.WebLayer.SiteSettings" parent="Base.Theme.WebLayer.SiteSettings" />
</resources>
diff --git a/chromium/weblayer/public/java/res/values/values.xml b/chromium/weblayer/public/java/res/values/values.xml
new file mode 100644
index 00000000000..a04c1d9a0ea
--- /dev/null
+++ b/chromium/weblayer/public/java/res/values/values.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2020 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. -->
+
+<resources xmlns:tools="http://schemas.android.com/tools">
+ <!-- Status and navigation bar icon styling. -->
+ <bool name="weblayer_window_light_status_bar">true</bool>
+ <bool name="weblayer_window_light_navigation_bar">true</bool>
+</resources>
diff --git a/chromium/weblayer/public/javatests/org/chromium/weblayer/ObserverListTest.java b/chromium/weblayer/public/javatests/org/chromium/weblayer/ObserverListTest.java
index 35343813c9d..605037dd909 100644
--- a/chromium/weblayer/public/javatests/org/chromium/weblayer/ObserverListTest.java
+++ b/chromium/weblayer/public/javatests/org/chromium/weblayer/ObserverListTest.java
@@ -4,7 +4,7 @@
package org.chromium.weblayer;
-import android.support.test.filters.SmallTest;
+import androidx.test.filters.SmallTest;
import org.junit.Assert;
import org.junit.Test;
diff --git a/chromium/weblayer/public/javatests/org/chromium/weblayer/WebViewCompatibilityHelperTest.java b/chromium/weblayer/public/javatests/org/chromium/weblayer/WebViewCompatibilityHelperTest.java
index ceca8dc15a9..998f0907ec4 100644
--- a/chromium/weblayer/public/javatests/org/chromium/weblayer/WebViewCompatibilityHelperTest.java
+++ b/chromium/weblayer/public/javatests/org/chromium/weblayer/WebViewCompatibilityHelperTest.java
@@ -7,9 +7,10 @@ package org.chromium.weblayer;
import android.content.Context;
import android.os.Build;
import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
import android.util.Pair;
+import androidx.test.filters.SmallTest;
+
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/chromium/weblayer/public/javatestutil/BUILD.gn b/chromium/weblayer/public/javatestutil/BUILD.gn
index 48b69a71639..5fd626da668 100644
--- a/chromium/weblayer/public/javatestutil/BUILD.gn
+++ b/chromium/weblayer/public/javatestutil/BUILD.gn
@@ -12,6 +12,7 @@ android_library("test_java") {
deps = [
"//base:base_java_test_support",
"//third_party/junit:junit",
+ "//weblayer/browser/java:interfaces_java",
"//weblayer/browser/java:test_java",
"//weblayer/public/java",
]
diff --git a/chromium/weblayer/public/javatestutil/org/chromium/weblayer/TestWebLayer.java b/chromium/weblayer/public/javatestutil/org/chromium/weblayer/TestWebLayer.java
index 370103f4fab..1623a9e7906 100644
--- a/chromium/weblayer/public/javatestutil/org/chromium/weblayer/TestWebLayer.java
+++ b/chromium/weblayer/public/javatestutil/org/chromium/weblayer/TestWebLayer.java
@@ -9,10 +9,12 @@ import android.content.pm.PackageManager;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.AndroidRuntimeException;
+import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import org.chromium.weblayer_private.interfaces.ObjectWrapper;
import org.chromium.weblayer_private.test_interfaces.ITestWebLayer;
/**
@@ -75,4 +77,41 @@ public final class TestWebLayer {
public void setSystemLocationSettingEnabled(boolean enabled) throws RemoteException {
mITestWebLayer.setSystemLocationSettingEnabled(enabled);
}
+
+ // Runs |runnable| when cc::RenderFrameMetadata's |top_controls_height| and
+ // |bottom_controls_height| matches the supplied values. |runnable| may be run synchronously.
+ public void waitForBrowserControlsMetadataState(Tab tab, int top, int bottom, Runnable runnable)
+ throws RemoteException {
+ mITestWebLayer.waitForBrowserControlsMetadataState(
+ tab.getITab(), top, bottom, ObjectWrapper.wrap(runnable));
+ }
+
+ public void setAccessibilityEnabled(boolean enabled) throws RemoteException {
+ mITestWebLayer.setAccessibilityEnabled(enabled);
+ }
+
+ public boolean canBrowserControlsScroll(Tab tab) throws RemoteException {
+ return mITestWebLayer.canBrowserControlsScroll(tab.getITab());
+ }
+
+ public void addInfoBar(Tab tab, Runnable runnable) throws RemoteException {
+ mITestWebLayer.addInfoBar(tab.getITab(), ObjectWrapper.wrap(runnable));
+ }
+
+ public View getInfoBarContainerView(Tab tab) throws RemoteException {
+ return (View) ObjectWrapper.unwrap(
+ mITestWebLayer.getInfoBarContainerView(tab.getITab()), View.class);
+ }
+
+ public void setIgnoreMissingKeyForTranslateManager(boolean ignore) throws RemoteException {
+ mITestWebLayer.setIgnoreMissingKeyForTranslateManager(ignore);
+ }
+
+ public void forceNetworkConnectivityState(boolean networkAvailable) throws RemoteException {
+ mITestWebLayer.forceNetworkConnectivityState(networkAvailable);
+ }
+
+ public boolean canInfoBarContainerScroll(Tab tab) throws RemoteException {
+ return mITestWebLayer.canInfoBarContainerScroll(tab.getITab());
+ }
}
diff --git a/chromium/weblayer/public/js_communication/web_message.cc b/chromium/weblayer/public/js_communication/web_message.cc
new file mode 100644
index 00000000000..ebdcd6632d0
--- /dev/null
+++ b/chromium/weblayer/public/js_communication/web_message.cc
@@ -0,0 +1,13 @@
+// Copyright 2020 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.
+
+#include "weblayer/public/js_communication/web_message.h"
+
+namespace weblayer {
+
+WebMessage::WebMessage() = default;
+
+WebMessage::~WebMessage() = default;
+
+} // namespace weblayer
diff --git a/chromium/weblayer/public/js_communication/web_message.h b/chromium/weblayer/public/js_communication/web_message.h
new file mode 100644
index 00000000000..169cbe1da0c
--- /dev/null
+++ b/chromium/weblayer/public/js_communication/web_message.h
@@ -0,0 +1,21 @@
+// Copyright 2020 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.
+
+#ifndef WEBLAYER_PUBLIC_JS_COMMUNICATION_WEB_MESSAGE_H_
+#define WEBLAYER_PUBLIC_JS_COMMUNICATION_WEB_MESSAGE_H_
+
+#include "base/strings/string16.h"
+
+namespace weblayer {
+
+struct WebMessage {
+ WebMessage();
+ ~WebMessage();
+
+ base::string16 message;
+};
+
+} // namespace weblayer
+
+#endif // WEBLAYER_PUBLIC_JS_COMMUNICATION_WEB_MESSAGE_H_
diff --git a/chromium/weblayer/public/js_communication/web_message_host.h b/chromium/weblayer/public/js_communication/web_message_host.h
new file mode 100644
index 00000000000..b81ab149abd
--- /dev/null
+++ b/chromium/weblayer/public/js_communication/web_message_host.h
@@ -0,0 +1,26 @@
+// Copyright 2020 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.
+
+#ifndef WEBLAYER_PUBLIC_JS_COMMUNICATION_WEB_MESSAGE_HOST_H_
+#define WEBLAYER_PUBLIC_JS_COMMUNICATION_WEB_MESSAGE_HOST_H_
+
+#include <memory>
+
+namespace weblayer {
+
+struct WebMessage;
+
+// Represents the browser side of a WebMessage channel. See
+// WebMessageHostFactory for details.
+class WebMessageHost {
+ public:
+ virtual ~WebMessageHost() = default;
+
+ // Called when the page sends a message to the browser side.
+ virtual void OnPostMessage(std::unique_ptr<WebMessage> message) = 0;
+};
+
+} // namespace weblayer
+
+#endif // WEBLAYER_PUBLIC_JS_COMMUNICATION_WEB_MESSAGE_HOST_H_
diff --git a/chromium/weblayer/public/js_communication/web_message_host_factory.h b/chromium/weblayer/public/js_communication/web_message_host_factory.h
new file mode 100644
index 00000000000..2f754e15653
--- /dev/null
+++ b/chromium/weblayer/public/js_communication/web_message_host_factory.h
@@ -0,0 +1,35 @@
+// Copyright 2020 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.
+
+#ifndef WEBLAYER_PUBLIC_JS_COMMUNICATION_WEB_MESSAGE_HOST_FACTORY_H_
+#define WEBLAYER_PUBLIC_JS_COMMUNICATION_WEB_MESSAGE_HOST_FACTORY_H_
+
+#include <memory>
+#include <string>
+
+namespace weblayer {
+
+class WebMessageHost;
+class WebMessageReplyProxy;
+
+// Creates a WebMessageHost in response to a page interacting with the object
+// registered by way of Tab::AddWebMessageHostFactory(). A WebMessageHost is
+// created for every page that matches the parameters of
+// AddWebMessageHostFactory().
+class WebMessageHostFactory {
+ public:
+ virtual ~WebMessageHostFactory() = default;
+
+ // The returned object is destroyed when the corresponding renderer has
+ // been destroyed. |proxy| may be used to send messages to the page and is
+ // valid for the life of the WebMessageHost.
+ virtual std::unique_ptr<WebMessageHost> CreateHost(
+ const std::string& origin_string,
+ bool is_main_frame,
+ WebMessageReplyProxy* proxy) = 0;
+};
+
+} // namespace weblayer
+
+#endif // WEBLAYER_PUBLIC_JS_COMMUNICATION_WEB_MESSAGE_HOST_FACTORY_H_
diff --git a/chromium/weblayer/public/js_communication/web_message_reply_proxy.h b/chromium/weblayer/public/js_communication/web_message_reply_proxy.h
new file mode 100644
index 00000000000..e7147096494
--- /dev/null
+++ b/chromium/weblayer/public/js_communication/web_message_reply_proxy.h
@@ -0,0 +1,25 @@
+// Copyright 2020 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.
+
+#ifndef WEBLAYER_PUBLIC_JS_COMMUNICATION_WEB_MESSAGE_REPLY_PROXY_H_
+#define WEBLAYER_PUBLIC_JS_COMMUNICATION_WEB_MESSAGE_REPLY_PROXY_H_
+
+#include <memory>
+
+namespace weblayer {
+
+struct WebMessage;
+
+// Used to send messages to the page.
+class WebMessageReplyProxy {
+ public:
+ virtual void PostMessage(std::unique_ptr<WebMessage>) = 0;
+
+ protected:
+ virtual ~WebMessageReplyProxy() = default;
+};
+
+} // namespace weblayer
+
+#endif // WEBLAYER_PUBLIC_JS_COMMUNICATION_WEB_MESSAGE_REPLY_PROXY_H_
diff --git a/chromium/weblayer/public/navigation.h b/chromium/weblayer/public/navigation.h
index 725962e4908..af69c1bbfe8 100644
--- a/chromium/weblayer/public/navigation.h
+++ b/chromium/weblayer/public/navigation.h
@@ -94,6 +94,11 @@ class Navigation {
// and redirect. When called during start, the header applies to both the
// start and redirect. |name| must be rfc 2616 compliant and |value| must
// not contain '\0', '\n' or '\r'.
+ //
+ // This function may be used to set the referer. If the referer is set in
+ // navigation start, it is reset during the redirect. In other words, if you
+ // need to set a referer that applies to redirects, then this must be called
+ // from NavigationRedirected().
virtual void SetRequestHeader(const std::string& name,
const std::string& value) = 0;
diff --git a/chromium/weblayer/public/navigation_controller.h b/chromium/weblayer/public/navigation_controller.h
index 4b042c19353..c584c5d1432 100644
--- a/chromium/weblayer/public/navigation_controller.h
+++ b/chromium/weblayer/public/navigation_controller.h
@@ -60,6 +60,11 @@ class NavigationController {
// Gets the page title of the given entry in the back/forward list, or an
// empty string if there is no navigation entry at that index.
virtual std::string GetNavigationEntryTitle(int index) = 0;
+
+ // Returns whether this entry will be skipped on a call to GoBack() or
+ // GoForward(). This will be true for navigations that were done without a
+ // user gesture, including both client side redirects and history.pushState.
+ virtual bool IsNavigationEntrySkippable(int index) = 0;
};
} // namespace weblayer
diff --git a/chromium/weblayer/public/navigation_observer.h b/chromium/weblayer/public/navigation_observer.h
index 6b0d2dda9eb..86567cb5255 100644
--- a/chromium/weblayer/public/navigation_observer.h
+++ b/chromium/weblayer/public/navigation_observer.h
@@ -5,6 +5,8 @@
#ifndef WEBLAYER_PUBLIC_NAVIGATION_OBSERVER_H_
#define WEBLAYER_PUBLIC_NAVIGATION_OBSERVER_H_
+class GURL;
+
namespace weblayer {
class Navigation;
@@ -95,6 +97,11 @@ class NavigationObserver {
// This is fired after each navigation has completed to indicate that the
// first paint after a non-empty layout has finished.
virtual void OnFirstContentfulPaint() {}
+
+ // Called after each navigation to indicate that the old page is no longer
+ // being rendered. Note this is not ordered with respect to
+ // OnFirstContentfulPaint.
+ virtual void OnOldPageNoLongerRendered(const GURL& url) {}
};
} // namespace weblayer
diff --git a/chromium/weblayer/public/new_tab_delegate.h b/chromium/weblayer/public/new_tab_delegate.h
index 2d131444df1..27291bf1b99 100644
--- a/chromium/weblayer/public/new_tab_delegate.h
+++ b/chromium/weblayer/public/new_tab_delegate.h
@@ -33,7 +33,9 @@ enum class NewTabType {
// in web terms, a new popup/window (and random other things).
class NewTabDelegate {
public:
- virtual void OnNewTab(std::unique_ptr<Tab> new_tab, NewTabType type) = 0;
+ // Called when a new tab is created by the browser. |new_tab| is owned by the
+ // browser.
+ virtual void OnNewTab(Tab* new_tab, NewTabType type) = 0;
// The page has requested a tab that was created by way of OnNewTab() to be
// closed. This is sent to the NewTabDelegate set on the page created by way
diff --git a/chromium/weblayer/public/profile.h b/chromium/weblayer/public/profile.h
index f878ed679c9..48f49c52758 100644
--- a/chromium/weblayer/public/profile.h
+++ b/chromium/weblayer/public/profile.h
@@ -5,9 +5,13 @@
#ifndef WEBLAYER_PUBLIC_PROFILE_H_
#define WEBLAYER_PUBLIC_PROFILE_H_
-#include <algorithm>
+#include <memory>
#include <string>
+#include "base/callback_forward.h"
+#include "base/containers/flat_set.h"
+#include "base/time/time.h"
+
namespace base {
class FilePath;
}
@@ -23,8 +27,12 @@ enum class BrowsingDataType {
CACHE = 1,
};
+// Used for setting/getting profile related settings.
enum class SettingType {
BASIC_SAFE_BROWSING_ENABLED = 0,
+ UKM_ENABLED = 1,
+ EXTENDED_REPORTING_SAFE_BROWSING_ENABLED = 2,
+ REAL_TIME_SAFE_BROWSING_ENABLED = 3,
};
class Profile {
@@ -61,11 +69,35 @@ class Profile {
// Gets the cookie manager for this profile.
virtual CookieManager* GetCookieManager() = 0;
+ // Asynchronously fetches the set of known Browser persistence-ids. See
+ // Browser::PersistenceInfo for more details on persistence-ids.
+ virtual void GetBrowserPersistenceIds(
+ base::OnceCallback<void(base::flat_set<std::string>)> callback) = 0;
+
+ // Asynchronously removes the storage associated with the set of
+ // Browser persistence-ids. This ignores ids actively in use. |done_callback|
+ // is run with the result of the operation (on the main thread). A value of
+ // true means all files were removed. A value of false indicates at least one
+ // of the files could not be removed.
+ virtual void RemoveBrowserPersistenceStorage(
+ base::OnceCallback<void(bool)> done_callback,
+ base::flat_set<std::string> ids) = 0;
+
// Set the boolean value of the given setting type.
virtual void SetBooleanSetting(SettingType type, bool value) = 0;
// Get the boolean value of the given setting type.
virtual bool GetBooleanSetting(SettingType type) = 0;
+
+ // For cross-origin navigations, the implementation may leverage a separate OS
+ // process for stronger isolation. If an embedder knows that a cross-origin
+ // navigation is likely starting soon, they can call this method as a hint to
+ // the implementation to start a fresh OS process. A subsequent navigation may
+ // use this preinitialized process, improving performance. It is safe to call
+ // this multiple times or when it is not certain that the spare renderer will
+ // be used, although calling this too eagerly may reduce performance as
+ // unnecessary processes are created.
+ virtual void PrepareForPossibleCrossOriginNavigation() = 0;
};
} // namespace weblayer
diff --git a/chromium/weblayer/public/tab.h b/chromium/weblayer/public/tab.h
index eeec5ff218a..ccf25ff7fd6 100644
--- a/chromium/weblayer/public/tab.h
+++ b/chromium/weblayer/public/tab.h
@@ -6,7 +6,9 @@
#define WEBLAYER_PUBLIC_TAB_H_
#include <algorithm>
+#include <map>
#include <string>
+#include <vector>
#include "base/callback_forward.h"
#include "base/strings/string16.h"
@@ -27,19 +29,13 @@ class ErrorPageDelegate;
class FullscreenDelegate;
class NavigationController;
class NewTabDelegate;
-class Profile;
class TabObserver;
+class WebMessageHostFactory;
// Represents a tab that is navigable.
class Tab {
public:
- static std::unique_ptr<Tab> Create(Profile* profile);
-
-#if defined(OS_ANDROID)
- static Tab* GetLastTabForTesting();
-#endif
-
- virtual ~Tab() {}
+ virtual ~Tab() = default;
// Sets the ErrorPageDelegate. If none is set, a default action will be taken
// for any given interaction with an error page.
@@ -75,6 +71,40 @@ class Tab {
// Returns the tab's guid.
virtual const std::string& GetGuid() = 0;
+ // Allows the embedder to get and set arbitrary data on the tab. This will be
+ // saved and restored with the browser, so it is important to keep this data
+ // as small as possible.
+ virtual void SetData(const std::map<std::string, std::string>& data) = 0;
+ virtual const std::map<std::string, std::string>& GetData() = 0;
+
+ // Adds a new WebMessageHostFactory. For any urls that match
+ // |allowed_origin_rules| a JS object is registered using the name
+ // |js_object_name| (in the global namespace). Script may use the object to
+ // send and receive messages and is available at page load time.
+ //
+ // The page is responsible for initiating the connection. That is,
+ // WebMessageHostFactory::CreateHost() is called once the page posts a
+ // message to the JS object.
+ //
+ // |allowed_origin_rules| is a set of rules used to determine which pages
+ // this applies to. '*' may be used to match anything. If not '*' the format
+ // is 'scheme://host:port':
+ // . scheme: The scheme, which can not be empty or contain '*'.
+ // . host: The host to match against. Can not contain '/' and may start with
+ // '*.' to match against a specific subdomain.
+ // . port (optional): matches a specific port.
+ //
+ // Returns an empty string on success. On failure, the return string gives
+ // an error message.
+ virtual base::string16 AddWebMessageHostFactory(
+ std::unique_ptr<WebMessageHostFactory> factory,
+ const base::string16& js_object_name,
+ const std::vector<std::string>& allowed_origin_rules) = 0;
+
+ // Removes the WebMessageHostFactory registered under |js_object_name|.
+ virtual void RemoveWebMessageHostFactory(
+ const base::string16& js_object_name) = 0;
+
#if !defined(OS_ANDROID)
// TODO: this isn't a stable API, so use it now for expediency in the C++ API,
// but if we ever want to have backward or forward compatibility in C++ this