diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/weblayer/public/java | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-chromium-85-based.tar.gz |
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/weblayer/public/java')
24 files changed, 940 insertions, 27 deletions
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() { + * @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> |