summaryrefslogtreecommitdiff
path: root/chromium/weblayer
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2021-03-12 09:13:00 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2021-03-16 09:58:26 +0000
commit03561cae90f1d99b5c54b1ef3be69f10e882b25e (patch)
treecc5f0958e823c044e7ae51cc0117fe51432abe5e /chromium/weblayer
parentfa98118a45f7e169f8846086dc2c22c49a8ba310 (diff)
downloadqtwebengine-chromium-03561cae90f1d99b5c54b1ef3be69f10e882b25e.tar.gz
BASELINE: Update Chromium to 88.0.4324.208
Change-Id: I3ae87d23e4eff4b4a469685658740a213600c667 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/weblayer')
-rw-r--r--chromium/weblayer/BUILD.gn45
-rw-r--r--chromium/weblayer/DIR_METADATA12
-rw-r--r--chromium/weblayer/OWNERS3
-rw-r--r--chromium/weblayer/README.md29
-rw-r--r--chromium/weblayer/app/content_main_delegate_impl.cc8
-rw-r--r--chromium/weblayer/app/main.cc2
-rw-r--r--chromium/weblayer/browser/DEPS6
-rw-r--r--chromium/weblayer/browser/android/javatests/BUILD.gn11
-rwxr-xr-xchromium/weblayer/browser/android/javatests/skew/build_weblayer_instrumentation_test_cipd_pkg.py13
-rw-r--r--chromium/weblayer/browser/android/javatests/skew/mb_config.pyl34
-rwxr-xr-xchromium/weblayer/browser/android/javatests/weblayer_instrumentation_test_versions.py2
-rw-r--r--chromium/weblayer/browser/android/metrics/metrics_browsertest.cc28
-rw-r--r--chromium/weblayer/browser/android/metrics/metrics_test_helper.cc9
-rw-r--r--chromium/weblayer/browser/android/metrics/metrics_test_helper.h16
-rw-r--r--chromium/weblayer/browser/android/metrics/ukm_browsertest.cc5
-rw-r--r--chromium/weblayer/browser/android/metrics/weblayer_metrics_service_client.cc61
-rw-r--r--chromium/weblayer/browser/android/metrics/weblayer_metrics_service_client.h18
-rw-r--r--chromium/weblayer/browser/android/resource_mapper.cc1
-rw-r--r--chromium/weblayer/browser/background_sync/background_sync_browsertest.cc180
-rw-r--r--chromium/weblayer/browser/background_sync/background_sync_controller_factory.cc54
-rw-r--r--chromium/weblayer/browser/background_sync/background_sync_controller_factory.h47
-rw-r--r--chromium/weblayer/browser/background_sync/background_sync_delegate_impl.cc97
-rw-r--r--chromium/weblayer/browser/background_sync/background_sync_delegate_impl.h49
-rw-r--r--chromium/weblayer/browser/browser_context_impl.cc4
-rw-r--r--chromium/weblayer/browser/browser_impl.cc43
-rw-r--r--chromium/weblayer/browser/browser_list_observer.h2
-rw-r--r--chromium/weblayer/browser/browser_main_parts_impl.cc61
-rw-r--r--chromium/weblayer/browser/client_hints_browsertest.cc4
-rw-r--r--chromium/weblayer/browser/content_browser_client_impl.cc44
-rw-r--r--chromium/weblayer/browser/content_browser_client_impl.h3
-rw-r--r--chromium/weblayer/browser/controls_visibility_reason.h4
-rw-r--r--chromium/weblayer/browser/cookie_manager_browsertest.cc2
-rw-r--r--chromium/weblayer/browser/default_search_engine.cc5
-rw-r--r--chromium/weblayer/browser/default_search_engine_browsertest.cc31
-rw-r--r--chromium/weblayer/browser/download_browsertest.cc2
-rw-r--r--chromium/weblayer/browser/errorpage_browsertest.cc28
-rw-r--r--chromium/weblayer/browser/favicon/favicon_backend_wrapper.cc11
-rw-r--r--chromium/weblayer/browser/favicon/favicon_backend_wrapper.h8
-rw-r--r--chromium/weblayer/browser/favicon/favicon_callback_proxy.cc2
-rw-r--r--chromium/weblayer/browser/favicon/favicon_service_impl.cc15
-rw-r--r--chromium/weblayer/browser/favicon/favicon_service_impl.h10
-rw-r--r--chromium/weblayer/browser/favicon/favicon_service_impl_factory.cc16
-rw-r--r--chromium/weblayer/browser/feature_list_creator.cc5
-rw-r--r--chromium/weblayer/browser/java/AndroidManifest_monochrome.xml15
-rw-r--r--chromium/weblayer/browser/java/BUILD.gn34
-rw-r--r--chromium/weblayer/browser/java/DEPS1
-rw-r--r--chromium/weblayer/browser/java/ResourceId.template1
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/ActionModeCallback.java53
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserControlsContainerView.java13
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java82
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserViewController.java6
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java10
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/CookieManagerImpl.java11
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/CrashReporterControllerImpl.java8
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/FaviconCallbackProxy.java1
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/MojoInterfaceRegistrar.java15
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/NavigationControllerImpl.java38
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/NavigationImpl.java10
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/PageInfoControllerDelegateImpl.java7
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java165
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/TranslateCompactInfoBar.java59
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/UrlBarControllerImpl.java47
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java88
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/WebMessageReplyProxyImpl.java16
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ActionModeItemType.java17
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBrowser.aidl3
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBrowserClient.aidl4
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IContextMenuParams.aidl11
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigation.aidl3
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigationControllerClient.aidl4
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IProfileClient.aidl2
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITab.aidl7
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITabClient.aidl10
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayer.aidl7
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayerClient.aidl8
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/LoadError.java5
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/RemoteMediaServiceConstants.java16
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/UrlBarOptionsKeys.java5
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/WebLayerVersionConstants.java2
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouteDialogFragmentImpl.java11
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouterClientImpl.java112
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionManager.java59
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionNotificationHelper.java55
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/payments/OWNERS5
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestFactory.java112
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestService.java57
-rw-r--r--chromium/weblayer/browser/java/org/chromium/weblayer_private/test_interfaces/ITestWebLayer.aidl19
-rw-r--r--chromium/weblayer/browser/java/res/drawable-hdpi/amp_icon.pngbin0 -> 405 bytes
-rw-r--r--chromium/weblayer/browser/java/res/drawable-mdpi/amp_icon.pngbin0 -> 306 bytes
-rw-r--r--chromium/weblayer/browser/java/res/drawable-xhdpi/amp_icon.pngbin0 -> 492 bytes
-rw-r--r--chromium/weblayer/browser/java/res/drawable-xxhdpi/amp_icon.pngbin0 -> 693 bytes
-rw-r--r--chromium/weblayer/browser/java/res/drawable-xxxhdpi/amp_icon.pngbin0 -> 886 bytes
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_af.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_am.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_ar.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_as.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_az.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_be.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_bg.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_bn.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_bs.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_ca.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_cs.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_da.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_de.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_el.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_en-GB.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_es-419.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_es.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_et.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_eu.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_fa.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_fi.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_fil.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_fr-CA.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_fr.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_gl.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_gu.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_hi.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_hr.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_hu.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_hy.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_id.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_is.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_it.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_iw.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_ja.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_ka.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_kk.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_km.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_kn.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_ko.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_ky.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_lo.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_lt.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_lv.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_mk.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_ml.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_mn.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_mr.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_ms.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_my.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_ne.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_nl.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_no.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_or.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_pa.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_pl.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_pt-BR.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_pt-PT.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_ro.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_ru.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_si.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_sk.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_sl.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_sq.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_sr-Latn.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_sr.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_sv.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_sw.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_ta.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_te.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_th.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_tr.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_uk.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_ur.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_uz.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_vi.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_zh-CN.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_zh-HK.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_zh-TW.xtb1
-rw-r--r--chromium/weblayer/browser/java/translations/weblayer_strings_zu.xtb1
-rw-r--r--chromium/weblayer/browser/java/weblayer_strings.grd3
-rw-r--r--chromium/weblayer/browser/java/weblayer_strings_grd/IDS_AMP_PUBLISHER_URL.png.sha11
-rw-r--r--chromium/weblayer/browser/media/media_router_factory.cc7
-rw-r--r--chromium/weblayer/browser/media/media_router_factory.h3
-rw-r--r--chromium/weblayer/browser/navigation_browsertest.cc33
-rw-r--r--chromium/weblayer/browser/navigation_controller_impl.cc89
-rw-r--r--chromium/weblayer/browser/navigation_controller_impl.h15
-rw-r--r--chromium/weblayer/browser/navigation_entry_data.cc47
-rw-r--r--chromium/weblayer/browser/navigation_entry_data.h63
-rw-r--r--chromium/weblayer/browser/navigation_impl.cc24
-rw-r--r--chromium/weblayer/browser/navigation_impl.h20
-rw-r--r--chromium/weblayer/browser/new_tab_delegate_browsertest.cc58
-rw-r--r--chromium/weblayer/browser/no_state_prefetch/no_state_prefetch_browsertest.cc25
-rw-r--r--chromium/weblayer/browser/no_state_prefetch/prerender_controller_impl.cc4
-rw-r--r--chromium/weblayer/browser/no_state_prefetch/prerender_link_manager_factory.cc4
-rw-r--r--chromium/weblayer/browser/no_state_prefetch/prerender_link_manager_factory.h2
-rw-r--r--chromium/weblayer/browser/no_state_prefetch/prerender_manager_delegate_impl.cc2
-rw-r--r--chromium/weblayer/browser/no_state_prefetch/prerender_manager_delegate_impl.h2
-rw-r--r--chromium/weblayer/browser/no_state_prefetch/prerender_manager_factory.cc2
-rw-r--r--chromium/weblayer/browser/no_state_prefetch/prerender_processor_impl_delegate_impl.cc2
-rw-r--r--chromium/weblayer/browser/no_state_prefetch/prerender_processor_impl_delegate_impl.h2
-rw-r--r--chromium/weblayer/browser/no_state_prefetch/prerender_tab_helper.cc2
-rw-r--r--chromium/weblayer/browser/no_state_prefetch/prerender_utils.cc4
-rw-r--r--chromium/weblayer/browser/page_load_metrics_browsertest.cc2
-rw-r--r--chromium/weblayer/browser/page_load_metrics_initialize.cc7
-rw-r--r--chromium/weblayer/browser/page_load_metrics_observer_impl.cc111
-rw-r--r--chromium/weblayer/browser/page_load_metrics_observer_impl.h39
-rw-r--r--chromium/weblayer/browser/page_specific_content_settings_delegate.cc2
-rw-r--r--chromium/weblayer/browser/password_manager_driver_factory.cc1
-rw-r--r--chromium/weblayer/browser/permissions/permission_manager_factory.cc3
-rw-r--r--chromium/weblayer/browser/persistence/browser_persister_browsertest.cc4
-rw-r--r--chromium/weblayer/browser/popup_blocker_browsertest.cc4
-rw-r--r--chromium/weblayer/browser/prefetch_browsertest.cc12
-rw-r--r--chromium/weblayer/browser/profile_browsertest.cc26
-rw-r--r--chromium/weblayer/browser/profile_impl.cc4
-rw-r--r--chromium/weblayer/browser/proxying_url_loader_factory_impl.cc68
-rw-r--r--chromium/weblayer/browser/resources/weblayer_internals/weblayer_internals.html1
-rw-r--r--chromium/weblayer/browser/safe_browsing/safe_browsing_blocking_page.cc5
-rw-r--r--chromium/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc54
-rw-r--r--chromium/weblayer/browser/safe_browsing/safe_browsing_service.cc26
-rw-r--r--chromium/weblayer/browser/safe_browsing/safe_browsing_service.h15
-rw-r--r--chromium/weblayer/browser/safe_browsing/url_checker_delegate_impl.cc2
-rw-r--r--chromium/weblayer/browser/signin_url_loader_throttle.cc4
-rw-r--r--chromium/weblayer/browser/subresource_filter_browsertest.cc36
-rw-r--r--chromium/weblayer/browser/tab_impl.cc122
-rw-r--r--chromium/weblayer/browser/tab_impl.h9
-rw-r--r--chromium/weblayer/browser/translate_client_impl.cc5
-rw-r--r--chromium/weblayer/browser/translate_client_impl.h1
-rw-r--r--chromium/weblayer/browser/translate_compact_infobar.cc7
-rw-r--r--chromium/weblayer/browser/translate_compact_infobar.h2
-rw-r--r--chromium/weblayer/browser/ukm_page_load_metrics_observer.cc41
-rw-r--r--chromium/weblayer/browser/ukm_page_load_metrics_observer.h35
-rw-r--r--chromium/weblayer/browser/url_bar/page_info_browsertest.cc3
-rw-r--r--chromium/weblayer/browser/url_bar/trusted_cdn_observer.cc36
-rw-r--r--chromium/weblayer/browser/url_bar/trusted_cdn_observer.h39
-rw-r--r--chromium/weblayer/browser/url_bar/url_bar_controller_impl.cc16
-rw-r--r--chromium/weblayer/browser/url_bar/url_bar_controller_impl.h1
-rw-r--r--chromium/weblayer/browser/weblayer_browser_interface_binders.cc14
-rw-r--r--chromium/weblayer/browser/weblayer_field_trials.h1
-rw-r--r--chromium/weblayer/browser/webrtc/media_stream_manager.cc13
-rw-r--r--chromium/weblayer/common/content_client_impl.cc9
-rw-r--r--chromium/weblayer/common/content_client_impl.h1
-rw-r--r--chromium/weblayer/common/features.cc5
-rw-r--r--chromium/weblayer/common/features.h2
-rw-r--r--chromium/weblayer/public/common/switches.cc3
-rw-r--r--chromium/weblayer/public/java/AndroidManifest.xml7
-rw-r--r--chromium/weblayer/public/java/BUILD.gn5
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/ActionModeCallback.java19
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/ActionModeItemType.java17
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/Browser.java75
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/BrowserControlsOffsetCallback.java39
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/BrowserFragment.java21
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/ContextMenuParams.java38
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/CrashReporterCallback.java2
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/LoadError.java10
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/MediaPlaybackBaseService.java101
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/MediaRouteDialogFragment.java2
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/MediaSessionService.java61
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/NavigateParams.java7
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/Navigation.java33
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/NavigationCallback.java26
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/NavigationController.java19
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/Profile.java6
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/RemoteMediaService.java51
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/ScrollOffsetCallback.java7
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/Tab.java154
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/UrlBarOptions.java9
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/WebLayer.java63
-rw-r--r--chromium/weblayer/public/java/org/chromium/weblayer/WebViewCompatibilityHelper.java5
-rw-r--r--chromium/weblayer/public/java/res/values/ids.xml2
-rw-r--r--chromium/weblayer/public/javatestutil/org/chromium/weblayer/TestWebLayer.java25
-rw-r--r--chromium/weblayer/public/navigation.h8
-rw-r--r--chromium/weblayer/public/navigation_controller.h1
-rw-r--r--chromium/weblayer/public/navigation_observer.h22
-rw-r--r--chromium/weblayer/public/tab.h4
-rw-r--r--chromium/weblayer/renderer/DEPS4
-rw-r--r--chromium/weblayer/renderer/content_renderer_client_impl.cc22
-rw-r--r--chromium/weblayer/renderer/content_renderer_client_impl.h1
-rw-r--r--chromium/weblayer/renderer/url_loader_throttle_provider.cc2
-rw-r--r--chromium/weblayer/renderer/weblayer_render_frame_observer.cc2
-rw-r--r--chromium/weblayer/shell/BUILD.gn13
-rw-r--r--chromium/weblayer/shell/android/BUILD.gn20
-rw-r--r--chromium/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_browsertests_apk/WebLayerBrowserTestsActivity.java11
-rw-r--r--chromium/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_private/MetricsTestHelper.java26
-rw-r--r--chromium/weblayer/shell/android/shell_apk/AndroidManifest.xml27
-rw-r--r--chromium/weblayer/shell/android/shell_apk/DEPS1
-rw-r--r--chromium/weblayer/shell/android/shell_apk/res/menu/app_menu.xml4
-rw-r--r--chromium/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/InstrumentationActivity.java30
-rw-r--r--chromium/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/TelemetryActivity.java30
-rw-r--r--chromium/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java177
-rw-r--r--chromium/weblayer/shell/browser/shell_views.cc31
-rw-r--r--chromium/weblayer/test/BUILD.gn13
-rw-r--r--chromium/weblayer/weblayer_module.gni9
-rw-r--r--chromium/weblayer/weblayer_resources.grd2
286 files changed, 4005 insertions, 788 deletions
diff --git a/chromium/weblayer/BUILD.gn b/chromium/weblayer/BUILD.gn
index 3a68602cc43..ecf8ce7c3eb 100644
--- a/chromium/weblayer/BUILD.gn
+++ b/chromium/weblayer/BUILD.gn
@@ -28,13 +28,6 @@ if (is_android) {
import("//v8/gni/v8.gni")
}
-# This file depends on the legacy global sources assignment filter. It should
-# be converted to check target platform before assigning source files to the
-# sources variable. Remove this import and set_sources_assignment_filter call
-# when the file has been converted. See https://crbug.com/1018739 for details.
-import("//build/config/deprecated_default_sources_assignment_filter.gni")
-set_sources_assignment_filter(deprecated_default_sources_assignment_filter)
-
source_set("android_descriptors") {
sources = [ "browser/android_descriptors.h" ]
public_deps = [ "//content/public/common:content_descriptors" ]
@@ -146,6 +139,10 @@ source_set("weblayer_lib_base") {
"app/main.cc",
"browser/autofill_client_impl.cc",
"browser/autofill_client_impl.h",
+ "browser/background_sync/background_sync_controller_factory.cc",
+ "browser/background_sync/background_sync_controller_factory.h",
+ "browser/background_sync/background_sync_delegate_impl.cc",
+ "browser/background_sync/background_sync_delegate_impl.h",
"browser/browser_context_impl.cc",
"browser/browser_context_impl.h",
"browser/browser_impl.cc",
@@ -198,16 +195,14 @@ source_set("weblayer_lib_base") {
"browser/host_content_settings_map_factory.h",
"browser/i18n_util.cc",
"browser/i18n_util.h",
- "browser/infobar_container_android.cc",
- "browser/infobar_container_android.h",
"browser/insecure_form_controller_client.cc",
"browser/insecure_form_controller_client.h",
- "browser/javascript_tab_modal_dialog_manager_delegate_android.cc",
- "browser/javascript_tab_modal_dialog_manager_delegate_android.h",
"browser/js_communication/web_message_host_factory_wrapper.cc",
"browser/js_communication/web_message_host_factory_wrapper.h",
"browser/navigation_controller_impl.cc",
"browser/navigation_controller_impl.h",
+ "browser/navigation_entry_data.cc",
+ "browser/navigation_entry_data.h",
"browser/navigation_error_navigation_throttle.cc",
"browser/navigation_error_navigation_throttle.h",
"browser/navigation_impl.cc",
@@ -230,6 +225,8 @@ source_set("weblayer_lib_base") {
"browser/no_state_prefetch/prerender_utils.h",
"browser/page_load_metrics_initialize.cc",
"browser/page_load_metrics_initialize.h",
+ "browser/page_load_metrics_observer_impl.cc",
+ "browser/page_load_metrics_observer_impl.h",
"browser/page_specific_content_settings_delegate.cc",
"browser/page_specific_content_settings_delegate.h",
"browser/password_manager_driver_factory.cc",
@@ -272,8 +269,6 @@ source_set("weblayer_lib_base") {
"browser/translate_client_impl.h",
"browser/translate_ranker_factory.cc",
"browser/translate_ranker_factory.h",
- "browser/ukm_page_load_metrics_observer.cc",
- "browser/ukm_page_load_metrics_observer.h",
"browser/url_bar/autocomplete_scheme_classifier_impl.cc",
"browser/url_bar/autocomplete_scheme_classifier_impl.h",
"browser/url_bar/page_info_delegate_impl.cc",
@@ -369,6 +364,7 @@ source_set("weblayer_lib_base") {
"//components/autofill/content/renderer",
"//components/autofill/core/browser",
"//components/autofill/core/common",
+ "//components/background_sync",
"//components/base32",
"//components/blocked_content",
"//components/browsing_data/content",
@@ -383,6 +379,8 @@ source_set("weblayer_lib_base") {
"//components/crash/content/browser",
"//components/crash/core/app",
"//components/crash/core/common",
+ "//components/download/content/factory",
+ "//components/download/content/public",
"//components/embedder_support",
"//components/embedder_support/origin_trials",
"//components/error_page/common",
@@ -400,6 +398,10 @@ source_set("weblayer_lib_base") {
"//components/metrics",
"//components/metrics:content",
"//components/network_time",
+ "//components/no_state_prefetch/browser",
+ "//components/no_state_prefetch/common",
+ "//components/no_state_prefetch/common:mojo_bindings",
+ "//components/no_state_prefetch/renderer",
"//components/omnibox/browser:location_bar",
"//components/page_info",
"//components/page_load_metrics/browser",
@@ -409,10 +411,6 @@ source_set("weblayer_lib_base") {
"//components/policy/core/browser",
"//components/pref_registry:pref_registry",
"//components/prefs",
- "//components/prerender/browser",
- "//components/prerender/common",
- "//components/prerender/common:mojo_bindings",
- "//components/prerender/renderer",
"//components/safe_browsing/content/common:interfaces",
"//components/safe_browsing/content/renderer:throttles",
"//components/safe_browsing/core:features",
@@ -544,8 +542,12 @@ source_set("weblayer_lib_base") {
"browser/google_accounts_callback_proxy.h",
"browser/http_auth_handler_impl.cc",
"browser/http_auth_handler_impl.h",
+ "browser/infobar_container_android.cc",
+ "browser/infobar_container_android.h",
"browser/infobar_service.cc",
"browser/infobar_service.h",
+ "browser/javascript_tab_modal_dialog_manager_delegate_android.cc",
+ "browser/javascript_tab_modal_dialog_manager_delegate_android.h",
"browser/js_communication/web_message_host_factory_proxy.cc",
"browser/js_communication/web_message_host_factory_proxy.h",
"browser/js_communication/web_message_reply_proxy_impl.cc",
@@ -580,6 +582,8 @@ source_set("weblayer_lib_base") {
"browser/tts_environment_android_impl.h",
"browser/url_bar/page_info_client_impl.cc",
"browser/url_bar/page_info_client_impl.h",
+ "browser/url_bar/trusted_cdn_observer.cc",
+ "browser/url_bar/trusted_cdn_observer.h",
"browser/verdict_cache_manager_factory.cc",
"browser/verdict_cache_manager_factory.h",
"browser/weblayer_factory_impl_android.cc",
@@ -613,6 +617,7 @@ source_set("weblayer_lib_base") {
"//components/embedder_support/android:web_contents_delegate",
"//components/embedder_support/android/metrics",
"//components/external_intents/android",
+ "//components/favicon/android",
"//components/infobars/android",
"//components/infobars/content",
"//components/javascript_dialogs",
@@ -622,6 +627,7 @@ source_set("weblayer_lib_base") {
"//components/minidump_uploader",
"//components/navigation_interception",
"//components/page_info/android",
+ "//components/payments/content/android",
"//components/permissions/android:native",
"//components/resources:android_resources",
"//components/safe_browsing/android:remote_database_manager",
@@ -795,15 +801,12 @@ if (is_android) {
grit("resources") {
source = "weblayer_resources.grd"
+ use_brotli = true
outputs = [
"grit/weblayer_resources.h",
"weblayer_resources.pak",
]
- grit_flags = [
- "-E",
- "root_gen_dir=" + rebase_path(root_gen_dir, root_build_dir),
- ]
deps = [ "//weblayer/browser/webui:mojo_bindings_js" ]
}
# TODO(jam): move weblayer_shell_resources_grit and copy_shell_resources here in
diff --git a/chromium/weblayer/DIR_METADATA b/chromium/weblayer/DIR_METADATA
new file mode 100644
index 00000000000..bb8ad53a7c1
--- /dev/null
+++ b/chromium/weblayer/DIR_METADATA
@@ -0,0 +1,12 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+ component: "Internals>WebLayer"
+}
+team_email: "weblayer-dev@chromium.org" \ No newline at end of file
diff --git a/chromium/weblayer/OWNERS b/chromium/weblayer/OWNERS
index d5ecf5efe0c..3af6880bfa5 100644
--- a/chromium/weblayer/OWNERS
+++ b/chromium/weblayer/OWNERS
@@ -8,6 +8,3 @@ nator@chromium.org
sky@chromium.org
timvolodine@chromium.org
tobiasjs@chromium.org
-
-# TEAM: weblayer-dev@chromium.org
-# COMPONENT: Internals>WebLayer
diff --git a/chromium/weblayer/README.md b/chromium/weblayer/README.md
index 072ccdfc69d..387351883c5 100644
--- a/chromium/weblayer/README.md
+++ b/chromium/weblayer/README.md
@@ -56,40 +56,69 @@ instructions. Otherwise follow the
To run the sample app:
+```
$ autoninja -C out/Default run_weblayer_shell
$ out/Default/bin/run_weblayer_shell
+```
To run instrumentation tests:
+```
$ autoninja -C out/Default weblayer_instrumentation_test_apk
$ out/Default/bin/run_weblayer_instrumentation_test_apk
+```
Note: this may not work on some versions of Android. If you see an error setting
the WebView provider when running instrumentation tests, try running the tests
using the WebLayer support APK which uses a different loading path:
+```
$ autoninja -C out/Default weblayer_support_instrumentation_test_apk
$ out/Default/bin/run_weblayer_support_instrumentation_test_apk
+```
The test script will build and install all necessary APKs.
+## Running Skew Tests
+
+Make sure you have the following gn arg:
+
+```
+system_webview_package_name = "com.google.android.webview"
+```
+
+The following tests the latest client library against M80:
+
+```
+ $ autoninja -C out/Default weblayer_instrumentation_test_versions_apk
+ $ cipd install --root /tmp/M80 chromium/testing/weblayer-x86 m80
+ $ out/Default/bin/run_weblayer_instrumentation_test_versions_apk \
+ --test-runner-outdir out/Default \
+ --client-outdir out/Default \
+ --implementation-outdir /tmp/M80/out/Release
+```
+
## Running WPT
To run WPT on android against weblayer do the following:
+```
$ export WPT_TEST= test you want to run, relative to wpt directory.
$ autoninja -C out/Default run_weblayer_shell weblayer_shell_wpt
$ out/Default/bin/run_weblayer_shell
$ testing/scripts/run_android_wpt.py --webdriver-binary=out/Default/clang_x64/chromedriver --product android_weblayer --isolated-script-test-output /tmp/weblayer_out.json --include ./third_party/blink/web_tests/external/wpt/$WPT_TEST
+```
`run_android_wpt.py` does not install `weblayer-shell`, you need to do that
yourself (executing `run_weblayer_shell` will do that).
To run against clank:
+```
$ autoninja -C out/Default monochrome_public_apk
$ out/Default/bin/monochrome_public_apk install
$ testing/scripts/run_android_wpt.py --webdriver-binary=out/Default/clang_x64/chromedriver --product chrome_android --package-name org.chromium.chrome --isolated-script-test-output /tmp/weblayer_out.json --include ./third_party/blink/web_tests/external/wpt/$WPT_TEST
+```
Passing in `-vvvv` may be useful if you want to see loads of information about
test execution.
diff --git a/chromium/weblayer/app/content_main_delegate_impl.cc b/chromium/weblayer/app/content_main_delegate_impl.cc
index f05bcb0adec..11bfb119816 100644
--- a/chromium/weblayer/app/content_main_delegate_impl.cc
+++ b/chromium/weblayer/app/content_main_delegate_impl.cc
@@ -144,10 +144,6 @@ bool ContentMainDelegateImpl::BasicStartupComplete(int* exit_code) {
// TODO(crbug.com/1025610): make notifications work with WebLayer.
// This also turns off Push messaging.
cl->AppendSwitch(::switches::kDisableNotifications);
- // TODO(crbug.com/1057099): make presentation-api work with WebLayer.
- cl->AppendSwitch(::switches::kDisablePresentationAPI);
- // TODO(crbug.com/1057100): make remote-playback-api work with WebLayer.
- cl->AppendSwitch(::switches::kDisableRemotePlaybackAPI);
std::vector<base::Feature> enabled_features = {};
std::vector<base::Feature> disabled_features = {
@@ -177,8 +173,8 @@ bool ContentMainDelegateImpl::BasicStartupComplete(int* exit_code) {
::features::kDisableDeJelly,
::features::kDynamicColorGamut,
#else
- // TODO(crbug.com/1131021): Support SMS Receiver on WebLayer.
- ::features::kSmsReceiver,
+ // TODO(crbug.com/1131021): Support WebOTP Service on WebLayer.
+ ::features::kWebOTP,
#endif
};
diff --git a/chromium/weblayer/app/main.cc b/chromium/weblayer/app/main.cc
index 5eee96132ed..9bb74da3359 100644
--- a/chromium/weblayer/app/main.cc
+++ b/chromium/weblayer/app/main.cc
@@ -40,7 +40,7 @@ int Main(MainParams params
#if defined(WIN_CONSOLE_APP)
HINSTANCE instance = GetModuleHandle(nullptr);
#endif
- sandbox::SandboxInterfaceInfo sandbox_info = {0};
+ sandbox::SandboxInterfaceInfo sandbox_info = {nullptr};
content::InitializeSandboxInfo(&sandbox_info);
content_params.instance = instance;
content_params.sandbox_info = &sandbox_info;
diff --git a/chromium/weblayer/browser/DEPS b/chromium/weblayer/browser/DEPS
index fe3b8f3b94e..8945c959e91 100644
--- a/chromium/weblayer/browser/DEPS
+++ b/chromium/weblayer/browser/DEPS
@@ -5,6 +5,7 @@ include_rules = [
"+components/autofill/content/common",
"+components/autofill/core/browser",
"+components/autofill/core/common",
+ "+components/background_sync",
"+components/base32",
"+components/blocked_content",
"+components/browsing_data/content",
@@ -17,6 +18,7 @@ include_rules = [
"+components/content_settings/core/common",
"+components/crash/content/browser",
"+components/crash/core/common",
+ "+components/download/content/public",
"+components/download/public/common",
"+components/embedder_support",
"+components/error_page/content/browser",
@@ -40,8 +42,8 @@ include_rules = [
"+components/permissions",
"+components/pref_registry",
"+components/prefs",
- "+components/prerender/browser",
- "+components/prerender/common",
+ "+components/no_state_prefetch/browser",
+ "+components/no_state_prefetch/common",
"+components/resources/android",
"+components/safe_browsing/core",
"+components/safe_browsing/core/common",
diff --git a/chromium/weblayer/browser/android/javatests/BUILD.gn b/chromium/weblayer/browser/android/javatests/BUILD.gn
index fccc34b09dc..e2da9b844b8 100644
--- a/chromium/weblayer/browser/android/javatests/BUILD.gn
+++ b/chromium/weblayer/browser/android/javatests/BUILD.gn
@@ -10,6 +10,7 @@ android_library("weblayer_java_tests") {
testonly = true
sources = [
"src/org/chromium/weblayer/test/BrowserFragmentLifecycleTest.java",
+ "src/org/chromium/weblayer/test/BrowserTest.java",
"src/org/chromium/weblayer/test/CookieManagerTest.java",
"src/org/chromium/weblayer/test/CrashReporterTest.java",
"src/org/chromium/weblayer/test/DataClearingTest.java",
@@ -30,6 +31,7 @@ android_library("weblayer_java_tests") {
"src/org/chromium/weblayer/test/OnTabRemovedTabListCallbackImpl.java",
"src/org/chromium/weblayer/test/PrerenderControllerTest.java",
"src/org/chromium/weblayer/test/ProfileTest.java",
+ "src/org/chromium/weblayer/test/RegisterExternalExperimentIdsTest.java",
"src/org/chromium/weblayer/test/RenderingTest.java",
"src/org/chromium/weblayer/test/ScrollOffsetCallbackTest.java",
"src/org/chromium/weblayer/test/SmokeTest.java",
@@ -68,11 +70,13 @@ android_library("weblayer_java_tests") {
android_library("weblayer_private_java_tests") {
testonly = true
sources = [
+ "src/org/chromium/weblayer/test/BrowserControlsOffsetCallbackTest.java",
"src/org/chromium/weblayer/test/BrowserControlsTest.java",
"src/org/chromium/weblayer/test/FullscreenCallbackPrivateTest.java",
"src/org/chromium/weblayer/test/GeolocationTest.java",
"src/org/chromium/weblayer/test/InfoBarTest.java",
"src/org/chromium/weblayer/test/MediaCaptureTest.java",
+ "src/org/chromium/weblayer/test/MediaRouterTest.java",
"src/org/chromium/weblayer/test/NetworkChangeNotifierTest.java",
"src/org/chromium/weblayer/test/PageInfoTest.java",
"src/org/chromium/weblayer/test/PopupTest.java",
@@ -87,6 +91,7 @@ android_library("weblayer_private_java_tests") {
":weblayer_java_test_support",
"//base:base_java",
"//base:base_java_test_support",
+ "//content/public/android:content_java",
"//content/public/test/android:content_java_test_support",
"//net/android:net_java_test_support",
"//third_party/android_deps:android_support_v4_java",
@@ -98,6 +103,7 @@ android_library("weblayer_private_java_tests") {
"//third_party/android_support_test_runner:runner_java",
"//third_party/hamcrest:hamcrest_java",
"//third_party/junit:junit",
+ "//ui/android:ui_java_test_support",
"//weblayer/public/java",
"//weblayer/public/javatestutil:test_java",
"//weblayer/shell/android:weblayer_shell_java",
@@ -195,7 +201,10 @@ weblayer_instrumentation("weblayer_support_instrumentation_test_apk") {
weblayer_instrumentation("weblayer_private_instrumentation_test_apk") {
apk_name = "WebLayerPrivateInstrumentationTest"
apk_under_test = "//weblayer/shell/android:weblayer_shell_apk"
- additional_apks = [ "//weblayer/shell/android:weblayer_support_apk" ]
+ additional_apks = [
+ "//weblayer/shell/android:weblayer_support_apk",
+ "//components/media_router/test/android/media_router_test_support:media_router_test_support_apk",
+ ]
deps = [ ":weblayer_private_java_tests" ]
}
diff --git a/chromium/weblayer/browser/android/javatests/skew/build_weblayer_instrumentation_test_cipd_pkg.py b/chromium/weblayer/browser/android/javatests/skew/build_weblayer_instrumentation_test_cipd_pkg.py
index 0868a5d57fe..c29d3b21555 100755
--- a/chromium/weblayer/browser/android/javatests/skew/build_weblayer_instrumentation_test_cipd_pkg.py
+++ b/chromium/weblayer/browser/android/javatests/skew/build_weblayer_instrumentation_test_cipd_pkg.py
@@ -7,11 +7,12 @@
# Script to build a CIPD package for weblayer_instrumentation_test_apk from
# the current Chromium checkout.
#
-# This should be run from the src directory of a release branch. After the
-# package is built the user should run two cipd commands (printed at the end
-# of script execution) to upload the package to the CIPD server and to update
-# the ref for the corresponding milestone. Once the ref is updated, the version
-# skew test will pick up the new package in successive runs.
+# This should be run from the src directory of a release branch. This will
+# take care of the build, you need not do that yourself. After the package is
+# built run two cipd commands (printed at the end of script execution) to
+# upload the package to the CIPD server and to update the ref for the
+# corresponding milestone. Once the ref is updated, the version skew test will
+# pick up the new package in successive runs.
import argparse
import contextlib
@@ -138,7 +139,7 @@ def main():
print('Use "cipd set-ref chromium/testing/weblayer-x86 --version ' +
'<CIPD instance version> -ref m<milestone>" to update the ref.')
print('The CIPD instance version can be found on the "Instance" line ' +
- 'above after "chromium/testing/weblayer-x86:".')
+ 'after "chromium/testing/weblayer-x86:".')
if __name__ == '__main__':
diff --git a/chromium/weblayer/browser/android/javatests/skew/mb_config.pyl b/chromium/weblayer/browser/android/javatests/skew/mb_config.pyl
index 4ccb34ed67b..bcf334900bb 100644
--- a/chromium/weblayer/browser/android/javatests/skew/mb_config.pyl
+++ b/chromium/weblayer/browser/android/javatests/skew/mb_config.pyl
@@ -13,15 +13,19 @@
# instrumentation tests.
{
'masters': {
- 'dummy.master': {
- 'dummy.builder': 'android_release_bot_minimal_symbols_x86_webview_google',
- },
+ 'dummy.group': {
+ 'dummy.builder.google_webview_pkg_name': 'android_weblayer_with_google_webview_pkg_name',
+ 'dummy.builder.aosp_webview_pkg_name': 'android_weblayer_with_aosp_webview_pkg_name',
+ }
},
'configs': {
- 'android_release_bot_minimal_symbols_x86_webview_google': [
- 'android', 'release_bot', 'minimal_symbols', 'x86',
- 'strip_debug_info', 'webview_google',
+ 'android_weblayer_with_aosp_webview_pkg_name': [
+ 'android_release_bot_minimal_symbols_x86'
+ ],
+
+ 'android_weblayer_with_google_webview_pkg_name': [
+ 'android_release_bot_minimal_symbols_x86_webview_google'
],
},
@@ -36,6 +40,18 @@
'mixins': ['android_without_codecs', 'chrome_with_codecs'],
},
+ # Default webview package name is com.android.webview which
+ # is necessary for skew tests to work on Android M and Anroid 10
+ # x86 builders.
+ 'android_release_bot_minimal_symbols_x86': {
+ 'mixins': ['android', 'release_bot', 'minimal_symbols', 'x86',
+ 'strip_debug_info', 'improved_debugging'],
+ },
+
+ 'android_release_bot_minimal_symbols_x86_webview_google': {
+ 'mixins': ['android_release_bot_minimal_symbols_x86', 'webview_google'],
+ },
+
'android_without_codecs': {
'gn_args': 'target_os="android"',
},
@@ -67,7 +83,7 @@
},
'release_bot': {
- 'mixins': ['release', 'static'],
+ 'mixins': ['release', 'static', 'goma'],
},
'static': {
@@ -85,5 +101,9 @@
'x86': {
'gn_args': 'target_cpu="x86"',
},
+
+ 'improved_debugging': {
+ 'gn_args': 'is_java_debug=true dcheck_always_on=true',
+ },
},
}
diff --git a/chromium/weblayer/browser/android/javatests/weblayer_instrumentation_test_versions.py b/chromium/weblayer/browser/android/javatests/weblayer_instrumentation_test_versions.py
index 87286c153dc..93c6826cbe0 100755
--- a/chromium/weblayer/browser/android/javatests/weblayer_instrumentation_test_versions.py
+++ b/chromium/weblayer/browser/android/javatests/weblayer_instrumentation_test_versions.py
@@ -10,7 +10,7 @@
# Example usage, testing M80 tests and client against master implementation:
# autoninja -C out/Release weblayer_instrumentation_test_versions_apk
# cipd install --root /tmp/M80 chromium/testing/weblayer-x86 m80
-# out/Release/bin/run_weblayer_instrumentation_tests_versions_apk \
+# out/Release/bin/run_weblayer_instrumentation_test_versions_apk \
# --test-runner-outdir out/Release
# --client-outdir /tmp/M80/out/Release
# --implementation-outdir out/Release
diff --git a/chromium/weblayer/browser/android/metrics/metrics_browsertest.cc b/chromium/weblayer/browser/android/metrics/metrics_browsertest.cc
index ec8bff6d7a6..d31ff53ac73 100644
--- a/chromium/weblayer/browser/android/metrics/metrics_browsertest.cc
+++ b/chromium/weblayer/browser/android/metrics/metrics_browsertest.cc
@@ -8,14 +8,16 @@
#include "base/metrics/metrics_hashes.h"
#include "base/metrics/statistics_recorder.h"
#include "base/no_destructor.h"
-#include "base/test/bind_test_util.h"
+#include "base/test/bind.h"
#include "components/metrics/log_decoder.h"
#include "components/metrics/metrics_log_uploader.h"
+#include "components/metrics/metrics_service.h"
#include "components/metrics/metrics_switches.h"
#include "content/public/test/browser_test_utils.h"
#include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h"
#include "weblayer/browser/android/metrics/metrics_test_helper.h"
#include "weblayer/browser/android/metrics/weblayer_metrics_service_client.h"
+#include "weblayer/browser/browser_list.h"
#include "weblayer/browser/profile_impl.h"
#include "weblayer/public/navigation_controller.h"
#include "weblayer/public/profile.h"
@@ -46,7 +48,7 @@ class MetricsBrowserTest : public WebLayerBrowserTest {
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
command_line->AppendSwitch(metrics::switches::kForceEnableMetricsReporting);
- InstallTestGmsBridge(HasUserConsent(),
+ InstallTestGmsBridge(GetConsentType(),
base::BindRepeating(&MetricsBrowserTest::OnLogMetrics,
base::Unretained(this)));
WebLayerMetricsServiceClient::GetInstance()->SetFastStartupForTesting(true);
@@ -80,7 +82,7 @@ class MetricsBrowserTest : public WebLayerBrowserTest {
size_t GetNumLogs() const { return metrics_logs_.size(); }
- virtual bool HasUserConsent() { return true; }
+ virtual ConsentType GetConsentType() { return ConsentType::kConsent; }
private:
std::unique_ptr<Profile> profile_;
@@ -197,7 +199,7 @@ IN_PROC_BROWSER_TEST_F(MetricsBrowserTest, RendererHistograms) {
}
class MetricsBrowserTestWithUserOptOut : public MetricsBrowserTest {
- bool HasUserConsent() override { return false; }
+ ConsentType GetConsentType() override { return ConsentType::kNoConsent; }
};
IN_PROC_BROWSER_TEST_F(MetricsBrowserTestWithUserOptOut, MetricsNotRecorded) {
@@ -205,4 +207,22 @@ IN_PROC_BROWSER_TEST_F(MetricsBrowserTestWithUserOptOut, MetricsNotRecorded) {
ASSERT_EQ(0u, GetNumLogs());
}
+class MetricsBrowserTestWithConfigurableConsent : public MetricsBrowserTest {
+ ConsentType GetConsentType() override { return ConsentType::kDelayConsent; }
+};
+
+IN_PROC_BROWSER_TEST_F(MetricsBrowserTestWithConfigurableConsent,
+ IsInForegroundWhenConsentGiven) {
+ // There should be at least one browser which is resumed. This is the trigger
+ // for whether the MetricsService is considered in the foreground.
+ EXPECT_TRUE(BrowserList::GetInstance()->HasAtLeastOneResumedBrowser());
+ RunConsentCallback(true);
+ // RunConsentCallback() should trigger the MetricsService to start.
+ EXPECT_TRUE(WebLayerMetricsServiceClient::GetInstance()
+ ->GetMetricsServiceIfStarted());
+ EXPECT_TRUE(WebLayerMetricsServiceClient::GetInstance()
+ ->GetMetricsService()
+ ->IsInForegroundForTesting());
+}
+
} // namespace weblayer
diff --git a/chromium/weblayer/browser/android/metrics/metrics_test_helper.cc b/chromium/weblayer/browser/android/metrics/metrics_test_helper.cc
index d41b1eba4f0..02dae4ec835 100644
--- a/chromium/weblayer/browser/android/metrics/metrics_test_helper.cc
+++ b/chromium/weblayer/browser/android/metrics/metrics_test_helper.cc
@@ -31,11 +31,11 @@ ProfileImpl* GetProfileByName(const std::string& name) {
} // namespace
-void InstallTestGmsBridge(bool has_user_consent,
+void InstallTestGmsBridge(ConsentType consent_type,
const OnLogsMetricsCallback on_log_metrics) {
GetOnLogMetricsCallback() = on_log_metrics;
Java_MetricsTestHelper_installTestGmsBridge(
- base::android::AttachCurrentThread(), has_user_consent);
+ base::android::AttachCurrentThread(), static_cast<int>(consent_type));
}
void RemoveTestGmsBridge() {
@@ -44,6 +44,11 @@ void RemoveTestGmsBridge() {
GetOnLogMetricsCallback().Reset();
}
+void RunConsentCallback(bool has_consent) {
+ Java_MetricsTestHelper_runConsentCallback(
+ base::android::AttachCurrentThread(), has_consent);
+}
+
ProfileImpl* CreateProfile(const std::string& name) {
DCHECK(!GetProfileByName(name));
JNIEnv* env = base::android::AttachCurrentThread();
diff --git a/chromium/weblayer/browser/android/metrics/metrics_test_helper.h b/chromium/weblayer/browser/android/metrics/metrics_test_helper.h
index ed398ce24de..2af4af79323 100644
--- a/chromium/weblayer/browser/android/metrics/metrics_test_helper.h
+++ b/chromium/weblayer/browser/android/metrics/metrics_test_helper.h
@@ -18,15 +18,29 @@ class ProfileImpl;
using OnLogsMetricsCallback =
base::RepeatingCallback<void(metrics::ChromeUserMetricsExtension)>;
+// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.weblayer_private
+// GENERATED_JAVA_CLASS_NAME_OVERRIDE: ConsentType
+enum class ConsentType {
+ kConsent,
+ kNoConsent,
+ // If this is supplied to InstallTestGmsBridge(), the callback used to
+ // determine if consent is given is not automatically called. Use
+ // RunConsentCallback() to apply consent.
+ kDelayConsent,
+};
+
// Call this in the SetUp() test harness method to install the test
// GmsBridge and to set the metrics user consent state.
void InstallTestGmsBridge(
- bool has_user_consent,
+ ConsentType consent_type,
const OnLogsMetricsCallback on_log_metrics = OnLogsMetricsCallback());
// Call this in the TearDown() test harness method to remove the GmsBridge.
void RemoveTestGmsBridge();
+// See comment for kDelayConsent.
+void RunConsentCallback(bool has_consent);
+
// See Profile::Create()'s comments for the semantics of |name|.
ProfileImpl* CreateProfile(const std::string& name);
diff --git a/chromium/weblayer/browser/android/metrics/ukm_browsertest.cc b/chromium/weblayer/browser/android/metrics/ukm_browsertest.cc
index 53bd2203807..4c82cdef66c 100644
--- a/chromium/weblayer/browser/android/metrics/ukm_browsertest.cc
+++ b/chromium/weblayer/browser/android/metrics/ukm_browsertest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/test/bind_test_util.h"
+#include "base/test/bind.h"
#include "components/ukm/ukm_test_helper.h"
#include "weblayer/browser/android/metrics/metrics_test_helper.h"
#include "weblayer/browser/android/metrics/weblayer_metrics_service_client.h"
@@ -17,7 +17,8 @@ namespace weblayer {
class UkmBrowserTest : public WebLayerBrowserTest {
public:
void SetUp() override {
- InstallTestGmsBridge(user_consent_);
+ InstallTestGmsBridge(user_consent_ ? ConsentType::kConsent
+ : ConsentType::kNoConsent);
WebLayerBrowserTest::SetUp();
}
diff --git a/chromium/weblayer/browser/android/metrics/weblayer_metrics_service_client.cc b/chromium/weblayer/browser/android/metrics/weblayer_metrics_service_client.cc
index 6b28c6ed7de..cf70359062c 100644
--- a/chromium/weblayer/browser/android/metrics/weblayer_metrics_service_client.cc
+++ b/chromium/weblayer/browser/android/metrics/weblayer_metrics_service_client.cc
@@ -15,11 +15,13 @@
#include "components/metrics/metrics_provider.h"
#include "components/metrics/metrics_service.h"
#include "components/page_load_metrics/browser/metrics_web_contents_observer.h"
+#include "components/ukm/ukm_service.h"
#include "components/variations/variations_ids_provider.h"
#include "components/version_info/android/channel_getter.h"
#include "content/public/browser/browser_context.h"
#include "google_apis/google_api_keys.h"
#include "weblayer/browser/browser_context_impl.h"
+#include "weblayer/browser/browser_list.h"
#include "weblayer/browser/java/jni/MetricsServiceClient_jni.h"
#include "weblayer/browser/system_network_context_manager.h"
#include "weblayer/browser/tab_impl.h"
@@ -80,9 +82,11 @@ WebLayerMetricsServiceClient* WebLayerMetricsServiceClient::GetInstance() {
WebLayerMetricsServiceClient::WebLayerMetricsServiceClient() {
ProfileImpl::AddProfileObserver(this);
+ BrowserList::GetInstance()->AddObserver(this);
}
WebLayerMetricsServiceClient::~WebLayerMetricsServiceClient() {
+ BrowserList::GetInstance()->RemoveObserver(this);
ProfileImpl::RemoveProfileObserver(this);
}
@@ -127,7 +131,7 @@ std::string WebLayerMetricsServiceClient::GetUploadSigningKey() {
return decoded_key;
}
-int WebLayerMetricsServiceClient::GetSampleRatePerMille() {
+int WebLayerMetricsServiceClient::GetSampleRatePerMille() const {
version_info::Channel channel = version_info::android::GetChannel();
if (channel == version_info::Channel::STABLE ||
channel == version_info::Channel::UNKNOWN) {
@@ -141,8 +145,6 @@ void WebLayerMetricsServiceClient::OnMetricsStart() {
std::move(task).Run();
}
post_start_tasks_.clear();
- GetMetricsService()->synthetic_trial_registry()->AddSyntheticTrialObserver(
- variations::VariationsIdsProvider::GetInstance());
}
void WebLayerMetricsServiceClient::OnMetricsNotStarted() {
@@ -161,10 +163,6 @@ void WebLayerMetricsServiceClient::RegisterAdditionalMetricsProviders(
service->RegisterMetricsProvider(std::make_unique<PageLoadMetricsProvider>());
}
-bool WebLayerMetricsServiceClient::IsPersistentHistogramsEnabled() {
- return true;
-}
-
bool WebLayerMetricsServiceClient::IsOffTheRecordSessionActive() {
for (auto* profile : ProfileImpl::GetAllProfiles()) {
if (profile->GetBrowserContext()->IsOffTheRecord())
@@ -180,6 +178,42 @@ WebLayerMetricsServiceClient::GetURLLoaderFactory() {
->GetSharedURLLoaderFactory();
}
+void WebLayerMetricsServiceClient::ApplyConsent(bool user_consent,
+ bool app_consent) {
+ // TODO(https://crbug.com/1155163): update this once consent can be
+ // dynamically changed.
+ // It is expected this function is called only once, and that prior to this
+ // function the metrics service has not been started. The reason the metric
+ // service should not have been started prior to this function is that the
+ // metrics service is only started if consent is given, and this function is
+ // responsible for setting consent.
+ DCHECK(!GetMetricsServiceIfStarted());
+ // UkmService is only created if consent is given.
+ DCHECK(!GetUkmService());
+
+ SetHaveMetricsConsent(user_consent, app_consent);
+ ApplyForegroundStateToServices();
+}
+
+void WebLayerMetricsServiceClient::ApplyForegroundStateToServices() {
+ const bool is_in_foreground =
+ BrowserList::GetInstance()->HasAtLeastOneResumedBrowser();
+ if (auto* metrics_service = WebLayerMetricsServiceClient::GetInstance()
+ ->GetMetricsServiceIfStarted()) {
+ if (is_in_foreground)
+ metrics_service->OnAppEnterForeground();
+ else
+ metrics_service->OnAppEnterBackground();
+ }
+
+ if (auto* ukm_service = GetUkmService()) {
+ if (is_in_foreground)
+ ukm_service->OnAppEnterForeground();
+ else
+ ukm_service->OnAppEnterBackground();
+ }
+}
+
void WebLayerMetricsServiceClient::ProfileCreated(ProfileImpl* profile) {
UpdateUkmService();
}
@@ -188,12 +222,21 @@ void WebLayerMetricsServiceClient::ProfileDestroyed(ProfileImpl* profile) {
UpdateUkmService();
}
+void WebLayerMetricsServiceClient::OnHasAtLeastOneResumedBrowserStateChanged(
+ bool new_value) {
+ ApplyForegroundStateToServices();
+}
+
+void JNI_ApplyConsentHelper(bool user_consent, bool app_consent) {
+ WebLayerMetricsServiceClient::GetInstance()->ApplyConsent(user_consent,
+ app_consent);
+}
+
// static
void JNI_MetricsServiceClient_SetHaveMetricsConsent(JNIEnv* env,
jboolean user_consent,
jboolean app_consent) {
- WebLayerMetricsServiceClient::GetInstance()->SetHaveMetricsConsent(
- user_consent, app_consent);
+ JNI_ApplyConsentHelper(user_consent, app_consent);
}
} // namespace weblayer
diff --git a/chromium/weblayer/browser/android/metrics/weblayer_metrics_service_client.h b/chromium/weblayer/browser/android/metrics/weblayer_metrics_service_client.h
index 09db1604fcb..a8475a2ffeb 100644
--- a/chromium/weblayer/browser/android/metrics/weblayer_metrics_service_client.h
+++ b/chromium/weblayer/browser/android/metrics/weblayer_metrics_service_client.h
@@ -18,13 +18,15 @@
#include "components/metrics/metrics_service_client.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
+#include "weblayer/browser/browser_list_observer.h"
#include "weblayer/browser/profile_impl.h"
namespace weblayer {
class WebLayerMetricsServiceClient
: public ::metrics::AndroidMetricsServiceClient,
- public ProfileImpl::ProfileObserver {
+ public ProfileImpl::ProfileObserver,
+ public BrowserListObserver {
friend class base::NoDestructor<WebLayerMetricsServiceClient>;
public:
@@ -42,21 +44,31 @@ class WebLayerMetricsServiceClient
std::string GetUploadSigningKey() override;
// metrics::AndroidMetricsServiceClient:
- int GetSampleRatePerMille() override;
+ int GetSampleRatePerMille() const override;
void OnMetricsStart() override;
void OnMetricsNotStarted() override;
int GetPackageNameLimitRatePerMille() override;
void RegisterAdditionalMetricsProviders(
metrics::MetricsService* service) override;
- bool IsPersistentHistogramsEnabled() override;
bool IsOffTheRecordSessionActive() override;
scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override;
private:
+ friend void JNI_ApplyConsentHelper(bool user_consent, bool app_consent);
+
+ // Called once when consent has been determined.
+ void ApplyConsent(bool user_consent, bool app_consent);
+
+ // Updates the services based on the foreground state.
+ void ApplyForegroundStateToServices();
+
// ProfileImpl::ProfileObserver:
void ProfileCreated(ProfileImpl* profile) override;
void ProfileDestroyed(ProfileImpl* profile) override;
+ // BrowserListObserver:
+ void OnHasAtLeastOneResumedBrowserStateChanged(bool new_value) override;
+
std::vector<base::OnceClosure> post_start_tasks_;
DISALLOW_COPY_AND_ASSIGN(WebLayerMetricsServiceClient);
diff --git a/chromium/weblayer/browser/android/resource_mapper.cc b/chromium/weblayer/browser/android/resource_mapper.cc
index aeeb6fbbf99..a49b3a67843 100644
--- a/chromium/weblayer/browser/android/resource_mapper.cc
+++ b/chromium/weblayer/browser/android/resource_mapper.cc
@@ -42,6 +42,7 @@ void ConstructMap() {
#include "components/resources/android/page_info_resource_id.h"
#include "components/resources/android/permissions_resource_id.h"
#include "components/resources/android/sms_resource_id.h"
+#include "components/resources/android/webxr_resource_id.h"
#undef LINK_RESOURCE_ID
#undef DECLARE_RESOURCE_ID
// Make sure ID list sizes match up.
diff --git a/chromium/weblayer/browser/background_sync/background_sync_browsertest.cc b/chromium/weblayer/browser/background_sync/background_sync_browsertest.cc
new file mode 100644
index 00000000000..afff194d77b
--- /dev/null
+++ b/chromium/weblayer/browser/background_sync/background_sync_browsertest.cc
@@ -0,0 +1,180 @@
+// 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 "base/run_loop.h"
+#include "base/time/time.h"
+#include "build/build_config.h"
+#include "components/background_sync/background_sync_controller_impl.h"
+#include "components/content_settings/core/browser/host_content_settings_map.h"
+#include "components/content_settings/core/common/content_settings.h"
+#include "content/public/browser/background_sync_parameters.h"
+#include "content/public/test/background_sync_test_util.h"
+#include "content/public/test/browser_test_utils.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
+#include "weblayer/browser/background_sync/background_sync_controller_factory.h"
+#include "weblayer/browser/background_sync/background_sync_delegate_impl.h"
+#include "weblayer/browser/host_content_settings_map_factory.h"
+#include "weblayer/browser/tab_impl.h"
+#include "weblayer/shell/browser/shell.h"
+#include "weblayer/test/weblayer_browser_test.h"
+#include "weblayer/test/weblayer_browser_test_utils.h"
+
+namespace {
+const char kExampleUrl[] = "https://www.example.com/";
+const char kTag[] = "test_tag";
+} // namespace
+
+namespace weblayer {
+
+class BackgroundSyncBrowserTest : public WebLayerBrowserTest {
+ public:
+ BackgroundSyncBrowserTest() = default;
+ ~BackgroundSyncBrowserTest() override = default;
+
+ void SetUpOnMainThread() override {
+ sync_event_received_ = std::make_unique<base::RunLoop>();
+ content::background_sync_test_util::SetIgnoreNetworkChanges(
+ /* ignore= */ true);
+
+ https_server_ = std::make_unique<net::EmbeddedTestServer>(
+ net::EmbeddedTestServer::TYPE_HTTPS);
+ https_server_->RegisterRequestHandler(base::BindRepeating(
+ &BackgroundSyncBrowserTest::HandleRequest, base::Unretained(this)));
+ https_server_->AddDefaultHandlers(
+ base::FilePath(FILE_PATH_LITERAL("weblayer/test/data")));
+ ASSERT_TRUE(https_server_->Start());
+ }
+
+ // Intercepts all requests.
+ std::unique_ptr<net::test_server::HttpResponse> HandleRequest(
+ const net::test_server::HttpRequest& request) {
+ if (request.GetURL().query() == "syncreceived") {
+ if (sync_event_received_)
+ sync_event_received_->Quit();
+ }
+
+ // The default handlers will take care of this request.
+ return nullptr;
+ }
+
+ protected:
+ content::WebContents* web_contents() {
+ return static_cast<TabImpl*>(shell()->tab())->web_contents();
+ }
+
+ std::unique_ptr<base::RunLoop> sync_event_received_;
+ std::unique_ptr<net::EmbeddedTestServer> https_server_;
+};
+
+IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, GetBackgroundSyncController) {
+ EXPECT_TRUE(BackgroundSyncControllerFactory::GetForBrowserContext(
+ GetBrowserContext()));
+}
+
+IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, ZeroSiteEngagementPenalty) {
+ // TODO(crbug.com/1091211): Update when we add support for Periodic Background
+ // Sync.
+ auto* controller = BackgroundSyncControllerFactory::GetForBrowserContext(
+ GetBrowserContext());
+ ASSERT_TRUE(controller);
+
+ url::Origin origin = url::Origin::Create(GURL(kExampleUrl));
+ content::BackgroundSyncRegistration registration;
+ registration.set_origin(origin);
+
+ // min interval >=0 implies Periodic Background Sync.
+ blink::mojom::SyncRegistrationOptions options(
+ kTag,
+ /* min_interval= */ base::TimeDelta::FromHours(12).InMilliseconds());
+ *registration.options() = std::move(options);
+ // First attempt.
+ registration.set_num_attempts(0);
+
+ content::BackgroundSyncParameters parameters;
+
+ base::TimeDelta delay = controller->GetNextEventDelay(
+ registration, &parameters,
+ /* time_till_soonest_scheduled_event_for_origin= */
+ base::TimeDelta::Max());
+ EXPECT_EQ(delay, base::TimeDelta::Max());
+}
+
+#if defined(OS_ANDROID)
+IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, BackgroundSyncNotDisabled) {
+ auto* controller = BackgroundSyncControllerFactory::GetForBrowserContext(
+ GetBrowserContext());
+ ASSERT_TRUE(controller);
+
+ // TODO(crbug.com/1087486, 1091211): Update logic here if we need to support
+ // Android L when we add browser wakeup logic.
+ content::BackgroundSyncParameters parameters;
+ controller->GetParameterOverrides(&parameters);
+ EXPECT_FALSE(parameters.disable);
+}
+#endif // defined (OS_ANDROID)
+
+IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, ContentSettings) {
+ auto* browser_context = GetBrowserContext();
+ auto* controller =
+ BackgroundSyncControllerFactory::GetForBrowserContext(browser_context);
+ ASSERT_TRUE(controller);
+
+ url::Origin origin = url::Origin::Create(GURL(kExampleUrl));
+ controller->AddToTrackedOrigins(origin);
+ ASSERT_TRUE(controller->IsOriginTracked(origin));
+
+ auto* host_content_settings_map =
+ HostContentSettingsMapFactory::GetForBrowserContext(browser_context);
+ ASSERT_TRUE(host_content_settings_map);
+
+ host_content_settings_map->SetContentSettingDefaultScope(
+ /* primary_url= */ GURL(kExampleUrl),
+ /* secondary_url= */ GURL(kExampleUrl),
+ ContentSettingsType::BACKGROUND_SYNC, CONTENT_SETTING_BLOCK);
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(controller->IsOriginTracked(origin));
+}
+
+IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, NormalProfile) {
+ // TODO(crbug.com/1087486, 1091211): Make this use
+ // BackgroundSyncController::ScheduleBrowserWakeup() once we support waking
+ // the browser up.
+ auto delegate =
+ std::make_unique<BackgroundSyncDelegateImpl>(GetBrowserContext());
+ ASSERT_TRUE(delegate);
+ EXPECT_FALSE(delegate->IsProfileOffTheRecord());
+}
+
+IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest, SyncEventFired) {
+ content::background_sync_test_util::SetOnline(web_contents(), false);
+ NavigateAndWaitForCompletion(
+ https_server_->GetURL("/background_sync_browsertest.html"), shell());
+ content::background_sync_test_util::SetOnline(web_contents(), true);
+ sync_event_received_->Run();
+}
+
+class IncognitoBackgroundSyncBrowserTest : public BackgroundSyncBrowserTest {
+ public:
+ IncognitoBackgroundSyncBrowserTest() { SetShellStartsInIncognitoMode(); }
+};
+
+#if defined(OS_ANDROID)
+// https://crbug.com/1147754
+#define MAYBE_OffTheRecordProfile DISABLED_OffTheRecordProfile
+#else
+#define MAYBE_OffTheRecordProfile OffTheRecordProfile
+#endif
+IN_PROC_BROWSER_TEST_F(IncognitoBackgroundSyncBrowserTest,
+ MAYBE_OffTheRecordProfile) {
+ // TODO(crbug.com/1087486, 1091211): Make this use
+ // BackgroundSyncController::ScheduleBrowserWakeup() once we support waking
+ // the browser up.
+ auto delegate =
+ std::make_unique<BackgroundSyncDelegateImpl>(GetBrowserContext());
+ EXPECT_TRUE(delegate->IsProfileOffTheRecord());
+}
+
+} // namespace weblayer \ No newline at end of file
diff --git a/chromium/weblayer/browser/background_sync/background_sync_controller_factory.cc b/chromium/weblayer/browser/background_sync/background_sync_controller_factory.cc
new file mode 100644
index 00000000000..8745490a93e
--- /dev/null
+++ b/chromium/weblayer/browser/background_sync/background_sync_controller_factory.cc
@@ -0,0 +1,54 @@
+// 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/browser/background_sync/background_sync_controller_factory.h"
+
+#include "components/background_sync/background_sync_controller_impl.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "weblayer/browser/background_sync/background_sync_delegate_impl.h"
+#include "weblayer/browser/host_content_settings_map_factory.h"
+
+namespace weblayer {
+
+// static
+BackgroundSyncControllerImpl*
+BackgroundSyncControllerFactory::GetForBrowserContext(
+ content::BrowserContext* browser_context) {
+ // This is safe because BuildServiceInstanceFor(), which this method calls,
+ // returns a pointer to a BackgroundSyncControllerImpl object.
+ return static_cast<BackgroundSyncControllerImpl*>(
+ GetInstance()->GetServiceForBrowserContext(browser_context, true));
+}
+
+// static
+BackgroundSyncControllerFactory*
+BackgroundSyncControllerFactory::GetInstance() {
+ static base::NoDestructor<BackgroundSyncControllerFactory> factory;
+ return factory.get();
+}
+
+BackgroundSyncControllerFactory::BackgroundSyncControllerFactory()
+ : BrowserContextKeyedServiceFactory(
+ "BackgroundSyncService",
+ BrowserContextDependencyManager::GetInstance()) {
+ DependsOn(HostContentSettingsMapFactory::GetInstance());
+}
+
+BackgroundSyncControllerFactory::~BackgroundSyncControllerFactory() = default;
+
+KeyedService* BackgroundSyncControllerFactory::BuildServiceInstanceFor(
+ content::BrowserContext* context) const {
+ return new BackgroundSyncControllerImpl(
+ context, std::make_unique<BackgroundSyncDelegateImpl>(context));
+}
+
+content::BrowserContext*
+BackgroundSyncControllerFactory::GetBrowserContextToUse(
+ content::BrowserContext* context) const {
+ // Background sync operates in incognito mode, and as incognito profiles in
+ // Weblayer are not tied to regular profiles, return |context| itself.
+ return context;
+}
+
+} // namespace weblayer
diff --git a/chromium/weblayer/browser/background_sync/background_sync_controller_factory.h b/chromium/weblayer/browser/background_sync/background_sync_controller_factory.h
new file mode 100644
index 00000000000..b04f8e9b8bc
--- /dev/null
+++ b/chromium/weblayer/browser/background_sync/background_sync_controller_factory.h
@@ -0,0 +1,47 @@
+// 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_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_CONTROLLER_FACTORY_H_
+#define WEBLAYER_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_CONTROLLER_FACTORY_H_
+
+#include "base/no_destructor.h"
+#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
+
+class BackgroundSyncControllerImpl;
+
+namespace content {
+class BrowserContext;
+}
+
+namespace weblayer {
+
+// Creates and maintains a BackgroundSyncController instance per BrowserContext.
+class BackgroundSyncControllerFactory
+ : public BrowserContextKeyedServiceFactory {
+ public:
+ static BackgroundSyncControllerImpl* GetForBrowserContext(
+ content::BrowserContext* browser_context);
+ static BackgroundSyncControllerFactory* GetInstance();
+
+ BackgroundSyncControllerFactory(const BackgroundSyncControllerFactory&) =
+ delete;
+ BackgroundSyncControllerFactory& operator=(
+ const BackgroundSyncControllerFactory&) = delete;
+
+ private:
+ friend class base::NoDestructor<BackgroundSyncControllerFactory>;
+
+ BackgroundSyncControllerFactory();
+ ~BackgroundSyncControllerFactory() override;
+
+ // BrowserContextKeyedServiceFactory methods:
+ KeyedService* BuildServiceInstanceFor(
+ content::BrowserContext* context) const override;
+ content::BrowserContext* GetBrowserContextToUse(
+ content::BrowserContext* context) const override;
+};
+
+} // namespace weblayer
+
+#endif // WEBLAYER_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_CONTROLLER_FACTORY_H_
diff --git a/chromium/weblayer/browser/background_sync/background_sync_delegate_impl.cc b/chromium/weblayer/browser/background_sync/background_sync_delegate_impl.cc
new file mode 100644
index 00000000000..aa339b0fc16
--- /dev/null
+++ b/chromium/weblayer/browser/background_sync/background_sync_delegate_impl.cc
@@ -0,0 +1,97 @@
+// 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/browser/background_sync/background_sync_delegate_impl.h"
+
+#include "build/build_config.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/web_contents.h"
+#include "services/metrics/public/cpp/ukm_recorder.h"
+#include "services/metrics/public/cpp/ukm_source_id.h"
+#include "weblayer/browser/host_content_settings_map_factory.h"
+
+namespace weblayer {
+
+BackgroundSyncDelegateImpl::BackgroundSyncDelegateImpl(
+ content::BrowserContext* browser_context)
+ : browser_context_(browser_context) {
+ DCHECK(browser_context_);
+}
+
+BackgroundSyncDelegateImpl::~BackgroundSyncDelegateImpl() = default;
+
+void BackgroundSyncDelegateImpl::GetUkmSourceId(
+ const url::Origin& origin,
+ base::OnceCallback<void(base::Optional<ukm::SourceId>)> callback) {
+ // The exact URL which registered the Background Sync event is not saved,
+ // and the current main frame URL might not correspond to |origin|. Thus, we
+ // associate a new source ID with the origin.
+ // The only way WebLayer can lose history information is through the
+ // clearBrowsingHistory() API which also deletes all existing service workers.
+ // Therefore, if this method is called, it's safe to assume that the origin
+ // associated with the Background Sync registration is in WebLayer's browsing
+ // history. It's okay to log UKM for it.
+ ukm::SourceId source_id = ukm::ConvertToSourceId(
+ ukm::AssignNewSourceId(), ukm::SourceIdType::HISTORY_ID);
+ ukm::UkmRecorder* recorder = ukm::UkmRecorder::Get();
+ DCHECK(recorder);
+ recorder->UpdateSourceURL(source_id, origin.GetURL());
+
+ std::move(callback).Run(source_id);
+}
+
+void BackgroundSyncDelegateImpl::Shutdown() {
+ // Clear the BrowserContext as we're not supposed to use it anymore.
+ browser_context_ = nullptr;
+}
+
+HostContentSettingsMap*
+BackgroundSyncDelegateImpl::GetHostContentSettingsMap() {
+ return HostContentSettingsMapFactory::GetForBrowserContext(browser_context_);
+}
+
+bool BackgroundSyncDelegateImpl::IsProfileOffTheRecord() {
+ DCHECK(browser_context_);
+ return browser_context_->IsOffTheRecord();
+}
+
+void BackgroundSyncDelegateImpl::NoteSuspendedPeriodicSyncOrigins(
+ std::set<url::Origin> suspended_origins) {
+ // TODO(crbug.com/1091211): Consider site engagement when adding support for
+ // Periodic Background Sync.
+}
+
+int BackgroundSyncDelegateImpl::GetSiteEngagementPenalty(const GURL& url) {
+ // TODO(crbug.com/1091211): Consider site engagement when adding support for
+ // Periodic Background Sync.
+ return 0;
+}
+
+#if defined(OS_ANDROID)
+
+void BackgroundSyncDelegateImpl::ScheduleBrowserWakeUpWithDelay(
+ blink::mojom::BackgroundSyncType sync_type,
+ base::TimeDelta delay) {
+ // TODO(crbug.com/1087486, 1091211): Add logic to wake up the browser.
+}
+
+void BackgroundSyncDelegateImpl::CancelBrowserWakeup(
+ blink::mojom::BackgroundSyncType sync_type) {
+ // TODO(crbug.com/1087486, 1091211): Add logic to wake up the browser.
+}
+
+bool BackgroundSyncDelegateImpl::ShouldDisableBackgroundSync() {
+ // TODO(crbug.com/1087486, 1091211): Add logic here if we need to support
+ // Android L.
+ return false;
+}
+
+bool BackgroundSyncDelegateImpl::ShouldDisableAndroidNetworkDetection() {
+ // TODO(crbug.com/1141778): Remove this once waking up the WebLayer
+ // embedder is supported.
+ return true;
+}
+#endif // defined(OS_ANDROID)
+
+} // namespace weblayer
diff --git a/chromium/weblayer/browser/background_sync/background_sync_delegate_impl.h b/chromium/weblayer/browser/background_sync/background_sync_delegate_impl.h
new file mode 100644
index 00000000000..7a5659096fd
--- /dev/null
+++ b/chromium/weblayer/browser/background_sync/background_sync_delegate_impl.h
@@ -0,0 +1,49 @@
+// 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_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_DELEGATE_IMPL_H_
+#define WEBLAYER_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_DELEGATE_IMPL_H_
+
+#include "build/build_config.h"
+#include "components/background_sync/background_sync_delegate.h"
+#include "url/origin.h"
+
+namespace content {
+class BrowserContext;
+} // namespace content
+
+namespace weblayer {
+
+// WebLayer's customization of the logic in components/background_sync.
+class BackgroundSyncDelegateImpl
+ : public background_sync::BackgroundSyncDelegate {
+ public:
+ explicit BackgroundSyncDelegateImpl(content::BrowserContext* browser_context);
+ ~BackgroundSyncDelegateImpl() override;
+
+ void GetUkmSourceId(const url::Origin& origin,
+ base::OnceCallback<void(base::Optional<ukm::SourceId>)>
+ callback) override;
+ void Shutdown() override;
+ HostContentSettingsMap* GetHostContentSettingsMap() override;
+ bool IsProfileOffTheRecord() override;
+ void NoteSuspendedPeriodicSyncOrigins(
+ std::set<url::Origin> suspended_origins) override;
+ int GetSiteEngagementPenalty(const GURL& url) override;
+#if defined(OS_ANDROID)
+ void ScheduleBrowserWakeUpWithDelay(
+ blink::mojom::BackgroundSyncType sync_type,
+ base::TimeDelta delay) override;
+ void CancelBrowserWakeup(blink::mojom::BackgroundSyncType sync_type) override;
+ bool ShouldDisableBackgroundSync() override;
+ bool ShouldDisableAndroidNetworkDetection() override;
+#endif // defined(OS_ANDROID)
+
+ private:
+ content::BrowserContext* browser_context_;
+};
+
+} // namespace weblayer
+
+#endif // WEBLAYER_BROWSER_BACKGROUND_SYNC_BACKGROUND_SYNC_DELEGATE_IMPL_H_ \ No newline at end of file
diff --git a/chromium/weblayer/browser/browser_context_impl.cc b/chromium/weblayer/browser/browser_context_impl.cc
index 27ca8c525c7..ddfe182c1fb 100644
--- a/chromium/weblayer/browser/browser_context_impl.cc
+++ b/chromium/weblayer/browser/browser_context_impl.cc
@@ -5,6 +5,7 @@
#include "weblayer/browser/browser_context_impl.h"
#include "base/threading/thread_restrictions.h"
+#include "components/background_sync/background_sync_controller_impl.h"
#include "components/blocked_content/safe_browsing_triggered_popup_blocker.h"
#include "components/client_hints/browser/client_hints.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
@@ -33,6 +34,7 @@
#include "content/public/browser/download_request_utils.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/storage_partition.h"
+#include "weblayer/browser/background_sync/background_sync_controller_factory.h"
#include "weblayer/browser/browsing_data_remover_delegate.h"
#include "weblayer/browser/browsing_data_remover_delegate_factory.h"
#include "weblayer/browser/client_hints_factory.h"
@@ -197,7 +199,7 @@ BrowserContextImpl::GetBackgroundFetchDelegate() {
content::BackgroundSyncController*
BrowserContextImpl::GetBackgroundSyncController() {
- return nullptr;
+ return BackgroundSyncControllerFactory::GetForBrowserContext(this);
}
content::BrowsingDataRemoverDelegate*
diff --git a/chromium/weblayer/browser/browser_impl.cc b/chromium/weblayer/browser/browser_impl.cc
index 11cdb81c1b5..74e628d5b93 100644
--- a/chromium/weblayer/browser/browser_impl.cc
+++ b/chromium/weblayer/browser/browser_impl.cc
@@ -31,9 +31,6 @@
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/json/json_writer.h"
-#include "components/metrics/metrics_service.h"
-#include "components/ukm/ukm_service.h"
-#include "weblayer/browser/android/metrics/weblayer_metrics_service_client.h"
#include "weblayer/browser/browser_process.h"
#include "weblayer/browser/java/jni/BrowserImpl_jni.h"
#endif
@@ -46,41 +43,6 @@ using base::android::ScopedJavaLocalRef;
namespace weblayer {
-namespace {
-
-#if defined(OS_ANDROID)
-void UpdateMetricsService() {
- static bool s_foreground = false;
- // TODO(sky): convert this to observer.
- bool foreground = BrowserList::GetInstance()->HasAtLeastOneResumedBrowser();
-
- if (foreground == s_foreground)
- return;
-
- s_foreground = foreground;
-
- auto* metrics_service =
- WebLayerMetricsServiceClient::GetInstance()->GetMetricsService();
- if (metrics_service) {
- if (foreground)
- metrics_service->OnAppEnterForeground();
- else
- metrics_service->OnAppEnterBackground();
- }
-
- auto* ukm_service =
- WebLayerMetricsServiceClient::GetInstance()->GetUkmService();
- if (ukm_service) {
- if (foreground)
- ukm_service->OnAppEnterForeground();
- else
- ukm_service->OnAppEnterBackground();
- }
-}
-#endif // defined(OS_ANDROID)
-
-} // namespace
-
// static
constexpr char BrowserImpl::kPersistenceFilePrefix[];
@@ -259,8 +221,8 @@ void BrowserImpl::SetWebPreferences(blink::web_pref::WebPreferences* prefs) {
AttachCurrentThread(), java_impl_);
prefs->preferred_color_scheme =
Java_BrowserImpl_getDarkThemeEnabled(AttachCurrentThread(), java_impl_)
- ? blink::PreferredColorScheme::kDark
- : blink::PreferredColorScheme::kLight;
+ ? blink::mojom::PreferredColorScheme::kDark
+ : blink::mojom::PreferredColorScheme::kLight;
prefs->font_scale_factor =
Java_BrowserImpl_getFontScale(AttachCurrentThread(), java_impl_);
#endif
@@ -443,7 +405,6 @@ void BrowserImpl::UpdateFragmentResumedState(bool state) {
const bool old_has_at_least_one_active_browser =
BrowserList::GetInstance()->HasAtLeastOneResumedBrowser();
fragment_resumed_ = state;
- UpdateMetricsService();
if (old_has_at_least_one_active_browser !=
BrowserList::GetInstance()->HasAtLeastOneResumedBrowser()) {
BrowserList::GetInstance()->NotifyHasAtLeastOneResumedBrowserChanged();
diff --git a/chromium/weblayer/browser/browser_list_observer.h b/chromium/weblayer/browser/browser_list_observer.h
index 4d6a7d06340..3b17897651b 100644
--- a/chromium/weblayer/browser/browser_list_observer.h
+++ b/chromium/weblayer/browser/browser_list_observer.h
@@ -17,7 +17,7 @@ class BrowserListObserver : public base::CheckedObserver {
#if defined(OS_ANDROID)
// Called when the value of BrowserList::HasAtLeastOneResumedBrowser()
// changes.
- void OnHasAtLeastOneResumedBrowserStateChanged(bool new_value) {}
+ virtual void OnHasAtLeastOneResumedBrowserStateChanged(bool new_value) {}
#endif
virtual void OnBrowserCreated(Browser* browser) {}
diff --git a/chromium/weblayer/browser/browser_main_parts_impl.cc b/chromium/weblayer/browser/browser_main_parts_impl.cc
index 769fd7957f9..30ad30176b7 100644
--- a/chromium/weblayer/browser/browser_main_parts_impl.cc
+++ b/chromium/weblayer/browser/browser_main_parts_impl.cc
@@ -6,7 +6,9 @@
#include "base/base_switches.h"
#include "base/bind.h"
+#include "base/json/json_reader.h"
#include "base/task/current_thread.h"
+#include "base/task/task_traits.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
@@ -14,7 +16,9 @@
#include "components/captive_portal/core/buildflags.h"
#include "components/prefs/pref_service.h"
#include "components/startup_metric_utils/browser/startup_metric_utils.h"
+#include "components/subresource_filter/content/browser/ruleset_service.h"
#include "components/translate/core/browser/translate_download_manager.h"
+#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/render_process_host.h"
@@ -35,6 +39,7 @@
#include "weblayer/browser/translate_accept_languages_factory.h"
#include "weblayer/browser/translate_ranker_factory.h"
#include "weblayer/browser/webui/web_ui_controller_factory.h"
+#include "weblayer/grit/weblayer_resources.h"
#include "weblayer/public/main.h"
#if defined(OS_ANDROID)
@@ -44,11 +49,14 @@
#include "components/crash/core/common/crash_key.h"
#include "components/javascript_dialogs/android/app_modal_dialog_view_android.h" // nogncheck
#include "components/javascript_dialogs/app_modal_dialog_manager.h" // nogncheck
+#include "components/metrics/metrics_service.h"
+#include "components/variations/variations_ids_provider.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "net/android/network_change_notifier_factory_android.h"
#include "net/base/network_change_notifier.h"
#include "weblayer/browser/android/metrics/uma_utils.h"
+#include "weblayer/browser/android/metrics/weblayer_metrics_service_client.h"
#include "weblayer/browser/java/jni/MojoInterfaceRegistrar_jni.h"
#include "weblayer/browser/media/local_presentation_manager_factory.h"
#include "weblayer/browser/media/media_router_factory.h"
@@ -56,9 +64,6 @@
#include "weblayer/common/features.h"
#endif
-#if defined(USE_X11)
-#include "ui/base/x/x11_util.h" // nogncheck
-#endif
#if defined(USE_AURA) && defined(USE_X11)
#include "ui/base/ui_base_features.h"
#include "ui/events/devices/x11/touch_factory_x11.h" // nogncheck
@@ -75,6 +80,27 @@ namespace weblayer {
namespace {
+// Indexes and publishes the subresource filter ruleset data from resources in
+// the resource bundle.
+void PublishSubresourceFilterRulesetFromResourceBundle() {
+ // First obtain the version of the ruleset data from the manifest.
+ std::string ruleset_manifest_string =
+ ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
+ IDR_SUBRESOURCE_FILTER_UNINDEXED_RULESET_MANIFEST_JSON);
+ auto ruleset_manifest = base::JSONReader::Read(ruleset_manifest_string);
+ DCHECK(ruleset_manifest);
+ std::string* content_version = ruleset_manifest->FindStringKey("version");
+
+ // Instruct the RulesetService to obtain the unindexed ruleset data from the
+ // ResourceBundle and give it the version of that data.
+ auto* ruleset_service =
+ BrowserProcess::GetInstance()->subresource_filter_ruleset_service();
+ subresource_filter::UnindexedRulesetInfo ruleset_info;
+ ruleset_info.resource_id = IDR_SUBRESOURCE_FILTER_UNINDEXED_RULESET;
+ ruleset_info.content_version = *content_version;
+ ruleset_service->IndexAndStoreAndPublishRulesetIfNeeded(ruleset_info);
+}
+
// Instantiates all weblayer KeyedService factories, which is
// especially important for services that should be created at profile
// creation time as compared to lazily on first access.
@@ -90,7 +116,7 @@ void EnsureBrowserContextKeyedServiceFactoriesBuilt() {
PrerenderLinkManagerFactory::GetInstance();
PrerenderManagerFactory::GetInstance();
#if defined(OS_ANDROID)
- if (base::FeatureList::IsEnabled(features::kMediaRouter)) {
+ if (MediaRouterFactory::IsFeatureEnabled()) {
LocalPresentationManagerFactory::GetInstance();
MediaRouterFactory::GetInstance();
}
@@ -138,6 +164,18 @@ int BrowserMainPartsImpl::PreCreateThreads() {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
::switches::kDisableMediaSessionAPI);
}
+
+ // WebLayer initializes the MetricsService once consent is determined.
+ // Determining consent is async and potentially slow. VariationsIdsProvider
+ // is responsible for updating the X-Client-Data header. To ensure the header
+ // is always provided, VariationsIdsProvider is registered now.
+ //
+ // Chrome registers the VariationsIdsProvider from PreCreateThreads() as well.
+ auto* metrics_client = WebLayerMetricsServiceClient::GetInstance();
+ metrics_client->GetMetricsService()
+ ->synthetic_trial_registry()
+ ->AddSyntheticTrialObserver(
+ variations::VariationsIdsProvider::GetInstance());
#endif
return content::RESULT_CODE_NORMAL_EXIT;
@@ -153,10 +191,6 @@ void BrowserMainPartsImpl::PreMainMessageLoopStart() {
int BrowserMainPartsImpl::PreEarlyInitialization() {
browser_process_ = std::make_unique<BrowserProcess>(std::move(local_state_));
-#if defined(USE_X11)
- if (!features::IsUsingOzonePlatform())
- ui::SetDefaultX11ErrorHandlers();
-#endif
#if defined(USE_AURA) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
ui::InitializeInputMethodForTesting();
#endif
@@ -191,6 +225,17 @@ void BrowserMainPartsImpl::PreMainMessageLoopRun() {
BrowserProcess::GetInstance()->PreMainMessageLoopRun();
+ // Publish the ruleset data. On the vast majority of runs this will
+ // effectively be a no-op as the version of the data changes at most once per
+ // release. Nonetheless, post it as a best-effort task to take it off the
+ // critical path of startup. Note that best-effort tasks are guaranteed to
+ // execute within a reasonable delay (assuming of course that the app isn't
+ // shut down first).
+ content::GetUIThreadTaskRunner({base::TaskPriority::BEST_EFFORT})
+ ->PostTask(
+ FROM_HERE,
+ base::BindOnce(&PublishSubresourceFilterRulesetFromResourceBundle));
+
if (main_function_params_.ui_task) {
std::move(*main_function_params_.ui_task).Run();
delete main_function_params_.ui_task;
diff --git a/chromium/weblayer/browser/client_hints_browsertest.cc b/chromium/weblayer/browser/client_hints_browsertest.cc
index 77e7711f9e0..9038a10c614 100644
--- a/chromium/weblayer/browser/client_hints_browsertest.cc
+++ b/chromium/weblayer/browser/client_hints_browsertest.cc
@@ -136,11 +136,11 @@ IN_PROC_BROWSER_TEST_F(ClientHintsBrowserTest,
->GetBrowserContext());
std::unique_ptr<base::Value> setting = settings_map->GetWebsiteSetting(
embedded_test_server()->base_url(), GURL(),
- ContentSettingsType::CLIENT_HINTS, std::string(), nullptr);
+ ContentSettingsType::CLIENT_HINTS, nullptr);
ASSERT_TRUE(setting);
settings_map->SetWebsiteSettingDefaultScope(
other_server.base_url(), GURL(), ContentSettingsType::CLIENT_HINTS,
- std::string(), std::make_unique<base::Value>(setting->Clone()));
+ std::make_unique<base::Value>(setting->Clone()));
// Settings take affect after navigation only, so the header shouldn't be
// there yet.
diff --git a/chromium/weblayer/browser/content_browser_client_impl.cc b/chromium/weblayer/browser/content_browser_client_impl.cc
index 7511ea0b467..b90fef995af 100644
--- a/chromium/weblayer/browser/content_browser_client_impl.cc
+++ b/chromium/weblayer/browser/content_browser_client_impl.cc
@@ -22,6 +22,8 @@
#include "components/embedder_support/switches.h"
#include "components/error_page/content/browser/net_error_auto_reloader.h"
#include "components/network_time/network_time_tracker.h"
+#include "components/no_state_prefetch/browser/prerender_manager.h"
+#include "components/no_state_prefetch/common/prerender_url_loader_throttle.h"
#include "components/page_load_metrics/browser/metrics_navigation_throttle.h"
#include "components/page_load_metrics/browser/metrics_web_contents_observer.h"
#include "components/permissions/quota_permission_context_impl.h"
@@ -29,8 +31,6 @@
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service_factory.h"
#include "components/prefs/scoped_user_pref_update.h"
-#include "components/prerender/browser/prerender_manager.h"
-#include "components/prerender/common/prerender_url_loader_throttle.h"
#include "components/security_interstitials/content/insecure_form_navigation_throttle.h"
#include "components/security_interstitials/content/ssl_cert_reporter.h"
#include "components/security_interstitials/content/ssl_error_handler.h"
@@ -639,10 +639,10 @@ content::ControllerPresentationServiceDelegate*
ContentBrowserClientImpl::GetControllerPresentationServiceDelegate(
content::WebContents* web_contents) {
#if defined(OS_ANDROID)
- if (WebLayerFactoryImplAndroid::GetClientMajorVersion() < 87)
+ if (WebLayerFactoryImplAndroid::GetClientMajorVersion() < 88)
return nullptr;
- if (base::FeatureList::IsEnabled(features::kMediaRouter)) {
+ if (MediaRouterFactory::IsFeatureEnabled()) {
MediaRouterFactory::DoPlatformInitIfNeeded();
return media_router::PresentationServiceDelegateImpl::
GetOrCreateForWebContents(web_contents);
@@ -657,11 +657,26 @@ ContentBrowserClientImpl::CreateThrottlesForNavigation(
content::NavigationHandle* handle) {
std::vector<std::unique_ptr<content::NavigationThrottle>> throttles;
+ TabImpl* tab = TabImpl::FromWebContents(handle->GetWebContents());
+ NavigationControllerImpl* navigation_controller = nullptr;
+ if (tab) {
+ navigation_controller =
+ static_cast<NavigationControllerImpl*>(tab->GetNavigationController());
+ }
if (handle->IsInMainFrame()) {
NavigationUIDataImpl* navigation_ui_data =
static_cast<NavigationUIDataImpl*>(handle->GetNavigationUIData());
+
+ NavigationImpl* navigation_impl = nullptr;
+ if (navigation_controller) {
+ navigation_impl =
+ navigation_controller->GetNavigationImplFromHandle(handle);
+ }
+
if ((!navigation_ui_data ||
!navigation_ui_data->disable_network_error_auto_reload()) &&
+ (!navigation_impl ||
+ !navigation_impl->disable_network_error_auto_reload()) &&
IsNetworkErrorAutoReloadEnabled()) {
auto auto_reload_throttle =
error_page::NetErrorAutoReloader::MaybeCreateThrottleFor(handle);
@@ -684,11 +699,8 @@ ContentBrowserClientImpl::CreateThrottlesForNavigation(
// The next highest priority throttle *must* be this as it's responsible for
// calling to NavigationController for certain events.
- TabImpl* tab = TabImpl::FromWebContents(handle->GetWebContents());
if (tab) {
- auto throttle =
- static_cast<NavigationControllerImpl*>(tab->GetNavigationController())
- ->CreateNavigationThrottle(handle);
+ auto throttle = navigation_controller->CreateNavigationThrottle(handle);
if (throttle)
throttles.push_back(std::move(throttle));
}
@@ -713,13 +725,11 @@ ContentBrowserClientImpl::CreateThrottlesForNavigation(
throttles.push_back(
GetSafeBrowsingService()->CreateSafeBrowsingNavigationThrottle(
handle));
- if (handle->IsInMainFrame()) {
- throttles.push_back(
- navigation_interception::InterceptNavigationDelegate::
- CreateThrottleFor(
- handle, navigation_interception::SynchronyMode::kAsync));
- }
}
+
+ throttles.push_back(
+ navigation_interception::InterceptNavigationDelegate::CreateThrottleFor(
+ handle, navigation_interception::SynchronyMode::kAsync));
}
#endif
return throttles;
@@ -908,7 +918,7 @@ bool ContentBrowserClientImpl::WillCreateURLLoaderFactory(
URLLoaderFactoryType type,
const url::Origin& request_initiator,
base::Optional<int64_t> navigation_id,
- base::UkmSourceId ukm_source_id,
+ ukm::SourceIdObj ukm_source_id,
mojo::PendingReceiver<network::mojom::URLLoaderFactory>* factory_receiver,
mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>*
header_client,
@@ -995,4 +1005,8 @@ ukm::UkmService* ContentBrowserClientImpl::GetUkmService() {
#endif
}
+bool ContentBrowserClientImpl::HasErrorPage(int http_status_code) {
+ return http_status_code >= 400;
+}
+
} // namespace weblayer
diff --git a/chromium/weblayer/browser/content_browser_client_impl.h b/chromium/weblayer/browser/content_browser_client_impl.h
index b1a565bea42..fa350fa0895 100644
--- a/chromium/weblayer/browser/content_browser_client_impl.h
+++ b/chromium/weblayer/browser/content_browser_client_impl.h
@@ -132,7 +132,7 @@ class ContentBrowserClientImpl : public content::ContentBrowserClient {
URLLoaderFactoryType type,
const url::Origin& request_initiator,
base::Optional<int64_t> navigation_id,
- base::UkmSourceId ukm_source_id,
+ ukm::SourceIdObj ukm_source_id,
mojo::PendingReceiver<network::mojom::URLLoaderFactory>* factory_receiver,
mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>*
header_client,
@@ -155,6 +155,7 @@ class ContentBrowserClientImpl : public content::ContentBrowserClient {
content::SpeechRecognitionManagerDelegate*
CreateSpeechRecognitionManagerDelegate() override;
ukm::UkmService* GetUkmService() override;
+ bool HasErrorPage(int http_status_code) override;
void CreateFeatureListAndFieldTrials();
diff --git a/chromium/weblayer/browser/controls_visibility_reason.h b/chromium/weblayer/browser/controls_visibility_reason.h
index dd03668ae3e..097b3acd4dc 100644
--- a/chromium/weblayer/browser/controls_visibility_reason.h
+++ b/chromium/weblayer/browser/controls_visibility_reason.h
@@ -10,6 +10,10 @@ namespace weblayer {
// This enum represents actions or UI conditions that affect the visibility of
// top UI, and is used to track concurrent concerns and to allow native and Java
// code to coordinate.
+//
+// WARNING: only a subset of these are used if OnlyExpandTopControlsAtPageTop
+// is true.
+//
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.weblayer_private
// GENERATED_JAVA_CLASS_NAME_OVERRIDE: ImplControlsVisibilityReason
enum class ControlsVisibilityReason {
diff --git a/chromium/weblayer/browser/cookie_manager_browsertest.cc b/chromium/weblayer/browser/cookie_manager_browsertest.cc
index 0d98a159a74..ca2cc7079be 100644
--- a/chromium/weblayer/browser/cookie_manager_browsertest.cc
+++ b/chromium/weblayer/browser/cookie_manager_browsertest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/test/bind_test_util.h"
+#include "base/test/bind.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "weblayer/browser/profile_impl.h"
#include "weblayer/public/cookie_manager.h"
diff --git a/chromium/weblayer/browser/default_search_engine.cc b/chromium/weblayer/browser/default_search_engine.cc
index 18b6968da4b..3258fbe7c73 100644
--- a/chromium/weblayer/browser/default_search_engine.cc
+++ b/chromium/weblayer/browser/default_search_engine.cc
@@ -30,9 +30,8 @@ void ResetDsePermissions(content::BrowserContext* browser_context) {
return;
GURL url = GetDseOrigin().GetURL();
HostContentSettingsMapFactory::GetForBrowserContext(browser_context)
- ->SetContentSettingDefaultScope(url, url,
- ContentSettingsType::GEOLOCATION,
- std::string(), CONTENT_SETTING_ALLOW);
+ ->SetContentSettingDefaultScope(
+ url, url, ContentSettingsType::GEOLOCATION, CONTENT_SETTING_ALLOW);
}
} // namespace weblayer
diff --git a/chromium/weblayer/browser/default_search_engine_browsertest.cc b/chromium/weblayer/browser/default_search_engine_browsertest.cc
index db68e3ae3ae..ff2dc1cd0f5 100644
--- a/chromium/weblayer/browser/default_search_engine_browsertest.cc
+++ b/chromium/weblayer/browser/default_search_engine_browsertest.cc
@@ -22,14 +22,12 @@ IN_PROC_BROWSER_TEST_F(DefaultSearchEngineBrowserTest,
->web_contents()
->GetBrowserContext());
auto origin = GetDseOrigin().GetURL();
- EXPECT_EQ(
- settings_map->GetContentSetting(
- origin, origin, ContentSettingsType::GEOLOCATION, std::string()),
- CONTENT_SETTING_ALLOW);
- EXPECT_EQ(
- settings_map->GetContentSetting(
- origin, origin, ContentSettingsType::NOTIFICATIONS, std::string()),
- CONTENT_SETTING_ASK);
+ EXPECT_EQ(settings_map->GetContentSetting(origin, origin,
+ ContentSettingsType::GEOLOCATION),
+ CONTENT_SETTING_ALLOW);
+ EXPECT_EQ(settings_map->GetContentSetting(origin, origin,
+ ContentSettingsType::NOTIFICATIONS),
+ CONTENT_SETTING_ASK);
}
class IncognitoDefaultSearchEngineBrowserTest
@@ -38,21 +36,20 @@ class IncognitoDefaultSearchEngineBrowserTest
IncognitoDefaultSearchEngineBrowserTest() { SetShellStartsInIncognitoMode(); }
};
+// Disabled on M88 only: http://crbug.com/1162363.
IN_PROC_BROWSER_TEST_F(IncognitoDefaultSearchEngineBrowserTest,
- IncognitoDoesNotHaveGeolocationPermission) {
+ DISABLED_IncognitoDoesNotHaveGeolocationPermission) {
auto* settings_map = HostContentSettingsMapFactory::GetForBrowserContext(
static_cast<TabImpl*>(shell()->tab())
->web_contents()
->GetBrowserContext());
auto origin = GetDseOrigin().GetURL();
- EXPECT_EQ(
- settings_map->GetContentSetting(
- origin, origin, ContentSettingsType::GEOLOCATION, std::string()),
- CONTENT_SETTING_ASK);
- EXPECT_EQ(
- settings_map->GetContentSetting(
- origin, origin, ContentSettingsType::NOTIFICATIONS, std::string()),
- CONTENT_SETTING_ASK);
+ EXPECT_EQ(settings_map->GetContentSetting(origin, origin,
+ ContentSettingsType::GEOLOCATION),
+ CONTENT_SETTING_ASK);
+ EXPECT_EQ(settings_map->GetContentSetting(origin, origin,
+ ContentSettingsType::NOTIFICATIONS),
+ CONTENT_SETTING_ASK);
}
} // namespace weblayer
diff --git a/chromium/weblayer/browser/download_browsertest.cc b/chromium/weblayer/browser/download_browsertest.cc
index c44c8c89fa0..8fc730d432a 100644
--- a/chromium/weblayer/browser/download_browsertest.cc
+++ b/chromium/weblayer/browser/download_browsertest.cc
@@ -9,7 +9,7 @@
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/task/post_task.h"
-#include "base/test/bind_test_util.h"
+#include "base/test/bind.h"
#include "base/threading/thread_restrictions.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/web_contents.h"
diff --git a/chromium/weblayer/browser/errorpage_browsertest.cc b/chromium/weblayer/browser/errorpage_browsertest.cc
index 776b26ba143..362b6357395 100644
--- a/chromium/weblayer/browser/errorpage_browsertest.cc
+++ b/chromium/weblayer/browser/errorpage_browsertest.cc
@@ -5,7 +5,7 @@
#include "weblayer/test/weblayer_browser_test.h"
#include "base/macros.h"
-#include "base/test/bind_test_util.h"
+#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "components/error_page/content/browser/net_error_auto_reloader.h"
#include "content/public/test/browser_test_utils.h"
@@ -72,9 +72,12 @@ class ErrorPageReloadBrowserTest : public ErrorPageBrowserTest {
WARN_UNUSED_RESULT {
content::TestNavigationManager navigation(web_contents(), url);
NavigationController::NavigateParams params;
- params.disable_network_error_auto_reload =
- disable_network_error_auto_reload;
- shell()->tab()->GetNavigationController()->Navigate(url, params);
+ auto* navigation_controller = shell()->tab()->GetNavigationController();
+ std::unique_ptr<DisableAutoReload> disable_auto_reload;
+ if (disable_network_error_auto_reload)
+ disable_auto_reload =
+ std::make_unique<DisableAutoReload>(navigation_controller);
+ navigation_controller->Navigate(url, params);
navigation.WaitForNavigationFinished();
return navigation.was_successful();
}
@@ -98,6 +101,23 @@ class ErrorPageReloadBrowserTest : public ErrorPageBrowserTest {
}
private:
+ class DisableAutoReload : public NavigationObserver {
+ public:
+ explicit DisableAutoReload(NavigationController* controller)
+ : controller_(controller) {
+ controller_->AddObserver(this);
+ }
+ ~DisableAutoReload() override { controller_->RemoveObserver(this); }
+
+ // NavigationObserver implementation:
+ void NavigationStarted(Navigation* navigation) override {
+ navigation->DisableNetworkErrorAutoReload();
+ }
+
+ private:
+ NavigationController* controller_;
+ };
+
base::test::ScopedFeatureList feature_list_;
};
diff --git a/chromium/weblayer/browser/favicon/favicon_backend_wrapper.cc b/chromium/weblayer/browser/favicon/favicon_backend_wrapper.cc
index 9f3108b7495..96ca4886bc0 100644
--- a/chromium/weblayer/browser/favicon/favicon_backend_wrapper.cc
+++ b/chromium/weblayer/browser/favicon/favicon_backend_wrapper.cc
@@ -75,6 +75,17 @@ FaviconBackendWrapper::GetFaviconsForUrl(
/* fallback_to_host */ false);
}
+favicon_base::FaviconRawBitmapResult
+FaviconBackendWrapper::GetLargestFaviconForUrl(
+ const GURL& page_url,
+ const std::vector<favicon_base::IconTypeSet>& icon_types_list,
+ int minimum_size_in_pixels) {
+ if (!favicon_backend_)
+ return {};
+ return favicon_backend_->GetLargestFaviconForUrl(page_url, icon_types_list,
+ minimum_size_in_pixels);
+}
+
void FaviconBackendWrapper::SetFaviconsOutOfDateForPage(const GURL& page_url) {
if (favicon_backend_ &&
favicon_backend_->SetFaviconsOutOfDateForPage(page_url)) {
diff --git a/chromium/weblayer/browser/favicon/favicon_backend_wrapper.h b/chromium/weblayer/browser/favicon/favicon_backend_wrapper.h
index eb74c63ca03..39d3b94498f 100644
--- a/chromium/weblayer/browser/favicon/favicon_backend_wrapper.h
+++ b/chromium/weblayer/browser/favicon/favicon_backend_wrapper.h
@@ -51,6 +51,10 @@ class FaviconBackendWrapper
const GURL& page_url,
const favicon_base::IconTypeSet& icon_types,
const std::vector<int>& desired_sizes);
+ favicon_base::FaviconRawBitmapResult GetLargestFaviconForUrl(
+ const GURL& page_url,
+ const std::vector<favicon_base::IconTypeSet>& icon_types_list,
+ int minimum_size_in_pixels);
void SetFaviconsOutOfDateForPage(const GURL& page_url);
void SetFavicons(const base::flat_set<GURL>& page_urls,
favicon_base::IconType icon_type,
@@ -95,8 +99,8 @@ class FaviconBackendWrapper
// batch commits.
base::OneShotTimer commit_timer_;
- // The real implementation of the backend. Is there is a problem initializing
- // the database this will be null.
+ // The real implementation of the backend. If there is a problem
+ // initializing the database this will be null.
std::unique_ptr<favicon::FaviconBackend> favicon_backend_;
// Timer used to remove items from the database that are likely no longer
diff --git a/chromium/weblayer/browser/favicon/favicon_callback_proxy.cc b/chromium/weblayer/browser/favicon/favicon_callback_proxy.cc
index 4ec3a90edf3..b1b88715595 100644
--- a/chromium/weblayer/browser/favicon/favicon_callback_proxy.cc
+++ b/chromium/weblayer/browser/favicon/favicon_callback_proxy.cc
@@ -26,7 +26,7 @@ void FaviconCallbackProxy::OnFaviconChanged(const gfx::Image& image) {
JNIEnv* env = base::android::AttachCurrentThread();
Java_FaviconCallbackProxy_onFaviconChanged(
env, java_proxy_,
- favicon.empty() ? nullptr : gfx::ConvertToJavaBitmap(&favicon));
+ favicon.empty() ? nullptr : gfx::ConvertToJavaBitmap(favicon));
}
static jlong JNI_FaviconCallbackProxy_CreateFaviconCallbackProxy(
diff --git a/chromium/weblayer/browser/favicon/favicon_service_impl.cc b/chromium/weblayer/browser/favicon/favicon_service_impl.cc
index b8ac3421677..d16aae1a2ef 100644
--- a/chromium/weblayer/browser/favicon/favicon_service_impl.cc
+++ b/chromium/weblayer/browser/favicon/favicon_service_impl.cc
@@ -125,6 +125,21 @@ base::CancelableTaskTracker::TaskId FaviconServiceImpl::GetFaviconForPageUrl(
std::move(callback)));
}
+base::CancelableTaskTracker::TaskId
+FaviconServiceImpl::GetLargestRawFaviconForPageURL(
+ const GURL& page_url,
+ const std::vector<favicon_base::IconTypeSet>& icon_types,
+ int minimum_size_in_pixels,
+ favicon_base::FaviconRawBitmapCallback callback,
+ base::CancelableTaskTracker* tracker) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ return tracker->PostTaskAndReplyWithResult(
+ backend_task_runner_.get(), FROM_HERE,
+ base::BindOnce(&FaviconBackendWrapper::GetLargestFaviconForUrl, backend_,
+ page_url, icon_types, minimum_size_in_pixels),
+ std::move(callback));
+}
+
base::CancelableTaskTracker::TaskId FaviconServiceImpl::GetFaviconForPageURL(
const GURL& page_url,
const favicon_base::IconTypeSet& icon_types,
diff --git a/chromium/weblayer/browser/favicon/favicon_service_impl.h b/chromium/weblayer/browser/favicon/favicon_service_impl.h
index 4d1a71db34d..695c36f3c4d 100644
--- a/chromium/weblayer/browser/favicon/favicon_service_impl.h
+++ b/chromium/weblayer/browser/favicon/favicon_service_impl.h
@@ -10,6 +10,7 @@
#include "base/memory/ref_counted.h"
#include "base/sequence_checker.h"
#include "components/favicon/core/core_favicon_service.h"
+#include "components/favicon/core/large_favicon_provider.h"
namespace base {
class FilePath;
@@ -22,7 +23,8 @@ class FaviconServiceImplObserver;
// FaviconServiceImpl provides the front end (ui side) access to the favicon
// database. Most functions are processed async on the backend task-runner.
-class FaviconServiceImpl : public favicon::CoreFaviconService {
+class FaviconServiceImpl : public favicon::CoreFaviconService,
+ public favicon::LargeFaviconProvider {
public:
FaviconServiceImpl();
FaviconServiceImpl(const FaviconServiceImpl&) = delete;
@@ -46,6 +48,12 @@ class FaviconServiceImpl : public favicon::CoreFaviconService {
base::CancelableTaskTracker* tracker);
// favicon::CoreFaviconService:
+ base::CancelableTaskTracker::TaskId GetLargestRawFaviconForPageURL(
+ const GURL& page_url,
+ const std::vector<favicon_base::IconTypeSet>& icon_types,
+ int minimum_size_in_pixels,
+ favicon_base::FaviconRawBitmapCallback callback,
+ base::CancelableTaskTracker* tracker) override;
base::CancelableTaskTracker::TaskId GetFaviconForPageURL(
const GURL& page_url,
const favicon_base::IconTypeSet& icon_types,
diff --git a/chromium/weblayer/browser/favicon/favicon_service_impl_factory.cc b/chromium/weblayer/browser/favicon/favicon_service_impl_factory.cc
index f75045536f2..ac39ab8abb4 100644
--- a/chromium/weblayer/browser/favicon/favicon_service_impl_factory.cc
+++ b/chromium/weblayer/browser/favicon/favicon_service_impl_factory.cc
@@ -5,12 +5,23 @@
#include "weblayer/browser/favicon/favicon_service_impl_factory.h"
#include "base/files/file_path.h"
+#include "components/favicon/content/large_favicon_provider_getter.h"
+#include "components/favicon/core/core_favicon_service.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "content/public/browser/browser_context.h"
#include "weblayer/browser/favicon/favicon_service_impl.h"
namespace weblayer {
+namespace {
+
+favicon::LargeFaviconProvider* GetLargeFaviconProvider(
+ content::BrowserContext* browser_context) {
+ return FaviconServiceImplFactory::GetForBrowserContext(browser_context);
+}
+
+} // namespace
+
// static
FaviconServiceImpl* FaviconServiceImplFactory::GetForBrowserContext(
content::BrowserContext* browser_context) {
@@ -30,7 +41,10 @@ FaviconServiceImplFactory* FaviconServiceImplFactory::GetInstance() {
FaviconServiceImplFactory::FaviconServiceImplFactory()
: BrowserContextKeyedServiceFactory(
"FaviconServiceImpl",
- BrowserContextDependencyManager::GetInstance()) {}
+ BrowserContextDependencyManager::GetInstance()) {
+ favicon::SetLargeFaviconProviderGetter(
+ base::BindRepeating(&GetLargeFaviconProvider));
+}
FaviconServiceImplFactory::~FaviconServiceImplFactory() = default;
diff --git a/chromium/weblayer/browser/feature_list_creator.cc b/chromium/weblayer/browser/feature_list_creator.cc
index 4ff04637b63..dbd12af2d89 100644
--- a/chromium/weblayer/browser/feature_list_creator.cc
+++ b/chromium/weblayer/browser/feature_list_creator.cc
@@ -16,11 +16,14 @@
#include "content/public/browser/network_service_instance.h"
#include "content/public/common/content_switch_dependent_feature_overrides.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
-#include "weblayer/browser/android/metrics/weblayer_metrics_service_client.h"
#include "weblayer/browser/system_network_context_manager.h"
#include "weblayer/browser/weblayer_variations_service_client.h"
#if defined(OS_ANDROID)
+#include "weblayer/browser/android/metrics/weblayer_metrics_service_client.h"
+#endif
+
+#if defined(OS_ANDROID)
namespace switches {
const char kDisableBackgroundNetworking[] = "disable-background-networking";
} // namespace switches
diff --git a/chromium/weblayer/browser/java/AndroidManifest_monochrome.xml b/chromium/weblayer/browser/java/AndroidManifest_monochrome.xml
new file mode 100644
index 00000000000..6eaac4d3fac
--- /dev/null
+++ b/chromium/weblayer/browser/java/AndroidManifest_monochrome.xml
@@ -0,0 +1,15 @@
+<?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. -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:dist="http://schemas.android.com/apk/distribution"
+ featureSplit="weblayer">
+ <uses-split android:name="chrome" />
+
+ <dist:module dist:onDemand="false">
+ <dist:fusing dist:include="true" />
+ </dist:module>
+
+ <application />
+</manifest>
diff --git a/chromium/weblayer/browser/java/BUILD.gn b/chromium/weblayer/browser/java/BUILD.gn
index a060247fe92..0c12f3ec5e8 100644
--- a/chromium/weblayer/browser/java/BUILD.gn
+++ b/chromium/weblayer/browser/java/BUILD.gn
@@ -5,6 +5,7 @@
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
import("//build/config/locales.gni")
+import("//tools/grit/grit_rule.gni")
import("//weblayer/variables.gni")
_bundle_utils_output =
@@ -18,6 +19,11 @@ jinja_template("weblayer_bundle_utils") {
android_resources("weblayer_resources") {
sources = [
+ "res/drawable-hdpi/amp_icon.png",
+ "res/drawable-mdpi/amp_icon.png",
+ "res/drawable-xhdpi/amp_icon.png",
+ "res/drawable-xxhdpi/amp_icon.png",
+ "res/drawable-xxxhdpi/amp_icon.png",
"res/drawable/weblayer_tab_indicator.xml",
"res/layout/site_settings_layout.xml",
"res/layout/weblayer_infobar_translate_compact_content.xml",
@@ -37,8 +43,15 @@ android_resources("weblayer_resources") {
"//components/browser_ui/strings/android:browser_ui_strings_grd",
"//components/browser_ui/styles/android:java_resources",
"//components/infobars/android:java_resources",
+ "//components/omnibox/browser:java_resources",
"//components/page_info/android:java_resources",
"//components/permissions/android:java_resources",
+
+ # TODO(crbug.com/1137713): Determine why the creation of
+ # //components/subresource_filter Java resources caused //weblayer's BundlePackageTest
+ # to fail without this dep even in advance of //weblayer depending on the code that uses these
+ # resources.
+ "//components/subresource_filter/android:java_resources",
"//components/translate/content/android:java_resources",
"//third_party/android_deps:material_design_java",
"//weblayer:components_java_strings",
@@ -51,13 +64,16 @@ generate_product_config_srcjar("weblayer_product_config") {
java_cpp_template("resource_id_javagen") {
sources = [ "ResourceId.template" ]
- package_path = "org/chromium/weblayer_private/resources"
inputs = [
"//components/resources/android/blocked_content_resource_id.h",
"//components/resources/android/page_info_resource_id.h",
"//components/resources/android/permissions_resource_id.h",
"//components/resources/android/sms_resource_id.h",
+ "//components/resources/android/webxr_resource_id.h",
+ "$root_gen_dir/device/vr/buildflags/buildflags.h",
]
+
+ deps = [ "//device/vr/buildflags" ]
}
java_strings_grd("weblayer_strings_grd") {
@@ -145,9 +161,12 @@ android_library("java") {
"org/chromium/weblayer_private/media/MediaRouteDialogFragmentImpl.java",
"org/chromium/weblayer_private/media/MediaRouterClientImpl.java",
"org/chromium/weblayer_private/media/MediaSessionManager.java",
+ "org/chromium/weblayer_private/media/MediaSessionNotificationHelper.java",
"org/chromium/weblayer_private/media/MediaStreamManager.java",
"org/chromium/weblayer_private/metrics/MetricsServiceClient.java",
"org/chromium/weblayer_private/metrics/UmaUtils.java",
+ "org/chromium/weblayer_private/payments/WebLayerPaymentRequestFactory.java",
+ "org/chromium/weblayer_private/payments/WebLayerPaymentRequestService.java",
"org/chromium/weblayer_private/permissions/PermissionRequestUtils.java",
"org/chromium/weblayer_private/resources/ResourceMapper.java",
_bundle_utils_output,
@@ -199,25 +218,33 @@ android_library("java") {
"//components/infobars/core:infobar_enums_java",
"//components/javascript_dialogs/android:java",
"//components/location/android:settings_java",
+ "//components/media_router/browser/android:cast_options_provider_java",
"//components/media_router/browser/android:java",
"//components/metrics:metrics_java",
"//components/minidump_uploader:minidump_uploader_java",
"//components/navigation_interception/android:navigation_interception_java",
"//components/omnibox/browser:browser_java",
"//components/page_info/android:java",
+ "//components/payments/content/android:java",
+ "//components/payments/mojom:mojom_java",
"//components/permissions/android:java",
+ "//components/prefs/android:java",
"//components/safe_browsing/android:safe_browsing_java",
"//components/security_interstitials/content/android:java",
+ "//components/security_state/core:security_state_enums_java",
"//components/signin/core/browser:signin_enums_java",
"//components/spellcheck/browser/android:java",
"//components/translate/content/android:java",
"//components/translate/content/android:translate_android_enums_java",
+ "//components/translate/core/common:translate_infobar_event_enum_java",
"//components/url_formatter/android:url_formatter_java",
+ "//components/user_prefs/android:java",
"//components/variations/android:variations_java",
"//components/version_info/android:version_constants_java",
"//components/webrtc/android:java",
"//content/public/android:content_java",
"//mojo/public/java:bindings_java",
+ "//mojo/public/java:system_java",
"//net/android:net_java",
"//services/network/public/mojom:cookies_mojom_java",
"//services/network/public/mojom:mojom_java",
@@ -277,6 +304,8 @@ android_library("test_java") {
"//base:jni_java",
"//components/infobars/android:java",
"//components/location/android:location_java",
+ "//components/media_router/browser/android:java",
+ "//components/media_router/browser/android:test_support_java",
"//components/permissions/android:java",
"//content/public/test/android:content_java_test_support",
"//net/android:net_java",
@@ -348,6 +377,7 @@ generate_jni("jni") {
android_library("interfaces_java") {
sources = [
"org/chromium/weblayer_private/interfaces/APICallException.java",
+ "org/chromium/weblayer_private/interfaces/ActionModeItemType.java",
"org/chromium/weblayer_private/interfaces/BrowserFragmentArgs.java",
"org/chromium/weblayer_private/interfaces/BrowsingDataType.java",
"org/chromium/weblayer_private/interfaces/CookieChangeCause.java",
@@ -359,6 +389,7 @@ android_library("interfaces_java") {
"org/chromium/weblayer_private/interfaces/NavigationState.java",
"org/chromium/weblayer_private/interfaces/NewTabType.java",
"org/chromium/weblayer_private/interfaces/ObjectWrapper.java",
+ "org/chromium/weblayer_private/interfaces/RemoteMediaServiceConstants.java",
"org/chromium/weblayer_private/interfaces/ScrollNotificationType.java",
"org/chromium/weblayer_private/interfaces/SettingType.java",
"org/chromium/weblayer_private/interfaces/SiteSettingsFragmentArgs.java",
@@ -407,6 +438,7 @@ android_aidl("aidl") {
"org/chromium/weblayer_private/interfaces/IChildProcessService.aidl",
"org/chromium/weblayer_private/interfaces/IClientDownload.aidl",
"org/chromium/weblayer_private/interfaces/IClientNavigation.aidl",
+ "org/chromium/weblayer_private/interfaces/IContextMenuParams.aidl",
"org/chromium/weblayer_private/interfaces/ICookieChangedCallbackClient.aidl",
"org/chromium/weblayer_private/interfaces/ICookieManager.aidl",
"org/chromium/weblayer_private/interfaces/ICrashReporterController.aidl",
diff --git a/chromium/weblayer/browser/java/DEPS b/chromium/weblayer/browser/java/DEPS
index 75b1b714394..7fdf4c982df 100644
--- a/chromium/weblayer/browser/java/DEPS
+++ b/chromium/weblayer/browser/java/DEPS
@@ -8,6 +8,7 @@ include_rules = [
"+components/location/android/java/src/org/chromium/components/location",
"+components/minidump_uploader",
"+components/page_info/android/java",
+ "+components/payments/content/android/java",
"+components/webapk/android/libs",
"+services/device/public/java/src/org/chromium/device/geolocation",
diff --git a/chromium/weblayer/browser/java/ResourceId.template b/chromium/weblayer/browser/java/ResourceId.template
index ed370063cb5..119965fe076 100644
--- a/chromium/weblayer/browser/java/ResourceId.template
+++ b/chromium/weblayer/browser/java/ResourceId.template
@@ -15,6 +15,7 @@ class ResourceId {
#include "components/resources/android/page_info_resource_id.h"
#include "components/resources/android/permissions_resource_id.h"
#include "components/resources/android/sms_resource_id.h"
+#include "components/resources/android/webxr_resource_id.h"
};
return resourceList;
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/ActionModeCallback.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/ActionModeCallback.java
index 6b1103e7324..4927ae672df 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/ActionModeCallback.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/ActionModeCallback.java
@@ -7,31 +7,68 @@ package org.chromium.weblayer_private;
import android.app.SearchManager;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.os.RemoteException;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
+import androidx.annotation.Nullable;
+
import org.chromium.base.PackageManagerUtils;
import org.chromium.content_public.browser.ActionModeCallbackHelper;
import org.chromium.content_public.browser.SelectionPopupController;
import org.chromium.content_public.browser.WebContents;
+import org.chromium.weblayer_private.interfaces.APICallException;
+import org.chromium.weblayer_private.interfaces.ActionModeItemType;
+import org.chromium.weblayer_private.interfaces.ITabClient;
+import org.chromium.weblayer_private.interfaces.ObjectWrapper;
/**
* A class that handles selection action mode for WebLayer.
*/
public final class ActionModeCallback implements ActionMode.Callback {
private final ActionModeCallbackHelper mHelper;
+ // Can be null during init.
+ private @Nullable ITabClient mTabClient;
+
+ // Bitfield of @ActionModeItemType values.
+ private int mActionModeOverride;
+
+ // Convert from content ActionModeCallbackHelper.MENU_ITEM_* values to
+ // @ActionModeItemType values.
+ private static int contentToWebLayerType(int contentType) {
+ switch (contentType) {
+ case ActionModeCallbackHelper.MENU_ITEM_SHARE:
+ return ActionModeItemType.SHARE;
+ case ActionModeCallbackHelper.MENU_ITEM_WEB_SEARCH:
+ return ActionModeItemType.WEB_SEARCH;
+ case ActionModeCallbackHelper.MENU_ITEM_PROCESS_TEXT:
+ case 0:
+ return 0;
+ default:
+ assert false;
+ return 0;
+ }
+ }
public ActionModeCallback(WebContents webContents) {
mHelper =
SelectionPopupController.fromWebContents(webContents).getActionModeCallbackHelper();
}
+ public void setTabClient(ITabClient tabClient) {
+ mTabClient = tabClient;
+ }
+
+ public void setOverride(int actionModeItemTypes) {
+ mActionModeOverride = actionModeItemTypes;
+ }
+
@Override
public final boolean onCreateActionMode(ActionMode mode, Menu menu) {
int allowedActionModes = ActionModeCallbackHelper.MENU_ITEM_PROCESS_TEXT
| ActionModeCallbackHelper.MENU_ITEM_SHARE;
- if (isWebSearchAvailable()) {
+ if ((mActionModeOverride & ActionModeItemType.WEB_SEARCH) != 0 || isWebSearchAvailable()) {
allowedActionModes |= ActionModeCallbackHelper.MENU_ITEM_WEB_SEARCH;
}
mHelper.setAllowedMenuItems(allowedActionModes);
@@ -53,7 +90,19 @@ public final class ActionModeCallback implements ActionMode.Callback {
@Override
public final boolean onActionItemClicked(ActionMode mode, MenuItem item) {
- return mHelper.onActionItemClicked(mode, item);
+ int menuItemType = contentToWebLayerType(mHelper.getAllowedMenuItemIfAny(mode, item));
+ if ((menuItemType & mActionModeOverride) == 0) {
+ return mHelper.onActionItemClicked(mode, item);
+ }
+ assert WebLayerFactoryImpl.getClientMajorVersion() >= 88;
+ try {
+ mTabClient.onActionItemClicked(
+ menuItemType, ObjectWrapper.wrap(mHelper.getSelectedText()));
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ mode.finish();
+ return true;
}
@Override
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserControlsContainerView.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserControlsContainerView.java
index f842c3a3c6e..131769baba0 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserControlsContainerView.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserControlsContainerView.java
@@ -161,6 +161,11 @@ class BrowserControlsContainerView extends FrameLayout {
* Requests that the browser controls visibility state be changed.
*/
void setAnimationConstraint(@BrowserControlsState int constraint);
+
+ /**
+ * Called when the offset of the controls changes.
+ */
+ void onOffsetsChanged(boolean isTop, int controlsOffset);
}
BrowserControlsContainerView(Context context, ContentViewRenderView contentViewRenderView,
@@ -371,7 +376,12 @@ class BrowserControlsContainerView extends FrameLayout {
mLastHeight = height;
if (mLastWidth > 0 && mLastHeight > 0 && mViewResourceAdapter == null) {
createAdapterAndLayer();
- if (mLastShownAmountWithView == DEFAULT_LAST_SHOWN_AMOUNT && mSavedState != null) {
+ if (mIsFullscreen) {
+ // This calls setControlsOffset() as onOffsetsChanged() does (mostly) nothing when
+ // fullscreen.
+ setControlsOffset(mIsTop ? -mLastHeight : mLastHeight, 0);
+ } else if (mLastShownAmountWithView == DEFAULT_LAST_SHOWN_AMOUNT
+ && mSavedState != null) {
// If there wasn't a View before and we have non-empty saved state from a previous
// BrowserControlsContainerView instance, apply those saved offsets now. We can't
// rely on BrowserControlsOffsetManager to notify us of the correct location as we
@@ -498,6 +508,7 @@ class BrowserControlsContainerView extends FrameLayout {
BrowserControlsContainerViewJni.get().setBottomControlsOffset(
mNativeBrowserControlsContainerView);
}
+ mDelegate.onOffsetsChanged(mIsTop, mControlsOffset);
}
private void reportHeightChange() {
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java
index 689b89e8df8..534373f07d3 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserImpl.java
@@ -71,12 +71,20 @@ public class BrowserImpl extends IBrowser.Stub implements View.OnAttachStateChan
private final UrlBarControllerImpl mUrlBarController;
private boolean mFragmentStarted;
private boolean mFragmentResumed;
- private boolean mFragmentStoppedForConfigurationChange;
+
+ // Tracks whether the fragment is in the middle of a configuration change and was attached when
+ // the configuration change started. This is set to true in onFragmentStop() and false when
+ // isViewAttachedToWindow() is true in either onViewAttachedToWindow() or onFragmentStarted().
+ // It's important to only set this to false when isViewAttachedToWindow() is true, as otherwise
+ // the WebContents may be prematurely hidden.
+ private boolean mInConfigurationChangeAndWasAttached;
+
// Cache the value instead of querying system every time.
private Boolean mPasswordEchoEnabled;
private Boolean mDarkThemeEnabled;
private Float mFontScale;
private boolean mViewAttachedToWindow;
+ private boolean mNotifyOnBrowserControlsOffsetsChanged;
// Created in the constructor from saved state and used in setClient().
private PersistenceInfo mPersistenceInfo;
@@ -156,7 +164,7 @@ public class BrowserImpl extends IBrowser.Stub implements View.OnAttachStateChan
mWindowAndroid = windowAndroid;
mEmbedderActivityContext = embedderAppContext;
mViewController = new BrowserViewController(
- windowAndroid, this, mViewControllerState, mFragmentStoppedForConfigurationChange);
+ windowAndroid, this, mViewControllerState, mInConfigurationChangeAndWasAttached);
mLocaleReceiver = new LocaleChangedBroadcastReceiver(windowAndroid.getContext().get());
mPasswordEchoEnabled = null;
}
@@ -231,8 +239,10 @@ public class BrowserImpl extends IBrowser.Stub implements View.OnAttachStateChan
@Override
public TabImpl createTab() {
- TabImpl tab = new TabImpl(mProfile, mWindowAndroid);
- addTab(tab);
+ TabImpl tab = new TabImpl(this, mProfile, mWindowAndroid);
+ // This needs |alwaysAdd| set to true as the Tab is created with the Browser already set to
+ // this.
+ addTab(tab, /* alwaysAdd */ true);
return tab;
}
@@ -282,14 +292,17 @@ public class BrowserImpl extends IBrowser.Stub implements View.OnAttachStateChan
@Override
public void addTab(ITab iTab) {
StrictModeWorkaround.apply();
- TabImpl tab = (TabImpl) iTab;
- if (tab.getBrowser() == this) return;
+ addTab((TabImpl) iTab, /* alwaysAdd */ false);
+ }
+
+ private void addTab(TabImpl tab, boolean alwaysAdd) {
+ if (!alwaysAdd && tab.getBrowser() == this) return;
BrowserImplJni.get().addTab(mNativeBrowser, tab.getNativeTab());
}
@CalledByNative
private void createJavaTabForNativeTab(long nativeTab) {
- new TabImpl(mProfile, mWindowAndroid, nativeTab);
+ new TabImpl(this, mProfile, mWindowAndroid, nativeTab);
}
private void checkPreferences() {
@@ -356,36 +369,23 @@ public class BrowserImpl extends IBrowser.Stub implements View.OnAttachStateChan
}
@CalledByNative
- private void onTabAdded(TabImpl tab) {
+ private void onTabAdded(TabImpl tab) throws RemoteException {
tab.attachToBrowser(this);
- try {
- if (mClient != null) mClient.onTabAdded(tab);
- } catch (RemoteException e) {
- throw new APICallException(e);
- }
+ if (mClient != null) mClient.onTabAdded(tab);
}
@CalledByNative
- private void onActiveTabChanged(TabImpl tab) {
+ private void onActiveTabChanged(TabImpl tab) throws RemoteException {
if (mViewController != null) mViewController.setActiveTab(tab);
- if (mInDestroy) return;
- try {
- if (mClient != null) {
- mClient.onActiveTabChanged(tab != null ? tab.getId() : 0);
- }
- } catch (RemoteException e) {
- throw new APICallException(e);
+ if (!mInDestroy && mClient != null) {
+ mClient.onActiveTabChanged(tab != null ? tab.getId() : 0);
}
}
@CalledByNative
- private void onTabRemoved(TabImpl tab) {
+ private void onTabRemoved(TabImpl tab) throws RemoteException {
if (mInDestroy) return;
- try {
- if (mClient != null) mClient.onTabRemoved(tab.getId());
- } catch (RemoteException e) {
- throw new APICallException(e);
- }
+ if (mClient != null) mClient.onTabRemoved(tab.getId());
// This doesn't reset state on TabImpl as |browser| is either about to be
// destroyed, or switching to a different fragment.
}
@@ -471,6 +471,21 @@ public class BrowserImpl extends IBrowser.Stub implements View.OnAttachStateChan
}
@Override
+ public void setBrowserControlsOffsetsEnabled(boolean enable) {
+ mNotifyOnBrowserControlsOffsetsChanged = enable;
+ }
+
+ public void onBrowserControlsOffsetsChanged(TabImpl tab, boolean isTop, int controlsOffset) {
+ if (mNotifyOnBrowserControlsOffsetsChanged && tab == getActiveTab()) {
+ try {
+ mClient.onBrowserControlsOffsetsChanged(isTop, controlsOffset);
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+ }
+
+ @Override
public boolean isRestoringPreviousState() {
return BrowserImplJni.get().isRestoringPreviousState(mNativeBrowser);
}
@@ -504,15 +519,17 @@ public class BrowserImpl extends IBrowser.Stub implements View.OnAttachStateChan
}
public void onFragmentStart() {
- mFragmentStoppedForConfigurationChange = false;
mFragmentStarted = true;
+ if (mViewAttachedToWindow) {
+ mInConfigurationChangeAndWasAttached = false;
+ }
BrowserImplJni.get().onFragmentStart(mNativeBrowser);
updateAllTabs();
checkPreferences();
}
public void onFragmentStop(boolean forConfigurationChange) {
- mFragmentStoppedForConfigurationChange = forConfigurationChange;
+ mInConfigurationChangeAndWasAttached = forConfigurationChange;
mFragmentStarted = false;
updateAllTabs();
}
@@ -536,8 +553,8 @@ public class BrowserImpl extends IBrowser.Stub implements View.OnAttachStateChan
return mFragmentResumed;
}
- public boolean isFragmentStoppedForConfigurationChange() {
- return mFragmentStoppedForConfigurationChange;
+ public boolean isInConfigurationChangeAndWasAttached() {
+ return mInConfigurationChangeAndWasAttached;
}
public boolean isViewAttachedToWindow() {
@@ -547,6 +564,9 @@ public class BrowserImpl extends IBrowser.Stub implements View.OnAttachStateChan
@Override
public void onViewAttachedToWindow(View v) {
mViewAttachedToWindow = true;
+ if (mFragmentStarted) {
+ mInConfigurationChangeAndWasAttached = false;
+ }
updateAllTabsViewAttachedState();
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserViewController.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserViewController.java
index fd9628bb755..013a665589a 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserViewController.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/BrowserViewController.java
@@ -270,6 +270,12 @@ public final class BrowserViewController
}
@Override
+ public void onOffsetsChanged(boolean isTop, int controlsOffset) {
+ if (mTab == null) return;
+ mTab.getBrowser().onBrowserControlsOffsetsChanged(mTab, isTop, controlsOffset);
+ }
+
+ @Override
public void onGestureStateChanged() {
// This is called from |mGestureStateTracker|.
assert mGestureStateTracker != null;
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java
index 983632cae0d..2619d519d0f 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/ContentViewRenderView.java
@@ -24,6 +24,7 @@ import android.widget.FrameLayout;
import android.widget.RelativeLayout;
import androidx.annotation.IntDef;
+import androidx.annotation.Nullable;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
@@ -677,7 +678,7 @@ public class ContentViewRenderView
ContentViewRenderViewJni.get().init(ContentViewRenderView.this, rootWindow);
assert mNativeContentViewRenderView != 0;
mWindowAndroid = rootWindow;
- requestMode(mode, (Boolean result) -> {});
+ requestMode(mode, null);
mDisplayAndroidObserver = new DisplayAndroid.DisplayAndroidObserver() {
@Override
public void onRotationChanged(int rotation) {
@@ -689,10 +690,9 @@ public class ContentViewRenderView
updateBackgroundColor();
}
- public void requestMode(@Mode int mode, ValueCallback<Boolean> callback) {
+ public void requestMode(@Mode int mode, @Nullable ValueCallback<Boolean> callback) {
boolean allowSurfaceControl = !mSelectionHandlesActive;
assert mode == MODE_SURFACE_VIEW || mode == MODE_TEXTURE_VIEW;
- assert callback != null;
if (mRequested != null
&& (mRequested.getMode() != mode
|| mRequested.getAllowSurfaceControl() != allowSurfaceControl)) {
@@ -710,7 +710,7 @@ public class ContentViewRenderView
listener.setRequestData(mRequested);
}
assert mRequested.getMode() == mode;
- mRequested.addCallback(callback);
+ if (callback != null) mRequested.addCallback(callback);
}
/**
@@ -805,7 +805,7 @@ public class ContentViewRenderView
// requestMode will take into account the updated |mSelectionHandlesActive|
// and respond appropriately, even if mode is the same.
- requestMode(mCurrent.getMode(), (Boolean result) -> {});
+ requestMode(mCurrent.getMode(), null);
}
public InsetObserverView getInsetObserverView() {
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/CookieManagerImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/CookieManagerImpl.java
index e2c56ccc4d6..ba3e80a7566 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/CookieManagerImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/CookieManagerImpl.java
@@ -11,7 +11,6 @@ import org.chromium.base.Callback;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
-import org.chromium.weblayer_private.interfaces.APICallException;
import org.chromium.weblayer_private.interfaces.CookieChangeCause;
import org.chromium.weblayer_private.interfaces.ICookieChangedCallbackClient;
import org.chromium.weblayer_private.interfaces.ICookieManager;
@@ -73,13 +72,9 @@ public final class CookieManagerImpl extends ICookieManager.Stub {
}
@CalledByNative
- private static void onCookieChange(
- ICookieChangedCallbackClient callback, String cookie, int cause) {
- try {
- callback.onCookieChanged(cookie, mojoCauseToJavaType(cause));
- } catch (RemoteException e) {
- throw new APICallException(e);
- }
+ private static void onCookieChange(ICookieChangedCallbackClient callback, String cookie,
+ int cause) throws RemoteException {
+ callback.onCookieChanged(cookie, mojoCauseToJavaType(cause));
}
@CookieChangeCause
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/CrashReporterControllerImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/CrashReporterControllerImpl.java
index 244b369f07a..4fc1c2f39dd 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/CrashReporterControllerImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/CrashReporterControllerImpl.java
@@ -82,6 +82,14 @@ public final class CrashReporterControllerImpl extends ICrashReporterController.
AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
TraceEvent.instant(TAG, "CrashReporterController: Begin uploading crash");
File minidumpFile = getCrashFileManager().getCrashFileWithLocalId(localId);
+ if (minidumpFile == null) {
+ try {
+ mClient.onCrashUploadFailed(localId, "invalid crash id");
+ } catch (RemoteException e) {
+ throw new AndroidRuntimeException(e);
+ }
+ return;
+ }
MinidumpUploader.Result result = new MinidumpUploader().upload(minidumpFile);
if (result.isSuccess()) {
CrashFileManager.markUploadSuccess(minidumpFile);
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/FaviconCallbackProxy.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/FaviconCallbackProxy.java
index 3c74a6dcd1b..219560ada96 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/FaviconCallbackProxy.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/FaviconCallbackProxy.java
@@ -53,6 +53,7 @@ public final class FaviconCallbackProxy extends IFaviconFetcher.Stub {
@CalledByNative
private void onFaviconChanged(Bitmap bitmap) throws RemoteException {
+ mTab.onFaviconChanged(bitmap);
mClient.onFaviconChanged(bitmap);
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/MojoInterfaceRegistrar.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/MojoInterfaceRegistrar.java
index d124792cd0d..ec49f06da6e 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/MojoInterfaceRegistrar.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/MojoInterfaceRegistrar.java
@@ -6,8 +6,11 @@ package org.chromium.weblayer_private;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.content_public.browser.InterfaceRegistrar;
+import org.chromium.content_public.browser.RenderFrameHost;
import org.chromium.content_public.browser.WebContents;
+import org.chromium.payments.mojom.PaymentRequest;
import org.chromium.services.service_manager.InterfaceRegistry;
+import org.chromium.weblayer_private.payments.WebLayerPaymentRequestFactory;
import org.chromium.webshare.mojom.ShareService;
/**
@@ -17,6 +20,8 @@ class MojoInterfaceRegistrar {
@CalledByNative
private static void registerMojoInterfaces() {
InterfaceRegistrar.Registry.addWebContentsRegistrar(new WebContentsInterfaceRegistrar());
+ InterfaceRegistrar.Registry.addRenderFrameHostRegistrar(
+ new RenderFrameHostInterfaceRegistrar());
}
private static class WebContentsInterfaceRegistrar implements InterfaceRegistrar<WebContents> {
@@ -25,4 +30,14 @@ class MojoInterfaceRegistrar {
registry.addInterface(ShareService.MANAGER, new WebShareServiceFactory(webContents));
}
}
+
+ private static class RenderFrameHostInterfaceRegistrar
+ implements InterfaceRegistrar<RenderFrameHost> {
+ @Override
+ public void registerInterfaces(
+ InterfaceRegistry registry, final RenderFrameHost renderFrameHost) {
+ registry.addInterface(
+ PaymentRequest.MANAGER, new WebLayerPaymentRequestFactory(renderFrameHost));
+ }
+ }
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/NavigationControllerImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/NavigationControllerImpl.java
index 3151068451c..0436c92162e 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/NavigationControllerImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/NavigationControllerImpl.java
@@ -5,8 +5,10 @@
package org.chromium.weblayer_private;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.webkit.WebResourceResponse;
+import org.chromium.base.TimeUtilsJni;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
@@ -28,6 +30,10 @@ public final class NavigationControllerImpl extends INavigationController.Stub {
private long mNativeNavigationController;
private INavigationControllerClient mNavigationControllerClient;
+ // Conversion between native TimeTicks and SystemClock.uptimeMillis().
+ private long mNativeTickOffsetUs;
+ private boolean mNativeTickOffsetUsComputed;
+
public NavigationControllerImpl(TabImpl tab, INavigationControllerClient client) {
mTab = tab;
mNavigationControllerClient = client;
@@ -215,11 +221,43 @@ public final class NavigationControllerImpl extends INavigationController.Stub {
}
@CalledByNative
+ private void onFirstContentfulPaint2(
+ long navigationStartTick, long firstContentfulPaintDurationMs) throws RemoteException {
+ if (WebLayerFactoryImpl.getClientMajorVersion() < 88) return;
+
+ mNavigationControllerClient.onFirstContentfulPaint2(
+ (navigationStartTick - getNativeTickOffsetUs()) / 1000,
+ firstContentfulPaintDurationMs);
+ }
+
+ @CalledByNative
+ private void onLargestContentfulPaint(long navigationStartTick,
+ long largestContentfulPaintDurationMs) throws RemoteException {
+ if (WebLayerFactoryImpl.getClientMajorVersion() < 88) return;
+
+ mNavigationControllerClient.onLargestContentfulPaint(
+ (navigationStartTick - getNativeTickOffsetUs()) / 1000,
+ largestContentfulPaintDurationMs);
+ }
+
+ @CalledByNative
private void onOldPageNoLongerRendered(String uri) throws RemoteException {
if (WebLayerFactoryImpl.getClientMajorVersion() < 85) return;
mNavigationControllerClient.onOldPageNoLongerRendered(uri);
}
+ private long getNativeTickOffsetUs() {
+ // See logic in CustomTabsConnection.java that this was based on.
+ if (!mNativeTickOffsetUsComputed) {
+ // Compute offset from time ticks to uptimeMillis.
+ mNativeTickOffsetUsComputed = true;
+ long nativeNowUs = TimeUtilsJni.get().getTimeTicksNowUs();
+ long javaNowUs = SystemClock.uptimeMillis() * 1000;
+ mNativeTickOffsetUs = nativeNowUs - javaNowUs;
+ }
+ return mNativeTickOffsetUs;
+ }
+
private static final class NavigateParamsImpl extends INavigateParams.Stub {
private boolean mReplaceCurrentEntry;
private boolean mIntentProcessingDisabled;
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/NavigationImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/NavigationImpl.java
index 7815edb19f1..1430e36d1d4 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/NavigationImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/NavigationImpl.java
@@ -161,6 +161,13 @@ public final class NavigationImpl extends INavigation.Stub {
return NavigationImplJni.get().isReload(mNativeNavigationImpl);
}
+ @Override
+ public void disableNetworkErrorAutoReload() {
+ if (!NavigationImplJni.get().disableNetworkErrorAutoReload(mNativeNavigationImpl)) {
+ throw new IllegalStateException();
+ }
+ }
+
private void throwIfNativeDestroyed() {
if (mNativeNavigationImpl == 0) {
throw new IllegalStateException("Using Navigation after native destroyed");
@@ -182,6 +189,8 @@ public final class NavigationImpl extends INavigation.Stub {
return LoadError.CONNECTIVITY_ERROR;
case ImplLoadError.OTHER_ERROR:
return LoadError.OTHER_ERROR;
+ case ImplLoadError.SAFE_BROWSING_ERROR:
+ return LoadError.SAFE_BROWSING_ERROR;
default:
throw new IllegalArgumentException("Unexpected load error " + loadError);
}
@@ -211,5 +220,6 @@ public final class NavigationImpl extends INavigation.Stub {
boolean setUserAgentString(long nativeNavigationImpl, String value);
boolean isPageInitiated(long nativeNavigationImpl);
boolean isReload(long nativeNavigationImpl);
+ boolean disableNetworkErrorAutoReload(long nativeNavigationImpl);
}
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/PageInfoControllerDelegateImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/PageInfoControllerDelegateImpl.java
index 0979cab4c25..0bd9d7b7e58 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/PageInfoControllerDelegateImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/PageInfoControllerDelegateImpl.java
@@ -12,6 +12,7 @@ import android.graphics.drawable.Drawable;
import android.webkit.ValueCallback;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import org.chromium.base.Callback;
import org.chromium.base.StrictModeContext;
@@ -127,6 +128,12 @@ public class PageInfoControllerDelegateImpl extends PageInfoControllerDelegate {
}));
}
+ @Override
+ @Nullable
+ public Drawable getPreviewUiIcon() {
+ return null;
+ }
+
private static boolean isHttpOrHttps(GURL url) {
String scheme = url.getScheme();
return UrlConstants.HTTP_SCHEME.equals(scheme) || UrlConstants.HTTPS_SCHEME.equals(scheme);
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java
index 96d559d7931..1fc0f36e619 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java
@@ -4,7 +4,9 @@
package org.chromium.weblayer_private;
+import android.Manifest.permission;
import android.app.Activity;
+import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.RectF;
import android.os.Build;
@@ -19,6 +21,7 @@ import android.view.ViewStructure;
import android.view.autofill.AutofillValue;
import android.webkit.ValueCallback;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
@@ -34,6 +37,7 @@ import org.chromium.components.browser_ui.util.BrowserControlsVisibilityDelegate
import org.chromium.components.browser_ui.util.ComposedBrowserControlsVisibilityDelegate;
import org.chromium.components.browser_ui.widget.InsetObserverView;
import org.chromium.components.embedder_support.contextmenu.ContextMenuParams;
+import org.chromium.components.embedder_support.util.UrlUtilities;
import org.chromium.components.external_intents.InterceptNavigationDelegateImpl;
import org.chromium.components.find_in_page.FindInPageBridge;
import org.chromium.components.find_in_page.FindMatchRectsDetails;
@@ -55,6 +59,7 @@ import org.chromium.ui.base.ViewAndroidDelegate;
import org.chromium.ui.base.WindowAndroid;
import org.chromium.url.GURL;
import org.chromium.weblayer_private.interfaces.APICallException;
+import org.chromium.weblayer_private.interfaces.IContextMenuParams;
import org.chromium.weblayer_private.interfaces.IDownloadCallbackClient;
import org.chromium.weblayer_private.interfaces.IErrorPageCallbackClient;
import org.chromium.weblayer_private.interfaces.IFaviconFetcher;
@@ -100,9 +105,8 @@ public final class TabImpl extends ITab.Stub {
private FullscreenCallbackProxy mFullscreenCallbackProxy;
private TabViewAndroidDelegate mViewAndroidDelegate;
private GoogleAccountsCallbackProxy mGoogleAccountsCallbackProxy;
- // BrowserImpl this TabImpl is in. This is null before attached to a Browser. While this is null
- // before attached, there are code paths that may trigger calling methods before set.
- @Nullable
+ // BrowserImpl this TabImpl is in.
+ @NonNull
private BrowserImpl mBrowser;
/**
* The AutofillProvider that integrates with system-level autofill. This is null until
@@ -138,6 +142,7 @@ public final class TabImpl extends ITab.Stub {
private DisplayCutoutController mDisplayCutoutController;
private boolean mPostContainerViewInitDone;
+ private ActionModeCallback mActionModeCallback;
private WebLayerAccessibilityUtil.Observer mAccessibilityObserver;
@@ -236,7 +241,8 @@ public final class TabImpl extends ITab.Stub {
return sTabMap.get(tabId);
}
- public TabImpl(ProfileImpl profile, WindowAndroid windowAndroid) {
+ public TabImpl(BrowserImpl browser, ProfileImpl profile, WindowAndroid windowAndroid) {
+ mBrowser = browser;
mId = ++sNextId;
init(profile, windowAndroid, TabImplJni.get().createTab(profile.getNativeProfile(), this));
}
@@ -245,8 +251,10 @@ public final class TabImpl extends ITab.Stub {
* This constructor is called when the native side triggers creation of a TabImpl
* (as happens with popups and other scenarios).
*/
- public TabImpl(ProfileImpl profile, WindowAndroid windowAndroid, long nativeTab) {
+ public TabImpl(
+ BrowserImpl browser, ProfileImpl profile, WindowAndroid windowAndroid, long nativeTab) {
mId = ++sNextId;
+ mBrowser = browser;
TabImplJni.get().setJavaImpl(nativeTab, TabImpl.this);
init(profile, windowAndroid, nativeTab);
}
@@ -308,7 +316,7 @@ public final class TabImpl extends ITab.Stub {
// before installing this observer.
if (WebLayerFactoryImpl.getClientMajorVersion() >= 85) {
mMediaSessionHelper = new MediaSessionHelper(
- mWebContents, MediaSessionManager.createMediaSessionHelperDelegate(mId));
+ mWebContents, MediaSessionManager.createMediaSessionHelperDelegate(this));
}
}
@@ -318,7 +326,8 @@ public final class TabImpl extends ITab.Stub {
mPostContainerViewInitDone = true;
SelectionPopupController controller =
SelectionPopupController.fromWebContents(mWebContents);
- controller.setActionModeCallback(new ActionModeCallback(mWebContents));
+ mActionModeCallback = new ActionModeCallback(mWebContents);
+ controller.setActionModeCallback(mActionModeCallback);
controller.setSelectionClient(SelectionClient.createSmartSelectionClient(mWebContents));
}
@@ -334,6 +343,9 @@ public final class TabImpl extends ITab.Stub {
* Sets the BrowserImpl this TabImpl is contained in.
*/
public void attachToBrowser(BrowserImpl browser) {
+ // NOTE: during tab creation this is called with |mBrowser| set to |browser|. This happens
+ // because the tab is created with |mBrowser| already set (to avoid having a bunch of null
+ // checks).
mBrowser = browser;
updateFromBrowser();
}
@@ -417,7 +429,6 @@ public final class TabImpl extends ITab.Stub {
public void onAttachedToViewController(
long topControlsContainerViewHandle, long bottomControlsContainerViewHandle) {
// attachToFragment() must be called before activate().
- assert mBrowser != null;
TabImplJni.get().setBrowserControlsContainerViews(
mNativeTab, topControlsContainerViewHandle, bottomControlsContainerViewHandle);
mInfoBarContainer.onTabAttachedToViewController();
@@ -454,7 +465,7 @@ public final class TabImpl extends ITab.Stub {
public boolean isVisible() {
return isActiveTab()
&& ((mBrowser.isStarted() && mBrowser.isViewAttachedToWindow())
- || mBrowser.isFragmentStoppedForConfigurationChange());
+ || mBrowser.isInConfigurationChangeAndWasAttached());
}
@CalledByNative
@@ -469,7 +480,7 @@ public final class TabImpl extends ITab.Stub {
}
public boolean isActiveTab() {
- return mBrowser != null && mBrowser.getActiveTab() == this;
+ return mBrowser.getActiveTab() == this;
}
private void updateWebContentsVisibility() {
@@ -529,6 +540,7 @@ public final class TabImpl extends ITab.Stub {
StrictModeWorkaround.apply();
mClient = client;
mTabCallbackProxy = new TabCallbackProxy(mNativeTab, client);
+ mActionModeCallback.setTabClient(mClient);
}
@Override
@@ -596,11 +608,13 @@ public final class TabImpl extends ITab.Stub {
@Override
public void setTranslateTargetLanguage(String targetLanguage) {
+ StrictModeWorkaround.apply();
TabImplJni.get().setTranslateTargetLanguage(mNativeTab, targetLanguage);
}
@Override
public void setScrollOffsetsEnabled(boolean enabled) {
+ StrictModeWorkaround.apply();
if (enabled) {
if (mGestureStateListenerWithScroll == null) {
mGestureStateListenerWithScroll = new GestureStateListenerWithScroll() {
@@ -624,6 +638,49 @@ public final class TabImpl extends ITab.Stub {
}
}
+ @Override
+ public void setFloatingActionModeOverride(int actionModeItemTypes) {
+ StrictModeWorkaround.apply();
+ mActionModeCallback.setOverride(actionModeItemTypes);
+ }
+
+ @Override
+ public void setDesktopUserAgentEnabled(boolean enable) {
+ StrictModeWorkaround.apply();
+ TabImplJni.get().setDesktopUserAgentEnabled(mNativeTab, enable);
+ }
+
+ @Override
+ public boolean isDesktopUserAgentEnabled() {
+ StrictModeWorkaround.apply();
+ return TabImplJni.get().isDesktopUserAgentEnabled(mNativeTab);
+ }
+
+ @Override
+ public void download(IContextMenuParams contextMenuParams) {
+ StrictModeWorkaround.apply();
+ NativeContextMenuParamsHolder nativeContextMenuParamsHolder =
+ (NativeContextMenuParamsHolder) contextMenuParams;
+
+ WindowAndroid window = getBrowser().getWindowAndroid();
+ if (window.hasPermission(permission.WRITE_EXTERNAL_STORAGE)) {
+ continueDownload(nativeContextMenuParamsHolder);
+ return;
+ }
+
+ String[] requestPermissions = new String[] {permission.WRITE_EXTERNAL_STORAGE};
+ window.requestPermissions(requestPermissions, (permissions, grantResults) -> {
+ if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ continueDownload(nativeContextMenuParamsHolder);
+ }
+ });
+ }
+
+ private void continueDownload(NativeContextMenuParamsHolder nativeContextMenuParamsHolder) {
+ TabImplJni.get().download(
+ mNativeTab, nativeContextMenuParamsHolder.mNativeContextMenuParams);
+ }
+
public void removeFaviconCallbackProxy(FaviconCallbackProxy proxy) {
mFaviconCallbackProxies.remove(proxy);
}
@@ -809,16 +866,12 @@ public final class TabImpl extends ITab.Stub {
}
@CalledByNative
- private void onFindResultAvailable(
- int numberOfMatches, int activeMatchOrdinal, boolean finalUpdate) {
- try {
- if (mFindInPageCallbackClient != null) {
- // The WebLayer API deals in indices instead of ordinals.
- mFindInPageCallbackClient.onFindResult(
- numberOfMatches, activeMatchOrdinal - 1, finalUpdate);
- }
- } catch (RemoteException e) {
- throw new AndroidRuntimeException(e);
+ private void onFindResultAvailable(int numberOfMatches, int activeMatchOrdinal,
+ boolean finalUpdate) throws RemoteException {
+ if (mFindInPageCallbackClient != null) {
+ // The WebLayer API deals in indices instead of ordinals.
+ mFindInPageCallbackClient.onFindResult(
+ numberOfMatches, activeMatchOrdinal - 1, finalUpdate);
}
if (mFindResultBar != null) {
@@ -947,6 +1000,11 @@ public final class TabImpl extends ITab.Stub {
mMediaStreamManager.destroy();
mMediaStreamManager = null;
+ if (mMediaSessionHelper != null) {
+ mMediaSessionHelper.destroy();
+ mMediaSessionHelper = null;
+ }
+
// Destroying FaviconCallbackProxy removes from mFaviconCallbackProxies. Copy to avoid
// problems.
Set<FaviconCallbackProxy> faviconCallbackProxies = mFaviconCallbackProxies;
@@ -1015,14 +1073,56 @@ public final class TabImpl extends ITab.Stub {
return TextUtils.isEmpty(s) ? null : s;
}
+ private static class NativeContextMenuParamsHolder extends IContextMenuParams.Stub {
+ // Note: avoid adding more members since an object with a finalizer will delay GC of any
+ // object it references.
+ private final long mNativeContextMenuParams;
+
+ NativeContextMenuParamsHolder(long nativeContextMenuParams) {
+ mNativeContextMenuParams = nativeContextMenuParams;
+ }
+
+ /**
+ * A finalizer is required to ensure that the native object associated with
+ * this object gets destructed, otherwise there would be a memory leak.
+ *
+ * This is safe because it makes a simple call into C++ code that is both
+ * thread-safe and very fast.
+ *
+ * @see java.lang.Object#finalize()
+ */
+ @Override
+ protected final void finalize() throws Throwable {
+ super.finalize();
+ TabImplJni.get().destroyContextMenuParams(mNativeContextMenuParams);
+ }
+ }
+
@CalledByNative
- private void showContextMenu(ContextMenuParams params) throws RemoteException {
+ private void showContextMenu(ContextMenuParams params, long nativeContextMenuParams)
+ throws RemoteException {
if (WebLayerFactoryImpl.getClientMajorVersion() < 82) return;
- mClient.showContextMenu(ObjectWrapper.wrap(params.getPageUrl()),
+ if (WebLayerFactoryImpl.getClientMajorVersion() < 88) {
+ mClient.showContextMenu(ObjectWrapper.wrap(params.getPageUrl()),
+ ObjectWrapper.wrap(nonEmptyOrNull(params.getLinkUrl())),
+ ObjectWrapper.wrap(nonEmptyOrNull(params.getLinkText())),
+ ObjectWrapper.wrap(nonEmptyOrNull(params.getTitleText())),
+ ObjectWrapper.wrap(nonEmptyOrNull(params.getSrcUrl())));
+ return;
+ }
+
+ boolean canDownload =
+ (params.isImage() && UrlUtilities.isDownloadableScheme(params.getSrcUrl()))
+ || (params.isVideo() && UrlUtilities.isDownloadableScheme(params.getSrcUrl())
+ && params.canSaveMedia())
+ || (params.isAnchor() && UrlUtilities.isDownloadableScheme(params.getLinkUrl()));
+ mClient.showContextMenu2(ObjectWrapper.wrap(params.getPageUrl()),
ObjectWrapper.wrap(nonEmptyOrNull(params.getLinkUrl())),
ObjectWrapper.wrap(nonEmptyOrNull(params.getLinkText())),
ObjectWrapper.wrap(nonEmptyOrNull(params.getTitleText())),
- ObjectWrapper.wrap(nonEmptyOrNull(params.getSrcUrl())));
+ ObjectWrapper.wrap(nonEmptyOrNull(params.getSrcUrl())), params.isImage(),
+ params.isVideo(), canDownload,
+ new NativeContextMenuParamsHolder(nativeContextMenuParams));
}
@VisibleForTesting
@@ -1037,8 +1137,6 @@ public final class TabImpl extends ITab.Stub {
}
private void onBrowserControlsConstraintUpdated(int constraint) {
- // WARNING: this may be called before attached. This means |mBrowser| may be null.
-
// If something has overridden the FIP's SHOWN constraint, cancel FIP. This causes FIP to
// dismiss when entering fullscreen.
if (constraint != BrowserControlsState.SHOWN) {
@@ -1105,7 +1203,11 @@ public final class TabImpl extends ITab.Stub {
@Nullable
private BrowserViewController getViewController() {
if (!isActiveTab()) return null;
- return mBrowser.getPossiblyNullViewController();
+ // During rotation it's possible for this to be called before BrowserViewController has been
+ // updated. Verify BrowserViewController reflects this is the active tab before returning
+ // it.
+ BrowserViewController viewController = mBrowser.getPossiblyNullViewController();
+ return viewController != null && viewController.getTab() == this ? viewController : null;
}
@VisibleForTesting
@@ -1123,6 +1225,13 @@ public final class TabImpl extends ITab.Stub {
return translateInfoBar.getTargetLanguageForTesting();
}
+ /** Called by {@link FaviconCallbackProxy} when the favicon for the current page has changed. */
+ public void onFaviconChanged(Bitmap bitmap) {
+ if (mMediaSessionHelper != null) {
+ mMediaSessionHelper.updateFavicon(bitmap);
+ }
+ }
+
@NativeMethods
interface Natives {
TabImpl fromWebContents(WebContents webContents);
@@ -1151,5 +1260,9 @@ public final class TabImpl extends ITab.Stub {
boolean canTranslate(long nativeTabImpl);
void showTranslateUi(long nativeTabImpl);
void setTranslateTargetLanguage(long nativeTabImpl, String targetLanguage);
+ void setDesktopUserAgentEnabled(long nativeTabImpl, boolean enable);
+ boolean isDesktopUserAgentEnabled(long nativeTabImpl);
+ void download(long nativeTabImpl, long nativeContextMenuParams);
+ void destroyContextMenuParams(long contextMenuParams);
}
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/TranslateCompactInfoBar.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/TranslateCompactInfoBar.java
index a2d2212ee72..937ba551330 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/TranslateCompactInfoBar.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/TranslateCompactInfoBar.java
@@ -21,6 +21,7 @@ import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.chrome.browser.infobar.ActionType;
+import org.chromium.chrome.browser.infobar.InfobarEvent;
import org.chromium.components.infobars.InfoBar;
import org.chromium.components.infobars.InfoBarCompactLayout;
import org.chromium.components.translate.TranslateMenu;
@@ -76,38 +77,6 @@ public class TranslateCompactInfoBar extends InfoBar
private static final String INFOBAR_HISTOGRAM_TRANSLATION_COUNT =
"Translate.CompactInfobar.TranslationsPerPage";
- /**
- * This is used to back a UMA histogram, so it should be treated as
- * append-only. The values should not be changed or reused, and
- * INFOBAR_HISTOGRAM_BOUNDARY should be the last.
- */
- private static final int INFOBAR_IMPRESSION = 0;
- private static final int INFOBAR_TARGET_TAB_TRANSLATE = 1;
- private static final int INFOBAR_DECLINE = 2;
- private static final int INFOBAR_OPTIONS = 3;
- private static final int INFOBAR_MORE_LANGUAGES = 4;
- private static final int INFOBAR_MORE_LANGUAGES_TRANSLATE = 5;
- private static final int INFOBAR_PAGE_NOT_IN = 6;
- private static final int INFOBAR_ALWAYS_TRANSLATE = 7;
- private static final int INFOBAR_NEVER_TRANSLATE = 8;
- private static final int INFOBAR_NEVER_TRANSLATE_SITE = 9;
- private static final int INFOBAR_SCROLL_HIDE = 10;
- private static final int INFOBAR_SCROLL_SHOW = 11;
- private static final int INFOBAR_REVERT = 12;
- private static final int INFOBAR_SNACKBAR_ALWAYS_TRANSLATE_IMPRESSION = 13;
- private static final int INFOBAR_SNACKBAR_NEVER_TRANSLATE_IMPRESSION = 14;
- private static final int INFOBAR_SNACKBAR_NEVER_TRANSLATE_SITE_IMPRESSION = 15;
- private static final int INFOBAR_SNACKBAR_CANCEL_ALWAYS = 16;
- private static final int INFOBAR_SNACKBAR_CANCEL_NEVER_SITE = 17;
- private static final int INFOBAR_SNACKBAR_CANCEL_NEVER = 18;
- private static final int INFOBAR_ALWAYS_TRANSLATE_UNDO = 19;
- private static final int INFOBAR_CLOSE_DEPRECATED = 20;
- private static final int INFOBAR_SNACKBAR_AUTO_ALWAYS_IMPRESSION = 21;
- private static final int INFOBAR_SNACKBAR_AUTO_NEVER_IMPRESSION = 22;
- private static final int INFOBAR_SNACKBAR_CANCEL_AUTO_ALWAYS = 23;
- private static final int INFOBAR_SNACKBAR_CANCEL_AUTO_NEVER = 24;
- private static final int INFOBAR_HISTOGRAM_BOUNDARY = 25;
-
// Need 2 instances of TranslateMenuHelper to prevent a race condition bug which happens when
// showing language menu after dismissing overflow menu.
private TranslateMenuHelper mOverflowMenuHelper;
@@ -124,7 +93,7 @@ public class TranslateCompactInfoBar extends InfoBar
private static InfoBar create(TabImpl tab, int initialStep, String sourceLanguageCode,
String targetLanguageCode, boolean alwaysTranslate, boolean triggeredFromMenu,
String[] languages, String[] languageCodes, int[] hashCodes, int tabTextColor) {
- recordInfobarAction(INFOBAR_IMPRESSION);
+ recordInfobarAction(InfobarEvent.INFOBAR_IMPRESSION);
return new TranslateCompactInfoBar(initialStep, sourceLanguageCode, targetLanguageCode,
alwaysTranslate, triggeredFromMenu, languages, languageCodes, hashCodes,
tabTextColor);
@@ -217,7 +186,7 @@ public class TranslateCompactInfoBar extends InfoBar
@Override
public void onClick(View v) {
mTabLayout.endScrollingAnimationIfPlaying();
- recordInfobarAction(INFOBAR_OPTIONS);
+ recordInfobarAction(InfobarEvent.INFOBAR_OPTIONS);
initMenuHelper(TranslateMenu.MENU_OVERFLOW);
mOverflowMenuHelper.show(TranslateMenu.MENU_OVERFLOW, getParentWidth());
mMenuExpanded = true;
@@ -298,7 +267,7 @@ public class TranslateCompactInfoBar extends InfoBar
if (isDismissed()) return;
if (!mUserInteracted) {
- recordInfobarAction(INFOBAR_DECLINE);
+ recordInfobarAction(InfobarEvent.INFOBAR_DECLINE);
}
// NOTE: In Chrome there is a check for whether auto "never translate" should be triggered
@@ -322,11 +291,11 @@ public class TranslateCompactInfoBar extends InfoBar
switch (tab.getPosition()) {
case SOURCE_TAB_INDEX:
incrementAndRecordTranslationsPerPageCount();
- recordInfobarAction(INFOBAR_REVERT);
+ recordInfobarAction(InfobarEvent.INFOBAR_REVERT);
onButtonClicked(ActionType.TRANSLATE_SHOW_ORIGINAL);
return;
case TARGET_TAB_INDEX:
- recordInfobarAction(INFOBAR_TARGET_TAB_TRANSLATE);
+ recordInfobarAction(InfobarEvent.INFOBAR_TARGET_TAB_TRANSLATE);
recordInfobarLanguageData(
INFOBAR_HISTOGRAM_TRANSLATE_LANGUAGE, mOptions.targetLanguageCode());
startTranslating(TARGET_TAB_INDEX);
@@ -346,34 +315,34 @@ public class TranslateCompactInfoBar extends InfoBar
public void onOverflowMenuItemClicked(int itemId) {
switch (itemId) {
case TranslateMenu.ID_OVERFLOW_MORE_LANGUAGE:
- recordInfobarAction(INFOBAR_MORE_LANGUAGES);
+ recordInfobarAction(InfobarEvent.INFOBAR_MORE_LANGUAGES);
initMenuHelper(TranslateMenu.MENU_TARGET_LANGUAGE);
mLanguageMenuHelper.show(TranslateMenu.MENU_TARGET_LANGUAGE, getParentWidth());
return;
case TranslateMenu.ID_OVERFLOW_ALWAYS_TRANSLATE:
// Only show snackbar when "Always Translate" is enabled.
if (!mOptions.getTranslateState(TranslateOptions.Type.ALWAYS_LANGUAGE)) {
- recordInfobarAction(INFOBAR_ALWAYS_TRANSLATE);
+ recordInfobarAction(InfobarEvent.INFOBAR_ALWAYS_TRANSLATE);
recordInfobarLanguageData(INFOBAR_HISTOGRAM_ALWAYS_TRANSLATE_LANGUAGE,
mOptions.sourceLanguageCode());
createAndShowSnackbar(ACTION_OVERFLOW_ALWAYS_TRANSLATE);
} else {
- recordInfobarAction(INFOBAR_ALWAYS_TRANSLATE_UNDO);
+ recordInfobarAction(InfobarEvent.INFOBAR_ALWAYS_TRANSLATE_UNDO);
handleTranslateOptionPostSnackbar(ACTION_OVERFLOW_ALWAYS_TRANSLATE);
}
return;
case TranslateMenu.ID_OVERFLOW_NEVER_LANGUAGE:
- recordInfobarAction(INFOBAR_NEVER_TRANSLATE);
+ recordInfobarAction(InfobarEvent.INFOBAR_NEVER_TRANSLATE);
recordInfobarLanguageData(
INFOBAR_HISTOGRAM_NEVER_TRANSLATE_LANGUAGE, mOptions.sourceLanguageCode());
createAndShowSnackbar(ACTION_OVERFLOW_NEVER_LANGUAGE);
return;
case TranslateMenu.ID_OVERFLOW_NEVER_SITE:
- recordInfobarAction(INFOBAR_NEVER_TRANSLATE_SITE);
+ recordInfobarAction(InfobarEvent.INFOBAR_NEVER_TRANSLATE_SITE);
createAndShowSnackbar(ACTION_OVERFLOW_NEVER_SITE);
return;
case TranslateMenu.ID_OVERFLOW_NOT_THIS_LANGUAGE:
- recordInfobarAction(INFOBAR_PAGE_NOT_IN);
+ recordInfobarAction(InfobarEvent.INFOBAR_PAGE_NOT_IN);
initMenuHelper(TranslateMenu.MENU_SOURCE_LANGUAGE);
mLanguageMenuHelper.show(TranslateMenu.MENU_SOURCE_LANGUAGE, getParentWidth());
return;
@@ -386,7 +355,7 @@ public class TranslateCompactInfoBar extends InfoBar
public void onTargetMenuItemClicked(String code) {
// Reset target code in both UI and native.
if (mNativeTranslateInfoBarPtr != 0 && mOptions.setTargetLanguage(code)) {
- recordInfobarAction(INFOBAR_MORE_LANGUAGES_TRANSLATE);
+ recordInfobarAction(InfobarEvent.INFOBAR_MORE_LANGUAGES_TRANSLATE);
recordInfobarLanguageData(
INFOBAR_HISTOGRAM_MORE_LANGUAGES_LANGUAGE, mOptions.targetLanguageCode());
TranslateCompactInfoBarJni.get().applyStringTranslateOption(mNativeTranslateInfoBarPtr,
@@ -536,7 +505,7 @@ public class TranslateCompactInfoBar extends InfoBar
private static void recordInfobarAction(int action) {
RecordHistogram.recordEnumeratedHistogram(
- INFOBAR_HISTOGRAM, action, INFOBAR_HISTOGRAM_BOUNDARY);
+ INFOBAR_HISTOGRAM, action, InfobarEvent.INFOBAR_HISTOGRAM_BOUNDARY);
}
private void recordInfobarLanguageData(String histogram, String langCode) {
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/UrlBarControllerImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/UrlBarControllerImpl.java
index 41e100e1b47..3c500e2a3f2 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/UrlBarControllerImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/UrlBarControllerImpl.java
@@ -8,6 +8,7 @@ import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.os.Bundle;
+import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
@@ -29,10 +30,12 @@ import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.components.content_settings.ContentSettingsType;
import org.chromium.components.embedder_support.util.Origin;
+import org.chromium.components.embedder_support.util.UrlUtilities;
import org.chromium.components.omnibox.SecurityButtonAnimationDelegate;
import org.chromium.components.omnibox.SecurityStatusIcon;
import org.chromium.components.page_info.PageInfoController;
import org.chromium.components.page_info.PermissionParamsListBuilderDelegate;
+import org.chromium.components.security_state.ConnectionSecurityLevel;
import org.chromium.content_public.browser.WebContents;
import org.chromium.weblayer_private.interfaces.IObjectWrapper;
import org.chromium.weblayer_private.interfaces.IUrlBarController;
@@ -114,6 +117,7 @@ public class UrlBarControllerImpl extends IUrlBarController.Stub {
private final UrlBarControllerImpl mController;
private float mTextSize;
private boolean mShowPageInfoWhenUrlTextClicked;
+ private boolean mShowPublisherUrl;
// These refer to the resources in the embedder's APK, not WebLayer's.
private @ColorRes int mUrlTextColor;
@@ -136,6 +140,8 @@ public class UrlBarControllerImpl extends IUrlBarController.Stub {
mTextSize = options.getFloat(UrlBarOptionsKeys.URL_TEXT_SIZE, DEFAULT_TEXT_SIZE);
mShowPageInfoWhenUrlTextClicked = options.getBoolean(
UrlBarOptionsKeys.SHOW_PAGE_INFO_WHEN_URL_TEXT_CLICKED, /*default= */ false);
+ mShowPublisherUrl =
+ options.getBoolean(UrlBarOptionsKeys.SHOW_PUBLISHER_URL, /*default= */ false);
mUrlTextColor = options.getInt(UrlBarOptionsKeys.URL_TEXT_COLOR, /*default= */ 0);
mUrlIconColor = options.getInt(UrlBarOptionsKeys.URL_ICON_COLOR, /*default= */ 0);
@@ -179,8 +185,24 @@ public class UrlBarControllerImpl extends IUrlBarController.Stub {
private void updateView() {
if (mBrowserImpl == null) return;
- String displayUrl =
- UrlBarControllerImplJni.get().getUrlForDisplay(mNativeUrlBarController);
+ int securityLevel = UrlBarControllerImplJni.get().getConnectionSecurityLevel(
+ mNativeUrlBarController);
+
+ String publisherUrl =
+ UrlBarControllerImplJni.get().getPublisherUrl(mNativeUrlBarController);
+
+ String displayUrl;
+ int securityIcon;
+ if (mShowPublisherUrl && securityLevel != ConnectionSecurityLevel.DANGEROUS
+ && !TextUtils.isEmpty(publisherUrl)) {
+ displayUrl = getContext().getResources().getString(R.string.amp_publisher_url,
+ UrlUtilities.extractPublisherFromPublisherUrl(publisherUrl));
+ securityIcon = R.drawable.amp_icon;
+ } else {
+ displayUrl = getUrlForDisplay();
+ securityIcon = getSecurityIcon();
+ }
+
mUrlTextView.setText(displayUrl);
mUrlTextView.setTextSize(
TypedValue.COMPLEX_UNIT_SP, Math.max(MINIMUM_TEXT_SIZE, mTextSize));
@@ -189,11 +211,9 @@ public class UrlBarControllerImpl extends IUrlBarController.Stub {
mUrlTextView.setTextColor(ContextCompat.getColor(embedderContext, mUrlTextColor));
}
- mSecurityButtonAnimationDelegate.updateSecurityButton(getSecurityIcon());
+ mSecurityButtonAnimationDelegate.updateSecurityButton(securityIcon);
mSecurityButton.setContentDescription(getContext().getResources().getString(
- SecurityStatusIcon.getSecurityIconContentDescriptionResourceId(
- UrlBarControllerImplJni.get().getConnectionSecurityLevel(
- mNativeUrlBarController))));
+ SecurityStatusIcon.getSecurityIconContentDescriptionResourceId(securityLevel)));
if (mUrlIconColor != 0 && embedderContext != null) {
ImageViewCompat.setImageTintList(mSecurityButton,
@@ -225,9 +245,19 @@ public class UrlBarControllerImpl extends IUrlBarController.Stub {
private void showPageInfoUi(View v) {
WebContents webContents = mBrowserImpl.getActiveTab().getWebContents();
+
+ String publisherUrl = null;
+ if (mShowPublisherUrl) {
+ String publisherUrlMaybeNull =
+ UrlBarControllerImplJni.get().getPublisherUrl(mNativeUrlBarController);
+ if (publisherUrlMaybeNull != null && !TextUtils.isEmpty(publisherUrlMaybeNull)) {
+ publisherUrl =
+ UrlUtilities.extractPublisherFromPublisherUrl(publisherUrlMaybeNull);
+ }
+ }
+
PageInfoController.show(mBrowserImpl.getWindowAndroid().getActivity().get(),
- webContents,
- /* contentPublisher= */ null, PageInfoController.OpenedFromSource.TOOLBAR,
+ webContents, publisherUrl, PageInfoController.OpenedFromSource.TOOLBAR,
PageInfoControllerDelegateImpl.create(webContents),
new PermissionParamsListBuilderDelegate(mBrowserImpl.getProfile()) {
@Override
@@ -260,6 +290,7 @@ public class UrlBarControllerImpl extends IUrlBarController.Stub {
long createUrlBarController(long browserPtr);
void deleteUrlBarController(long urlBarControllerImplPtr);
String getUrlForDisplay(long nativeUrlBarControllerImpl);
+ String getPublisherUrl(long nativeUrlBarControllerImpl);
int getConnectionSecurityLevel(long nativeUrlBarControllerImpl);
boolean shouldShowDangerTriangleForWarningLevel(long nativeUrlBarControllerImpl);
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java
index 29f8b0a1626..b15c1a39df8 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebLayerImpl.java
@@ -42,9 +42,9 @@ import org.chromium.base.TraceEvent;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.base.annotations.NativeMethods;
-import org.chromium.base.compat.ApiHelperForO;
import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.base.library_loader.LibraryProcessType;
+import org.chromium.base.metrics.RecordHistogram;
import org.chromium.components.browser_ui.contacts_picker.ContactsPickerDialog;
import org.chromium.components.browser_ui.photo_picker.DecoderServiceHost;
import org.chromium.components.browser_ui.photo_picker.ImageDecoder;
@@ -78,6 +78,7 @@ import org.chromium.weblayer_private.interfaces.IWebLayerClient;
import org.chromium.weblayer_private.interfaces.ObjectWrapper;
import org.chromium.weblayer_private.interfaces.StrictModeWorkaround;
import org.chromium.weblayer_private.media.MediaRouteDialogFragmentImpl;
+import org.chromium.weblayer_private.media.MediaRouterClientImpl;
import org.chromium.weblayer_private.media.MediaSessionManager;
import org.chromium.weblayer_private.media.MediaStreamManager;
import org.chromium.weblayer_private.metrics.MetricsServiceClient;
@@ -117,7 +118,7 @@ public final class WebLayerImpl extends IWebLayer.Stub {
// The required package ID for WebLayer when loaded as a shared library, hardcoded in the
// resources. If this value changes make sure to change _SHARED_LIBRARY_HARDCODED_ID in
// //build/android/gyp/util/protoresources.py.
- private static final int REQUIRED_PACKAGE_IDENTIFIER = 12;
+ private static final int REQUIRED_PACKAGE_IDENTIFIER = 36;
private final ProfileManager mProfileManager = new ProfileManager();
@@ -217,7 +218,6 @@ public final class WebLayerImpl extends IWebLayer.Stub {
notifyWebViewRunningInProcess(remoteContext.getClassLoader());
}
- remoteContext = processRemoteContext(remoteContext);
Context appContext = minimalInitForContext(
ObjectWrapper.unwrap(appContextWrapper, Context.class), remoteContext);
PackageInfo packageInfo = WebViewFactory.getLoadedPackageInfo();
@@ -379,7 +379,7 @@ public final class WebLayerImpl extends IWebLayer.Stub {
StrictModeWorkaround.apply();
// This is a no-op if init has already happened.
minimalInitForContext(ObjectWrapper.unwrap(appContext, Context.class),
- processRemoteContext(ObjectWrapper.unwrap(remoteContext, Context.class)));
+ ObjectWrapper.unwrap(remoteContext, Context.class));
return CrashReporterControllerImpl.getInstance();
}
@@ -411,13 +411,26 @@ public final class WebLayerImpl extends IWebLayer.Stub {
}
@Override
+ public void onRemoteMediaServiceStarted(IObjectWrapper sessionService, Intent intent) {
+ StrictModeWorkaround.apply();
+ MediaRouterClientImpl.serviceStarted(
+ ObjectWrapper.unwrap(sessionService, Service.class), intent);
+ }
+
+ @Override
+ public void onRemoteMediaServiceDestroyed(int id) {
+ StrictModeWorkaround.apply();
+ MediaRouterClientImpl.serviceDestroyed(id);
+ }
+
+ @Override
public IBinder initializeImageDecoder(IObjectWrapper appContext, IObjectWrapper remoteContext) {
StrictModeWorkaround.apply();
assert ContextUtils.getApplicationContext() == null;
CommandLine.init(null);
minimalInitForContext(ObjectWrapper.unwrap(appContext, Context.class),
- processRemoteContext(ObjectWrapper.unwrap(remoteContext, Context.class)));
+ ObjectWrapper.unwrap(remoteContext, Context.class));
LibraryLoader.getInstance().setLibraryProcessType(
LibraryProcessType.PROCESS_WEBLAYER_CHILD);
LibraryLoader.getInstance().ensureInitialized();
@@ -439,6 +452,19 @@ public final class WebLayerImpl extends IWebLayer.Stub {
public void setClient(IWebLayerClient client) {
StrictModeWorkaround.apply();
sClient = client;
+
+ if (WebLayerFactoryImpl.getClientMajorVersion() >= 88) {
+ try {
+ RecordHistogram.recordTimesHistogram("WebLayer.Startup.ClassLoaderCreationTime",
+ sClient.getClassLoaderCreationTime());
+ RecordHistogram.recordTimesHistogram(
+ "WebLayer.Startup.ContextCreationTime", sClient.getContextCreationTime());
+ RecordHistogram.recordTimesHistogram("WebLayer.Startup.WebLayerLoaderCreationTime",
+ sClient.getWebLayerLoaderCreationTime());
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
}
@Override
@@ -506,6 +532,42 @@ public final class WebLayerImpl extends IWebLayer.Stub {
}
}
+ public static Intent createRemoteMediaServiceIntent() {
+ if (sClient == null) {
+ throw new IllegalStateException("WebLayer should have been initialized already.");
+ }
+
+ try {
+ return sClient.createRemoteMediaServiceIntent();
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
+ public static int getPresentationApiNotificationId() {
+ if (sClient == null) {
+ throw new IllegalStateException("WebLayer should have been initialized already.");
+ }
+
+ try {
+ return sClient.getPresentationApiNotificationId();
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
+ public static int getRemotePlaybackApiNotificationId() {
+ if (sClient == null) {
+ throw new IllegalStateException("WebLayer should have been initialized already.");
+ }
+
+ try {
+ return sClient.getRemotePlaybackApiNotificationId();
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
public static String getClientApplicationName() {
Context context = ContextUtils.getApplicationContext();
return new StringBuilder()
@@ -606,6 +668,10 @@ public final class WebLayerImpl extends IWebLayer.Stub {
/** Forces adding entries to the package identifiers array until we hit the required ID. */
private static void forceAddAssetPaths(Context remoteContext, int packageId) {
+ if (packageId > REQUIRED_PACKAGE_IDENTIFIER) {
+ throw new AndroidRuntimeException(
+ "WebLayer package ID too large, aborting: " + packageId);
+ }
try {
Method addAssetPath = AssetManager.class.getMethod("addAssetPath", String.class);
String path = remoteContext.getApplicationInfo().sourceDir;
@@ -823,18 +889,6 @@ public final class WebLayerImpl extends IWebLayer.Stub {
}
}
- private static Context processRemoteContext(Context remoteContext) {
- // If WebLayer is in a DFM, make sure the correct resources are used.
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- try {
- return ApiHelperForO.createContextForSplit(remoteContext, "weblayer");
- } catch (PackageManager.NameNotFoundException e) {
- // WebLayer is not in a split, the original context will have the resources.
- }
- }
- return remoteContext;
- }
-
private static Context createContextForMode(Context remoteContext, int uiMode) {
Configuration configuration = new Configuration();
configuration.uiMode = uiMode;
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebMessageReplyProxyImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebMessageReplyProxyImpl.java
index d639a42cf3a..980275d0eb3 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebMessageReplyProxyImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/WebMessageReplyProxyImpl.java
@@ -44,22 +44,14 @@ public final class WebMessageReplyProxyImpl extends IWebMessageReplyProxy.Stub {
}
@CalledByNative
- private void onNativeDestroyed() {
+ private void onNativeDestroyed() throws RemoteException {
mNativeWebMessageReplyProxyImpl = 0;
- try {
- mClient.onReplyProxyDestroyed(mId);
- } catch (RemoteException e) {
- throw new APICallException(e);
- }
+ mClient.onReplyProxyDestroyed(mId);
}
@CalledByNative
- private void onPostMessage(String message) {
- try {
- mClient.onPostMessage(mId, message);
- } catch (RemoteException e) {
- throw new APICallException(e);
- }
+ private void onPostMessage(String message) throws RemoteException {
+ mClient.onPostMessage(mId, message);
}
@Override
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ActionModeItemType.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ActionModeItemType.java
new file mode 100644
index 00000000000..bbce175453d
--- /dev/null
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ActionModeItemType.java
@@ -0,0 +1,17 @@
+// 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_private.interfaces;
+
+import androidx.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@IntDef({ActionModeItemType.SHARE, ActionModeItemType.WEB_SEARCH})
+@Retention(RetentionPolicy.SOURCE)
+public @interface ActionModeItemType {
+ int SHARE = 1 << 0;
+ int WEB_SEARCH = 1 << 1;
+}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBrowser.aidl b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBrowser.aidl
index 485e4b45769..950df71a49e 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBrowser.aidl
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBrowser.aidl
@@ -43,4 +43,7 @@ interface IBrowser {
// Added in 87.
boolean isRestoringPreviousState() = 14;
+
+ // Added in 88.
+ void setBrowserControlsOffsetsEnabled(in boolean enable) = 13;
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBrowserClient.aidl b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBrowserClient.aidl
index 6c7eff74173..e7bbb456a83 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBrowserClient.aidl
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IBrowserClient.aidl
@@ -15,4 +15,8 @@ interface IBrowserClient {
// Added in 87.
IRemoteFragment createMediaRouteDialogFragment() = 3;
void onRestoreCompleted() = 5;
+
+ // Added in 88.
+ void onBrowserControlsOffsetsChanged(in boolean isTop,
+ in int controlsOffset) = 4;
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IContextMenuParams.aidl b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IContextMenuParams.aidl
new file mode 100644
index 00000000000..58baad20468
--- /dev/null
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IContextMenuParams.aidl
@@ -0,0 +1,11 @@
+// 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_private.interfaces;
+
+/**
+ * Holds on to the native ContextMenuParams object.
+ */
+interface IContextMenuParams {
+}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigation.aidl b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigation.aidl
index 5c94e3418ea..bc05deb6794 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigation.aidl
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigation.aidl
@@ -33,4 +33,7 @@ interface INavigation {
// @since 86
boolean isPageInitiated() = 11;
boolean isReload() = 12;
+
+ // @since 88
+ void disableNetworkErrorAutoReload() = 17;
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigationControllerClient.aidl b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigationControllerClient.aidl
index 73432f8bd19..0c3fa33d8db 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigationControllerClient.aidl
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/INavigationControllerClient.aidl
@@ -33,4 +33,8 @@ interface INavigationControllerClient {
// Added in M85.
void onOldPageNoLongerRendered(in String uri) = 9;
+
+ // Added in M88.
+ void onFirstContentfulPaint2(long navigationStartMs, long firstContentfulPaintDurationMs) = 10;
+ void onLargestContentfulPaint(long navigationStartMs, long largestContentfulPaintDurationMs) = 11;
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IProfileClient.aidl b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IProfileClient.aidl
index 50de21109a1..16cb26715b4 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IProfileClient.aidl
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IProfileClient.aidl
@@ -4,7 +4,7 @@
package org.chromium.weblayer_private.interfaces;
-// Added in Version 87.
+// Added in Version 88.
interface IProfileClient {
void onProfileDestroyed() = 0;
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITab.aidl b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITab.aidl
index a2985dbc8d4..03f1d69064e 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITab.aidl
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITab.aidl
@@ -6,6 +6,7 @@ package org.chromium.weblayer_private.interfaces;
import java.util.List;
+import org.chromium.weblayer_private.interfaces.IContextMenuParams;
import org.chromium.weblayer_private.interfaces.IDownloadCallbackClient;
import org.chromium.weblayer_private.interfaces.IErrorPageCallbackClient;
import org.chromium.weblayer_private.interfaces.IFaviconFetcher;
@@ -75,5 +76,11 @@ interface ITab {
// Added in 87
void setScrollOffsetsEnabled(in boolean enabled) = 26;
+
+ // Added in 88
+ void setFloatingActionModeOverride(in int actionModeItemTypes) = 27;
boolean willAutomaticallyReloadAfterCrash() = 28;
+ void setDesktopUserAgentEnabled(in boolean enable) = 29;
+ boolean isDesktopUserAgentEnabled() = 30;
+ void download(in IContextMenuParams contextMenuParams) = 31;
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITabClient.aidl b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITabClient.aidl
index 94e02e8c47b..1b8028c83c4 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITabClient.aidl
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/ITabClient.aidl
@@ -4,6 +4,7 @@
package org.chromium.weblayer_private.interfaces;
+import org.chromium.weblayer_private.interfaces.IContextMenuParams;
import org.chromium.weblayer_private.interfaces.IObjectWrapper;
/**
@@ -21,6 +22,7 @@ interface ITabClient {
// void onCloseTab() = 3;
// Added in M82.
+ // Deprecated in M88.
void showContextMenu(in IObjectWrapper pageUrl, in IObjectWrapper linkUrl,
in IObjectWrapper linkText, in IObjectWrapper titleOrAltText,
in IObjectWrapper srcUrl) = 4;
@@ -46,4 +48,12 @@ interface ITabClient {
// Added in M87
void onVerticalScrollOffsetChanged(in int offset) = 11;
+
+ // Added in M88
+ void onActionItemClicked(
+ in int actionModeItemType, in IObjectWrapper selectedString) = 12;
+ void showContextMenu2(in IObjectWrapper pageUrl, in IObjectWrapper linkUrl,
+ in IObjectWrapper linkText, in IObjectWrapper titleOrAltText,
+ in IObjectWrapper srcUrl, in boolean isImage, in boolean isVideo, in boolean canDownload,
+ in IContextMenuParams contextMenuParams) = 13;
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayer.aidl b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayer.aidl
index ae9df666cf0..d1bbc1dc6ba 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayer.aidl
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayer.aidl
@@ -105,4 +105,11 @@ interface IWebLayer {
IMediaRouteDialogFragment createMediaRouteDialogFragmentImpl(
in IRemoteFragmentClient remoteFragmentClient) = 21;
IProfile getIncognitoProfile(in String profileName) = 24;
+
+ // Added in Version 88.
+ void onRemoteMediaServiceStarted(in IObjectWrapper sessionService, in Intent intent) = 22;
+ void onRemoteMediaServiceDestroyed(int id) = 23;
+
+ // WARNING: when choosing next value make sure you look back for the max, as
+ // merges may mean the last function does not have the max value.
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayerClient.aidl b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayerClient.aidl
index a26f56deb45..933e8507b57 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayerClient.aidl
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/IWebLayerClient.aidl
@@ -13,4 +13,12 @@ interface IWebLayerClient {
// Since Version 86.
Intent createImageDecoderServiceIntent() = 3;
+
+ // Since Version 88.
+ long getClassLoaderCreationTime() = 4;
+ long getContextCreationTime() = 5;
+ long getWebLayerLoaderCreationTime() = 6;
+ Intent createRemoteMediaServiceIntent() = 7;
+ int getPresentationApiNotificationId() = 8;
+ int getRemotePlaybackApiNotificationId() = 9;
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/LoadError.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/LoadError.java
index eba5fbf0c51..9a37dfa0061 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/LoadError.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/LoadError.java
@@ -10,7 +10,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@IntDef({LoadError.NO_ERROR, LoadError.HTTP_CLIENT_ERROR, LoadError.HTTP_SERVER_ERROR,
- LoadError.SSL_ERROR, LoadError.CONNECTIVITY_ERROR, LoadError.OTHER_ERROR})
+ LoadError.SSL_ERROR, LoadError.CONNECTIVITY_ERROR, LoadError.OTHER_ERROR,
+ LoadError.SAFE_BROWSING_ERROR})
@Retention(RetentionPolicy.SOURCE)
public @interface LoadError {
int NO_ERROR = 0;
@@ -19,4 +20,6 @@ public @interface LoadError {
int SSL_ERROR = 3;
int CONNECTIVITY_ERROR = 4;
int OTHER_ERROR = 5;
+ // Sent since 88.
+ int SAFE_BROWSING_ERROR = 6;
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/RemoteMediaServiceConstants.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/RemoteMediaServiceConstants.java
new file mode 100644
index 00000000000..375e3d8a28f
--- /dev/null
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/RemoteMediaServiceConstants.java
@@ -0,0 +1,16 @@
+// 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_private.interfaces;
+
+/** Keys for remote media service intent extras. */
+public interface RemoteMediaServiceConstants {
+ // Used as a key in the client's AndroidManifest.xml to enable remote media playback, i.e.
+ // Presentation API, Remote Playback API, and Media Fling (automatic casting of html5 videos).
+ String FEATURE_ENABLED_KEY = "org.chromium.weblayer.ENABLE_REMOTE_MEDIA";
+
+ // Used internally by WebLayer as a key to the various values of remote media service
+ // notification IDs.
+ String NOTIFICATION_ID_KEY = "REMOTE_MEDIA_SERVICE_NOTIFICATION_ID_KEY";
+}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/UrlBarOptionsKeys.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/UrlBarOptionsKeys.java
index 40957da4af7..3045944cba1 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/UrlBarOptionsKeys.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/UrlBarOptionsKeys.java
@@ -10,6 +10,11 @@ public interface UrlBarOptionsKeys {
* If true, clicking on the url shows page info. Default is false.
*/
String SHOW_PAGE_INFO_WHEN_URL_TEXT_CLICKED = "ShowPageInfoWhenUrlTextClicked";
+ /**
+ * If true, shows publisher url. Default is false.
+ * @since 88
+ */
+ String SHOW_PUBLISHER_URL = "ShowPublisherUrl";
String URL_ICON_COLOR = "UrlIconColor";
String URL_TEXT_COLOR = "UrlTextColor";
String URL_TEXT_SIZE = "UrlTextSize";
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/WebLayerVersionConstants.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/WebLayerVersionConstants.java
index 3ef535d997e..a76b13c3ba8 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/WebLayerVersionConstants.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/interfaces/WebLayerVersionConstants.java
@@ -15,5 +15,5 @@ public interface WebLayerVersionConstants {
*
* @see WebLayer#isAvailable()
*/
- int MAX_SKEW = 3;
+ int MAX_SKEW = 4;
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouteDialogFragmentImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouteDialogFragmentImpl.java
index aede72b184c..c3c4a2c34f9 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouteDialogFragmentImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouteDialogFragmentImpl.java
@@ -33,6 +33,7 @@ import org.chromium.weblayer_private.interfaces.IRemoteFragment;
import org.chromium.weblayer_private.interfaces.IRemoteFragmentClient;
import org.chromium.weblayer_private.interfaces.StrictModeWorkaround;
+import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
/**
@@ -53,6 +54,10 @@ public class MediaRouteDialogFragmentImpl extends RemoteFragmentImpl {
private boolean mStarted;
private FragmentController mFragmentController;
+ // The instance for the currently active dialog, if any. This is a WeakReference to get around
+ // StaticFieldLeak warnings.
+ private static WeakReference<MediaRouteDialogFragmentImpl> sInstanceForTest;
+
/**
* A fake FragmentActivity needed to make the Fragment system happy.
*
@@ -195,6 +200,7 @@ public class MediaRouteDialogFragmentImpl extends RemoteFragmentImpl {
public MediaRouteDialogFragmentImpl(IRemoteFragmentClient remoteFragmentClient) {
super(remoteFragmentClient);
+ sInstanceForTest = new WeakReference<MediaRouteDialogFragmentImpl>(this);
}
@Override
@@ -239,6 +245,7 @@ public class MediaRouteDialogFragmentImpl extends RemoteFragmentImpl {
StrictModeWorkaround.apply();
super.onDestroy();
mFragmentController.dispatchDestroy();
+ sInstanceForTest = null;
}
@Override
@@ -300,4 +307,8 @@ public class MediaRouteDialogFragmentImpl extends RemoteFragmentImpl {
private Context getWebLayerContext() {
return mContext;
}
+
+ public static MediaRouteDialogFragmentImpl getInstanceForTest() {
+ return sInstanceForTest.get();
+ }
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouterClientImpl.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouterClientImpl.java
index 86a596bda08..588aa8d4de6 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouterClientImpl.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/media/MediaRouterClientImpl.java
@@ -4,23 +4,51 @@
package org.chromium.weblayer_private.media;
+import android.app.Service;
+import android.content.Context;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.support.v4.media.session.MediaSessionCompat;
import androidx.fragment.app.FragmentManager;
+import org.chromium.base.ContextUtils;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
+import org.chromium.components.browser_ui.media.MediaNotificationController;
import org.chromium.components.browser_ui.media.MediaNotificationInfo;
+import org.chromium.components.browser_ui.media.MediaNotificationManager;
+import org.chromium.components.browser_ui.notifications.NotificationWrapper;
+import org.chromium.components.browser_ui.notifications.NotificationWrapperBuilder;
import org.chromium.components.media_router.MediaRouterClient;
import org.chromium.content_public.browser.WebContents;
import org.chromium.weblayer_private.IntentUtils;
import org.chromium.weblayer_private.TabImpl;
+import org.chromium.weblayer_private.WebLayerImpl;
+import org.chromium.weblayer_private.interfaces.RemoteMediaServiceConstants;
/** Provides WebLayer-specific behavior for Media Router. */
@JNINamespace("weblayer")
public class MediaRouterClientImpl extends MediaRouterClient {
+ static int sPresentationNotificationId;
+ static int sRemotingNotificationId;
+
private MediaRouterClientImpl() {}
+ public static void serviceStarted(Service service, Intent intent) {
+ int notificationId = intent.getIntExtra(RemoteMediaServiceConstants.NOTIFICATION_ID_KEY, 0);
+ if (notificationId == 0) {
+ throw new RuntimeException("Invalid RemoteMediaService notification id");
+ }
+ MediaSessionNotificationHelper.serviceStarted(service, intent, notificationId);
+ }
+
+ public static void serviceDestroyed(int notificationId) {
+ MediaSessionNotificationHelper.serviceDestroyed(notificationId);
+ }
+
@Override
public int getTabId(WebContents webContents) {
TabImpl tab = TabImpl.fromWebContents(webContents);
@@ -34,7 +62,19 @@ public class MediaRouterClientImpl extends MediaRouterClient {
@Override
public void showNotification(MediaNotificationInfo notificationInfo) {
- // TODO: implement.
+ MediaNotificationManager.show(notificationInfo, () -> {
+ return new MediaRouterNotificationControllerDelegate(notificationInfo.id);
+ });
+ }
+
+ @Override
+ public int getPresentationNotificationId() {
+ return getPresentationNotificationIdFromClient();
+ }
+
+ @Override
+ public int getRemotingNotificationId() {
+ return getRemotingNotificationIdFromClient();
}
@Override
@@ -51,4 +91,74 @@ public class MediaRouterClientImpl extends MediaRouterClient {
MediaRouterClient.setInstance(new MediaRouterClientImpl());
}
+
+ @CalledByNative
+ public static boolean isMediaRouterEnabled() {
+ Context context = ContextUtils.getApplicationContext();
+ try {
+ ApplicationInfo ai = context.getPackageManager().getApplicationInfo(
+ context.getPackageName(), PackageManager.GET_META_DATA);
+ return ai.metaData.getBoolean(RemoteMediaServiceConstants.FEATURE_ENABLED_KEY);
+ } catch (NameNotFoundException e) {
+ return false;
+ }
+ }
+
+ private static class MediaRouterNotificationControllerDelegate
+ implements MediaNotificationController.Delegate {
+ // The ID distinguishes between Presentation and Remoting services/notifications.
+ private final int mNotificationId;
+
+ MediaRouterNotificationControllerDelegate(int notificationId) {
+ mNotificationId = notificationId;
+ }
+
+ @Override
+ public Intent createServiceIntent() {
+ return WebLayerImpl.createRemoteMediaServiceIntent().putExtra(
+ RemoteMediaServiceConstants.NOTIFICATION_ID_KEY, mNotificationId);
+ }
+
+ @Override
+ public String getAppName() {
+ return WebLayerImpl.getClientApplicationName();
+ }
+
+ @Override
+ public String getNotificationGroupName() {
+ if (mNotificationId == getPresentationNotificationIdFromClient()) {
+ return "org.chromium.weblayer.PresentationApi";
+ }
+
+ assert mNotificationId == getRemotingNotificationIdFromClient();
+ return "org.chromium.weblayer.RemotePlaybackApi";
+ }
+
+ @Override
+ public NotificationWrapperBuilder createNotificationWrapperBuilder() {
+ return MediaSessionNotificationHelper.createNotificationWrapperBuilder(mNotificationId);
+ }
+
+ @Override
+ public void onMediaSessionUpdated(MediaSessionCompat session) {
+ // TODO(estade): implement.
+ }
+
+ @Override
+ public void logNotificationShown(NotificationWrapper notification) {}
+ }
+
+ private static int getPresentationNotificationIdFromClient() {
+ if (sPresentationNotificationId == 0) {
+ sPresentationNotificationId = WebLayerImpl.getPresentationApiNotificationId();
+ }
+ return sPresentationNotificationId;
+ }
+
+ private static int getRemotingNotificationIdFromClient() {
+ if (sRemotingNotificationId == 0) {
+ sRemotingNotificationId = WebLayerImpl.getRemotePlaybackApiNotificationId();
+ }
+ return sRemotingNotificationId;
+ }
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionManager.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionManager.java
index 3311c77593a..d555a77cf20 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionManager.java
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionManager.java
@@ -12,14 +12,12 @@ import org.chromium.components.browser_ui.media.MediaNotificationController;
import org.chromium.components.browser_ui.media.MediaNotificationInfo;
import org.chromium.components.browser_ui.media.MediaNotificationManager;
import org.chromium.components.browser_ui.media.MediaSessionHelper;
-import org.chromium.components.browser_ui.notifications.ForegroundServiceUtils;
-import org.chromium.components.browser_ui.notifications.NotificationMetadata;
import org.chromium.components.browser_ui.notifications.NotificationWrapper;
import org.chromium.components.browser_ui.notifications.NotificationWrapperBuilder;
+import org.chromium.components.embedder_support.browser_context.BrowserContextHandle;
import org.chromium.weblayer_private.IntentUtils;
+import org.chromium.weblayer_private.TabImpl;
import org.chromium.weblayer_private.WebLayerImpl;
-import org.chromium.weblayer_private.WebLayerNotificationChannels;
-import org.chromium.weblayer_private.WebLayerNotificationWrapperBuilder;
/**
* A glue class for MediaSession.
@@ -31,43 +29,30 @@ public class MediaSessionManager {
private static int sNotificationId;
public static void serviceStarted(Service service, Intent intent) {
- MediaNotificationController controller = getController();
- if (controller != null && controller.processIntent(service, intent)) return;
-
- // The service has been started with startForegroundService() but the
- // notification hasn't been shown. See similar logic in {@link
- // ChromeMediaNotificationControllerDelegate}.
- MediaNotificationController.finishStartingForegroundServiceOnO(
- service, createNotificationWrapperBuilder().buildNotificationWrapper());
- // Call stopForeground to guarantee Android unset the foreground bit.
- ForegroundServiceUtils.getInstance().stopForeground(
- service, Service.STOP_FOREGROUND_REMOVE);
- service.stopSelf();
+ MediaSessionNotificationHelper.serviceStarted(service, intent, getNotificationId());
}
public static void serviceDestroyed() {
- MediaNotificationController controller = getController();
- if (controller != null) controller.onServiceDestroyed();
- MediaNotificationManager.clear(getNotificationId());
+ MediaSessionNotificationHelper.serviceDestroyed(getNotificationId());
}
- public static MediaSessionHelper.Delegate createMediaSessionHelperDelegate(int tabId) {
+ public static MediaSessionHelper.Delegate createMediaSessionHelperDelegate(TabImpl tab) {
return new MediaSessionHelper.Delegate() {
@Override
public Intent createBringTabToFrontIntent() {
- return IntentUtils.createBringTabToFrontIntent(tabId);
+ return IntentUtils.createBringTabToFrontIntent(tab.getId());
}
@Override
- public boolean fetchLargeFaviconImage() {
- // TODO(crbug.com/1076463): WebLayer doesn't support favicons.
- return false;
+ public BrowserContextHandle getBrowserContextHandle() {
+ return tab.getProfile();
}
@Override
public MediaNotificationInfo.Builder createMediaNotificationInfoBuilder() {
- return new MediaNotificationInfo.Builder().setInstanceId(tabId).setId(
- getNotificationId());
+ return new MediaNotificationInfo.Builder()
+ .setInstanceId(tab.getId())
+ .setId(getNotificationId());
}
@Override
@@ -79,12 +64,13 @@ public class MediaSessionManager {
@Override
public void hideMediaNotification() {
- MediaNotificationManager.hide(tabId, getNotificationId());
+ MediaNotificationManager.hide(tab.getId(), getNotificationId());
}
@Override
public void activateAndroidMediaSession() {
- MediaNotificationManager.activateAndroidMediaSession(tabId, getNotificationId());
+ MediaNotificationManager.activateAndroidMediaSession(
+ tab.getId(), getNotificationId());
}
};
}
@@ -108,7 +94,8 @@ public class MediaSessionManager {
@Override
public NotificationWrapperBuilder createNotificationWrapperBuilder() {
- return MediaSessionManager.createNotificationWrapperBuilder();
+ return MediaSessionNotificationHelper.createNotificationWrapperBuilder(
+ getNotificationId());
}
@Override
@@ -120,22 +107,8 @@ public class MediaSessionManager {
public void logNotificationShown(NotificationWrapper notification) {}
}
- private static NotificationWrapperBuilder createNotificationWrapperBuilder() {
- // Only the null tag will work as expected, because {@link Service#startForeground()} only
- // takes an ID and no tag. If we pass a tag here, then the notification that's used to
- // display a paused state (no foreground service) will not be identified as the same one
- // that's used with the foreground service.
- return WebLayerNotificationWrapperBuilder.create(
- WebLayerNotificationChannels.ChannelId.MEDIA_PLAYBACK,
- new NotificationMetadata(0, null /*notificationTag*/, getNotificationId()));
- }
-
private static int getNotificationId() {
if (sNotificationId == 0) sNotificationId = WebLayerImpl.getMediaSessionNotificationId();
return sNotificationId;
}
-
- private static MediaNotificationController getController() {
- return MediaNotificationManager.getController(getNotificationId());
- }
}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionNotificationHelper.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionNotificationHelper.java
new file mode 100644
index 00000000000..fbd9b5da8b3
--- /dev/null
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/media/MediaSessionNotificationHelper.java
@@ -0,0 +1,55 @@
+// 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_private.media;
+
+import android.app.Service;
+import android.content.Intent;
+
+import org.chromium.components.browser_ui.media.MediaNotificationController;
+import org.chromium.components.browser_ui.media.MediaNotificationManager;
+import org.chromium.components.browser_ui.notifications.ForegroundServiceUtils;
+import org.chromium.components.browser_ui.notifications.NotificationMetadata;
+import org.chromium.components.browser_ui.notifications.NotificationWrapperBuilder;
+import org.chromium.weblayer_private.WebLayerNotificationChannels;
+import org.chromium.weblayer_private.WebLayerNotificationWrapperBuilder;
+
+/**
+ * A helper class for management of MediaSession (local device), Presentation API and Remote
+ * Playback API (casting) notifications and foreground services.
+ */
+class MediaSessionNotificationHelper {
+ static void serviceStarted(Service service, Intent intent, int notificationId) {
+ MediaNotificationController controller =
+ MediaNotificationManager.getController(notificationId);
+ if (controller != null && controller.processIntent(service, intent)) return;
+
+ // The service has been started with startForegroundService() but the
+ // notification hasn't been shown. See similar logic in {@link
+ // ChromeMediaNotificationControllerDelegate}.
+ MediaNotificationController.finishStartingForegroundServiceOnO(service,
+ createNotificationWrapperBuilder(notificationId).buildNotificationWrapper());
+ // Call stopForeground to guarantee Android unset the foreground bit.
+ ForegroundServiceUtils.getInstance().stopForeground(
+ service, Service.STOP_FOREGROUND_REMOVE);
+ service.stopSelf();
+ }
+
+ static void serviceDestroyed(int notificationId) {
+ MediaNotificationController controller =
+ MediaNotificationManager.getController(notificationId);
+ if (controller != null) controller.onServiceDestroyed();
+ MediaNotificationManager.clear(notificationId);
+ }
+
+ static NotificationWrapperBuilder createNotificationWrapperBuilder(int notificationId) {
+ // Only the null tag will work as expected, because {@link Service#startForeground()} only
+ // takes an ID and no tag. If we pass a tag here, then the notification that's used to
+ // display a paused state (no foreground service) will not be identified as the same one
+ // that's used with the foreground service.
+ return WebLayerNotificationWrapperBuilder.create(
+ WebLayerNotificationChannels.ChannelId.MEDIA_PLAYBACK,
+ new NotificationMetadata(0, null /*notificationTag*/, notificationId));
+ }
+}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/payments/OWNERS b/chromium/weblayer/browser/java/org/chromium/weblayer_private/payments/OWNERS
new file mode 100644
index 00000000000..faba26b9c87
--- /dev/null
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/payments/OWNERS
@@ -0,0 +1,5 @@
+# TEAM: payments-dev@chromium.org
+# COMPONENT: Blink>Payments
+# OS: Android
+
+file://components/payments/OWNERS
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestFactory.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestFactory.java
new file mode 100644
index 00000000000..c3231fc4fde
--- /dev/null
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestFactory.java
@@ -0,0 +1,112 @@
+// 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_private.payments;
+
+import androidx.annotation.Nullable;
+
+import org.chromium.components.embedder_support.browser_context.BrowserContextHandle;
+import org.chromium.components.payments.InvalidPaymentRequest;
+import org.chromium.components.payments.PaymentFeatureList;
+import org.chromium.components.payments.PaymentRequestService;
+import org.chromium.components.payments.PaymentRequestServiceUtil;
+import org.chromium.components.payments.PrefsStrings;
+import org.chromium.components.user_prefs.UserPrefs;
+import org.chromium.content_public.browser.FeaturePolicyFeature;
+import org.chromium.content_public.browser.RenderFrameHost;
+import org.chromium.content_public.browser.WebContents;
+import org.chromium.content_public.browser.WebContentsStatics;
+import org.chromium.mojo.system.MojoException;
+import org.chromium.mojo.system.MojoResult;
+import org.chromium.payments.mojom.PaymentRequest;
+import org.chromium.services.service_manager.InterfaceFactory;
+import org.chromium.weblayer_private.ProfileImpl;
+import org.chromium.weblayer_private.TabImpl;
+
+/** Creates an instance of PaymentRequest for use in WebLayer. */
+public class WebLayerPaymentRequestFactory implements InterfaceFactory<PaymentRequest> {
+ private final RenderFrameHost mRenderFrameHost;
+
+ /**
+ * Production implementation of the WebLayerPaymentRequestService's Delegate. Gives true answers
+ * about the system.
+ */
+ private static class WebLayerPaymentRequestDelegateImpl
+ implements PaymentRequestService.Delegate {
+ private final RenderFrameHost mRenderFrameHost;
+
+ /* package */ WebLayerPaymentRequestDelegateImpl(RenderFrameHost renderFrameHost) {
+ mRenderFrameHost = renderFrameHost;
+ }
+
+ @Override
+ public boolean isOffTheRecord() {
+ ProfileImpl profile = getProfile();
+ if (profile == null) return true;
+ return profile.isIncognito();
+ }
+
+ @Override
+ public String getInvalidSslCertificateErrorMessage() {
+ assert false : "Not implemented yet";
+ return "";
+ }
+
+ @Override
+ public boolean prefsCanMakePayment() {
+ BrowserContextHandle profile = getProfile();
+ return profile != null
+ && UserPrefs.get(profile).getBoolean(PrefsStrings.CAN_MAKE_PAYMENT_ENABLED);
+ }
+
+ @Nullable
+ @Override
+ public String getTwaPackageName() {
+ return null;
+ }
+
+ @Nullable
+ private ProfileImpl getProfile() {
+ WebContents webContents =
+ PaymentRequestServiceUtil.getLiveWebContents(mRenderFrameHost);
+ if (webContents == null) return null;
+ TabImpl tab = TabImpl.fromWebContents(webContents);
+ if (tab == null) return null;
+ return tab.getProfile();
+ }
+ }
+
+ /**
+ * Creates an instance of WebLayerPaymentRequestFactory.
+ * @param renderFrameHost The frame that issues the payment request on the merchant page.
+ */
+ public WebLayerPaymentRequestFactory(RenderFrameHost renderFrameHost) {
+ mRenderFrameHost = renderFrameHost;
+ }
+
+ @Override
+ public PaymentRequest createImpl() {
+ if (mRenderFrameHost == null) return new InvalidPaymentRequest();
+ if (!mRenderFrameHost.isFeatureEnabled(FeaturePolicyFeature.PAYMENT)) {
+ mRenderFrameHost.getRemoteInterfaces().onConnectionError(
+ new MojoException(MojoResult.PERMISSION_DENIED));
+ return null;
+ }
+
+ if (!PaymentFeatureList.isEnabled(PaymentFeatureList.WEB_PAYMENTS)) {
+ return new InvalidPaymentRequest();
+ }
+
+ PaymentRequestService.Delegate delegate =
+ new WebLayerPaymentRequestDelegateImpl(mRenderFrameHost);
+
+ WebContents webContents = WebContentsStatics.fromRenderFrameHost(mRenderFrameHost);
+ if (webContents == null || webContents.isDestroyed()) return new InvalidPaymentRequest();
+
+ return PaymentRequestService.createPaymentRequest(mRenderFrameHost,
+ /*isOffTheRecord=*/delegate.isOffTheRecord(), delegate,
+ (paymentRequestService)
+ -> new WebLayerPaymentRequestService(paymentRequestService, delegate));
+ }
+}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestService.java b/chromium/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestService.java
new file mode 100644
index 00000000000..15a27e1be91
--- /dev/null
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/payments/WebLayerPaymentRequestService.java
@@ -0,0 +1,57 @@
+// 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_private.payments;
+
+import org.chromium.components.payments.BrowserPaymentRequest;
+import org.chromium.components.payments.PaymentAppService;
+import org.chromium.components.payments.PaymentRequestService;
+import org.chromium.components.payments.PaymentRequestService.Delegate;
+import org.chromium.payments.mojom.PaymentDetails;
+import org.chromium.payments.mojom.PaymentValidationErrors;
+
+/** The WebLayer-specific part of the payment request service. */
+public class WebLayerPaymentRequestService implements BrowserPaymentRequest {
+ /**
+ * Create an instance of {@link WebLayerPaymentRequestService}.
+ * @param paymentRequestService The payment request service.
+ * @param delegate The delegate of the payment request service.
+ */
+ public WebLayerPaymentRequestService(
+ PaymentRequestService paymentRequestService, Delegate delegate) {
+ assert false : "Not implemented yet";
+ }
+
+ @Override
+ public void onPaymentDetailsUpdated(
+ PaymentDetails details, boolean hasNotifiedInvokedPaymentApp) {
+ assert false : "Not implemented yet";
+ }
+
+ @Override
+ public void onPaymentDetailsNotUpdated(String selectedShippingOptionError) {
+ assert false : "Not implemented yet";
+ }
+
+ @Override
+ public void complete(int result) {
+ assert false : "Not implemented yet";
+ }
+
+ @Override
+ public void retry(PaymentValidationErrors errors) {
+ assert false : "Not implemented yet";
+ }
+
+ @Override
+ public void close() {
+ assert false : "Not implemented yet";
+ }
+
+ @Override
+ public void addPaymentAppFactories(PaymentAppService service) {
+ assert false : "Not implemented yet";
+ }
+
+}
diff --git a/chromium/weblayer/browser/java/org/chromium/weblayer_private/test_interfaces/ITestWebLayer.aidl b/chromium/weblayer/browser/java/org/chromium/weblayer_private/test_interfaces/ITestWebLayer.aidl
index 53eff3330ed..e11d7a1ded7 100644
--- a/chromium/weblayer/browser/java/org/chromium/weblayer_private/test_interfaces/ITestWebLayer.aidl
+++ b/chromium/weblayer/browser/java/org/chromium/weblayer_private/test_interfaces/ITestWebLayer.aidl
@@ -4,6 +4,8 @@
package org.chromium.weblayer_private.test_interfaces;
+import android.os.Bundle;
+import org.chromium.weblayer_private.interfaces.IBrowser;
import org.chromium.weblayer_private.interfaces.IObjectWrapper;
import org.chromium.weblayer_private.interfaces.ITab;
@@ -38,7 +40,7 @@ interface ITestWebLayer {
void addInfoBar(in ITab tab, in IObjectWrapper runnable) = 10;
// Gets the infobar container view associated with |tab|.
- IObjectWrapper getInfoBarContainerView(in ITab tab) = 11;
+ IObjectWrapper /* View */ getInfoBarContainerView(in ITab tab) = 11;
void setIgnoreMissingKeyForTranslateManager(in boolean ignore) = 12;
void forceNetworkConnectivityState(in boolean networkAvailable) = 13;
@@ -53,4 +55,19 @@ interface ITestWebLayer {
// Returns true if a fullscreen toast was shown for |tab|.
boolean didShowFullscreenToast(in ITab tab) = 17;
+
+ // Does setup for MediaRouter tests, mocking out Chromecast devices.
+ void initializeMockMediaRouteProvider(
+ boolean closeRouteWithErrorOnSend, boolean disableIsSupportsSource,
+ in String createRouteErrorMessage, in String joinRouteErrorMessage) = 18;
+
+ // Gets a button from the currently visible media route selection dialog. The button represents a
+ // route and contains the text |name|. Returns null if no such dialog or button exists.
+ IObjectWrapper /* View */ getMediaRouteButton(String name) = 19;
+
+ // Causes the renderer process in the tab's main frame to crash.
+ void crashTab(in ITab tab) = 20;
+
+ boolean isWindowOnSmallDevice(in IBrowser browser) = 21;
+ IObjectWrapper getSecurityButton(IObjectWrapper /* View */ urlBarView) = 22;
}
diff --git a/chromium/weblayer/browser/java/res/drawable-hdpi/amp_icon.png b/chromium/weblayer/browser/java/res/drawable-hdpi/amp_icon.png
new file mode 100644
index 00000000000..651c3596045
--- /dev/null
+++ b/chromium/weblayer/browser/java/res/drawable-hdpi/amp_icon.png
Binary files differ
diff --git a/chromium/weblayer/browser/java/res/drawable-mdpi/amp_icon.png b/chromium/weblayer/browser/java/res/drawable-mdpi/amp_icon.png
new file mode 100644
index 00000000000..855dfc1122f
--- /dev/null
+++ b/chromium/weblayer/browser/java/res/drawable-mdpi/amp_icon.png
Binary files differ
diff --git a/chromium/weblayer/browser/java/res/drawable-xhdpi/amp_icon.png b/chromium/weblayer/browser/java/res/drawable-xhdpi/amp_icon.png
new file mode 100644
index 00000000000..e6d2088c1d1
--- /dev/null
+++ b/chromium/weblayer/browser/java/res/drawable-xhdpi/amp_icon.png
Binary files differ
diff --git a/chromium/weblayer/browser/java/res/drawable-xxhdpi/amp_icon.png b/chromium/weblayer/browser/java/res/drawable-xxhdpi/amp_icon.png
new file mode 100644
index 00000000000..d98a6aa4d11
--- /dev/null
+++ b/chromium/weblayer/browser/java/res/drawable-xxhdpi/amp_icon.png
Binary files differ
diff --git a/chromium/weblayer/browser/java/res/drawable-xxxhdpi/amp_icon.png b/chromium/weblayer/browser/java/res/drawable-xxxhdpi/amp_icon.png
new file mode 100644
index 00000000000..c596f1a6e19
--- /dev/null
+++ b/chromium/weblayer/browser/java/res/drawable-xxxhdpi/amp_icon.png
Binary files differ
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_af.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_af.xtb
index 403610204ab..8044c90dff8 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_af.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_af.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="af">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – afgelewer deur Google</translation>
<translation id="8298278839890148234">Webblaaieraktiwiteit</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_am.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_am.xtb
index 2fd6e46a16e..33857155f5c 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_am.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_am.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="am">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – በGoogle የተላከ</translation>
<translation id="8298278839890148234">የድር አሳሽ እንቅስቃሴ</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_ar.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_ar.xtb
index 55fcefece9b..15eb8ba27b9 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_ar.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_ar.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ar">
+<translation id="3345071039229881713">‏<ph name="PUBLISHER_ORIGIN" /> - تستضيف Google صفحة الويب هذه.</translation>
<translation id="8298278839890148234">نشاط التصفُّح على الويب</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_as.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_as.xtb
index db63c417200..dd8a3667014 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_as.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_as.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="as">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Googleএ ডেলিভাৰী কৰা</translation>
<translation id="8298278839890148234">ৱেব ব্ৰাউজাৰৰ কার্যকলাপ</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_az.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_az.xtb
index 684871cc3c3..aa69911464c 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_az.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_az.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="az">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Google tərəfindən əlçatan edilir</translation>
<translation id="8298278839890148234">Veb axtarış fəaliyyəti</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_be.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_be.xtb
index 4c18cf28a2f..8781907f374 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_be.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_be.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="be">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – праз Google</translation>
<translation id="8298278839890148234">Дзеянні ў вэб-браўзеры</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_bg.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_bg.xtb
index 1e7789939c0..aa5bf5613d1 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_bg.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_bg.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="bg">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – предоставено от Google</translation>
<translation id="8298278839890148234">Активност в уеб браузъра</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_bn.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_bn.xtb
index 374b81798d7..823f214680d 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_bn.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_bn.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="bn">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Google-এর প্রদান করা</translation>
<translation id="8298278839890148234">ওয়েব ব্রাউজার অ্যাক্টিভিটি</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_bs.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_bs.xtb
index 4fb2dbb390e..a18eebd6f80 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_bs.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_bs.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="bs">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – isporučio je Google</translation>
<translation id="8298278839890148234">Aktivnost web preglednika</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_ca.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_ca.xtb
index ba2d4e4da24..00eaa5da8c5 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_ca.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_ca.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ca">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" />, ofert per Google</translation>
<translation id="8298278839890148234">Activitat del navegador web</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_cs.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_cs.xtb
index 5710c42229a..9628cb22fd1 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_cs.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_cs.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="cs">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – zprostředkováno Googlem</translation>
<translation id="8298278839890148234">Aktivita ve webovém prohlížeči</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_da.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_da.xtb
index 63df7f53aa1..ac51312a15e 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_da.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_da.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="da">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – leveret af Google</translation>
<translation id="8298278839890148234">Webbrowseraktivitet</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_de.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_de.xtb
index a6c724e09b6..28aaa445f3e 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_de.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_de.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="de">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Von Google bereitgestellt</translation>
<translation id="8298278839890148234">Webbrowseraktivitäten</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_el.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_el.xtb
index 91f7efb7d08..4f0bd839302 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_el.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_el.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="el">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – από την Google</translation>
<translation id="8298278839890148234">Δραστηριότητα προγράμματος περιήγησης στον ιστό</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_en-GB.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_en-GB.xtb
index 078cecbe647..eaaef148aea 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_en-GB.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_en-GB.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="en-GB">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – delivered by Google</translation>
<translation id="8298278839890148234">Web browser activity</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_es-419.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_es-419.xtb
index e529fa34f49..7d4395f9d35 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_es-419.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_es-419.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="es-419">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – proporcionado por Google</translation>
<translation id="8298278839890148234">Actividad del navegador web</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_es.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_es.xtb
index fcf6da55978..1953298c15a 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_es.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_es.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="es">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – ofrecido por Google</translation>
<translation id="8298278839890148234">Actividad del navegador web</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_et.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_et.xtb
index 37ada0e9df4..1699a5d9e39 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_et.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_et.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="et">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – esitatud Google'i kaudu</translation>
<translation id="8298278839890148234">Veebibrauseri tegevused</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_eu.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_eu.xtb
index 2698f9fb351..eb7e1037ed0 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_eu.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_eu.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="eu">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> (Google-k ostatatua)</translation>
<translation id="8298278839890148234">Sareko arakatze-jarduerak</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_fa.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_fa.xtb
index 77daea83d86..61e6a43d9bd 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_fa.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_fa.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="fa">
+<translation id="3345071039229881713">‏<ph name="PUBLISHER_ORIGIN" /> – ارائه‌شده توسط Google</translation>
<translation id="8298278839890148234">فعالیت مرورگر وب</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_fi.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_fi.xtb
index 78a8d793d2e..93db71c5531 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_fi.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_fi.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="fi">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Googlen toimittama</translation>
<translation id="8298278839890148234">Verkon selaustoiminta</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_fil.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_fil.xtb
index 08f97ffffd4..10f67e6277b 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_fil.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_fil.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="fil">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Hatid ng Google</translation>
<translation id="8298278839890148234">Aktibidad ng web browser</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_fr-CA.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_fr-CA.xtb
index 537978cc551..2057930ad4d 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_fr-CA.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_fr-CA.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="fr-CA">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" />, proposé par Google</translation>
<translation id="8298278839890148234">Activité de navigation Web</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_fr.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_fr.xtb
index 9810a3e323a..e2c2390e32e 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_fr.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_fr.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="fr">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> - proposé par Google</translation>
<translation id="8298278839890148234">Activité de navigation sur le Web</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_gl.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_gl.xtb
index c315bcbcd56..aac3c6c6057 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_gl.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_gl.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="gl">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" />: contido ofrecido por Google</translation>
<translation id="8298278839890148234">Actividade de navegación pola Web</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_gu.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_gu.xtb
index 9e2ee22696d..dd0f55da619 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_gu.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_gu.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="gu">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Google દ્વારા પ્રદાન કરવામાં આવે છે</translation>
<translation id="8298278839890148234">વેબ બ્રાઉઝરની પ્રવૃત્તિ</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_hi.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_hi.xtb
index a9ae0e70db1..54b48a7e612 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_hi.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_hi.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="hi">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Google होस्ट करता है</translation>
<translation id="8298278839890148234">वेब ब्राउज़र की गतिविधि</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_hr.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_hr.xtb
index bc0817b9c82..d8415a78663 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_hr.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_hr.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="hr">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – isporučuje Google</translation>
<translation id="8298278839890148234">Aktivnost u web-pregledniku</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_hu.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_hu.xtb
index 587b17fb1f5..7032ea8d28e 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_hu.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_hu.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="hu">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – megjelenítette: Google</translation>
<translation id="8298278839890148234">Böngészős tevékenységek</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_hy.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_hy.xtb
index c5676da7cb3..b97e7dd5814 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_hy.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_hy.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="hy">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – տրամադրվել է Google-ի կողմից</translation>
<translation id="8298278839890148234">Գործողություններ դիտարկիչում</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_id.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_id.xtb
index 31b5fe5d797..b09d8e11c38 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_id.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_id.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="id">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – ditayangkan oleh Google</translation>
<translation id="8298278839890148234">Aktivitas penjelajahan web</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_is.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_is.xtb
index 923602bb298..3727dfd0753 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_is.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_is.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="is">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – frá Google</translation>
<translation id="8298278839890148234">Vafranotkun</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_it.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_it.xtb
index c4dc6e6ca5d..312e0fc7a54 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_it.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_it.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="it">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> - pubblicato da Google</translation>
<translation id="8298278839890148234">Attività del browser web</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_iw.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_iw.xtb
index bea498feca7..b79b1216692 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_iw.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_iw.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="iw">
+<translation id="3345071039229881713">‏<ph name="PUBLISHER_ORIGIN" /> – התוכן מוצג באמצעות Google</translation>
<translation id="8298278839890148234">פעילות דפדפן אינטרנט</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_ja.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_ja.xtb
index 091fdcc87ff..aa6d2c42a20 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_ja.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_ja.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ja">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> - Google により配信</translation>
<translation id="8298278839890148234">ウェブブラウザのアクティビティ</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_ka.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_ka.xtb
index 57bc785af7f..e234f67409d 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_ka.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_ka.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ka">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> — მოწოდებულია Google-ის მიერ</translation>
<translation id="8298278839890148234">ვებ-ბრაუზერის აქტივობა</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_kk.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_kk.xtb
index d18117e9c7f..d431e1370ff 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_kk.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_kk.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="kk">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Google ұсынған</translation>
<translation id="8298278839890148234">Браузерді қолдану мәліметі</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_km.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_km.xtb
index 312955fb520..ba4f9e13800 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_km.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_km.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="km">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – បញ្ជូន​ដោយ Google</translation>
<translation id="8298278839890148234">សកម្មភាព​កម្មវិធីរុករក​តាមអ៊ីនធឺណិត</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_kn.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_kn.xtb
index 91524cd5c0f..14e9dcf395a 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_kn.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_kn.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="kn">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Google ಮೂಲಕ ವಿತರಿಸಲಾಗಿದೆ</translation>
<translation id="8298278839890148234">ವೆಬ್ ಬ್ರೌಸಿಂಗ್ ಚಟುವಟಿಕೆ</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_ko.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_ko.xtb
index 742a5338444..ae1c1d98e33 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_ko.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_ko.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ko">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Google 게시</translation>
<translation id="8298278839890148234">웹브라우저 활동</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_ky.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_ky.xtb
index 2d0f4b479b2..2717dc3b4ea 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_ky.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_ky.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ky">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Google аркылуу алынган</translation>
<translation id="8298278839890148234">Көрүлгөн вебсайттар</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_lo.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_lo.xtb
index fba8f18695e..cbf1a5ad955 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_lo.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_lo.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="lo">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – ສະໜອງໃຫ້ໂດຍ Google</translation>
<translation id="8298278839890148234">ການເຄື່ອນໄຫວໃນໂປຣແກຣມທ່ອງເວັບ</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_lt.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_lt.xtb
index a1a90e6ff7c..592147336dd 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_lt.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_lt.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="lt">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – pateikė „Google“</translation>
<translation id="8298278839890148234">Žiniatinklio naršyklės veikla</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_lv.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_lv.xtb
index 5d965478866..8a4831c6f3c 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_lv.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_lv.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="lv">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> — nodrošina Google</translation>
<translation id="8298278839890148234">Pārlūkošanas darbības</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_mk.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_mk.xtb
index 2f2d3c2b91b..405e9450b74 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_mk.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_mk.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="mk">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> - овозможено од Google</translation>
<translation id="8298278839890148234">Активност на прелистувачот</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_ml.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_ml.xtb
index d4a01802579..5477ed262bf 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_ml.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_ml.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ml">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Google നൽകുന്നത്</translation>
<translation id="8298278839890148234">വെബ് ബ്രൗസർ ആക്റ്റിവിറ്റി</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_mn.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_mn.xtb
index 79d5dac7607..d86a10d44d5 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_mn.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_mn.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="mn">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Google-с хүргэсэн</translation>
<translation id="8298278839890148234">Хөтчийн үйл ажиллагаа</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_mr.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_mr.xtb
index 5a3e6820752..d6bfc7ee945 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_mr.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_mr.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="mr">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Google द्वारे वितरित</translation>
<translation id="8298278839890148234">वेब ब्राउझर अ‍ॅक्टिव्हिटी</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_ms.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_ms.xtb
index e105952bce6..37587a8a3ab 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_ms.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_ms.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ms">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – disampaikan oleh Google</translation>
<translation id="8298278839890148234">Aktiviti penyemakan imbas</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_my.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_my.xtb
index e8bf710e16c..09799a0bae0 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_my.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_my.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="my">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Google က ပေးပို့သည်</translation>
<translation id="8298278839890148234">ဝဘ်ဘရောင်ဇာ လုပ်ဆောင်ချက်</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_ne.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_ne.xtb
index 06ec47e44f4..07a9ef4ec27 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_ne.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_ne.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ne">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Google ले होस्ट गर्छ</translation>
<translation id="8298278839890148234">ब्राउजर प्रयोग गरी गरिएको क्रियाकलाप</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_nl.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_nl.xtb
index 759b04e50cc..7f4dbbc5017 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_nl.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_nl.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="nl">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> - geleverd door Google</translation>
<translation id="8298278839890148234">Webbrowseractivititeit</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_no.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_no.xtb
index 409a800ee70..069be093e86 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_no.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_no.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="no">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – levert av Google</translation>
<translation id="8298278839890148234">Nettleseraktivitet</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_or.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_or.xtb
index f88f14b33c3..da35ed2c026 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_or.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_or.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="or">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Google ଦ୍ୱାରା ଡେଲିଭର୍ କରାଯାଇଛି</translation>
<translation id="8298278839890148234">ୱେବ୍ ବ୍ରାଉଜର୍ କାର୍ଯ୍ୟକଳାପ</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_pa.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_pa.xtb
index 0d4c8c78fba..d01e13ba70b 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_pa.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_pa.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="pa">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Google ਵੱਲੋਂ ਡਿਲੀਵਰ ਕੀਤਾ ਗਿਆ</translation>
<translation id="8298278839890148234">ਵੈੱਬ ਬ੍ਰਾਊਜ਼ਰ ਸਰਗਰਮੀ</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_pl.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_pl.xtb
index 52a394f3e02..dcd31ccaae0 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_pl.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_pl.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="pl">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – dostarczane przez Google</translation>
<translation id="8298278839890148234">Aktywność w przeglądarce</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_pt-BR.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_pt-BR.xtb
index dd6972f79e3..39ebd4b7d46 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_pt-BR.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_pt-BR.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="pt-BR">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – veiculada pelo Google</translation>
<translation id="8298278839890148234">Atividade do navegador da Web</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_pt-PT.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_pt-PT.xtb
index 76966566f3d..1c8b3a49086 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_pt-PT.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_pt-PT.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="pt-PT">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – fornecido pela Google</translation>
<translation id="8298278839890148234">Atividade do navegador de Internet</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_ro.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_ro.xtb
index 12f45d28945..b0d7e977eac 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_ro.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_ro.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ro">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – oferită de Google</translation>
<translation id="8298278839890148234">Activitatea în browserul web</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_ru.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_ru.xtb
index 401647df65a..a538ba19b11 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_ru.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_ru.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ru">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – представлено Google</translation>
<translation id="8298278839890148234">Действия в веб-браузере</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_si.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_si.xtb
index 1e95ef55536..9a1384a5a17 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_si.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_si.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="si">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Google මගින් බෙදා හරින ලදි</translation>
<translation id="8298278839890148234">වෙබ් බ්‍රවුසර ක්‍රියාකාරකම</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_sk.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_sk.xtb
index 53b2d4ec263..a1237a16e71 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_sk.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_sk.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="sk">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – zobrazuje Google</translation>
<translation id="8298278839890148234">Aktivita webového prehliadača</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_sl.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_sl.xtb
index 152968ea560..38a4b6f89af 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_sl.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_sl.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="sl">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – vsebino prikazuje Google</translation>
<translation id="8298278839890148234">Dejavnost brskalnika</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_sq.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_sq.xtb
index 2e0a6950797..c38cc86e6ab 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_sq.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_sq.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="sq">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – dorëzuar nga Google</translation>
<translation id="8298278839890148234">Aktiviteti i shfletuesit të uebit</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_sr-Latn.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_sr-Latn.xtb
index 24f260082a7..36be57eb557 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_sr-Latn.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_sr-Latn.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="sr-Latn">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – isporučuje Google</translation>
<translation id="8298278839890148234">Aktivnosti u veb-pregledaču</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_sr.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_sr.xtb
index 9008032cbef..4e0cb92af45 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_sr.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_sr.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="sr">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – испоручује Google</translation>
<translation id="8298278839890148234">Активности у веб-прегледачу</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_sv.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_sv.xtb
index 610cb47e53f..92f86fb85b7 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_sv.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_sv.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="sv">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – via Google</translation>
<translation id="8298278839890148234">Webbläsaraktivitet</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_sw.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_sw.xtb
index cf0a4b711da..9ba44479261 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_sw.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_sw.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="sw">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – inawasilishwa na Google</translation>
<translation id="8298278839890148234">Shughuli za kivinjari</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_ta.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_ta.xtb
index 8a47545a26a..a5c9700dda7 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_ta.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_ta.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ta">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Googleளால் இயக்கப்படுவது</translation>
<translation id="8298278839890148234">இணைய உலாவியின் செயல்பாடு</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_te.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_te.xtb
index 3894c532d87..df4fdf8c52c 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_te.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_te.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="te">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Google ద్వారా డెలివరీ చేయబడింది</translation>
<translation id="8298278839890148234">బ్రౌజింగ్ యాక్టివిటీ</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_th.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_th.xtb
index 1c8e14c9ca0..ba3c34dc64a 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_th.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_th.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="th">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – นำส่งโดย Google</translation>
<translation id="8298278839890148234">กิจกรรมของเว็บเบราว์เซอร์</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_tr.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_tr.xtb
index 11d4ab4aeef..6eb4e9f826a 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_tr.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_tr.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="tr">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Google tarafından yayınlandı</translation>
<translation id="8298278839890148234">Web tarayıcısı etkinliği</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_uk.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_uk.xtb
index f8630458317..a240cd57ad6 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_uk.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_uk.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="uk">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – розміщено в Google</translation>
<translation id="8298278839890148234">Дії у веб-переглядачі</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_ur.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_ur.xtb
index 57e46884972..c26db486d20 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_ur.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_ur.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="ur">
+<translation id="3345071039229881713">‏<ph name="PUBLISHER_ORIGIN" /> – Google کے ذریعے ڈیلیور کردہ</translation>
<translation id="8298278839890148234">ویب براؤزر کی سرگرمی</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_uz.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_uz.xtb
index 92655c71edf..6dc23627370 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_uz.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_uz.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="uz">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – Google taqdim etadi</translation>
<translation id="8298278839890148234">Veb-brauzerdagi faoliyat</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_vi.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_vi.xtb
index 2f57bd60947..833428c26c1 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_vi.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_vi.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="vi">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – do Google cung cấp</translation>
<translation id="8298278839890148234">Hoạt động duyệt web</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_zh-CN.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_zh-CN.xtb
index 84075ec9807..f7a6fde8a59 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_zh-CN.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_zh-CN.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="zh-CN">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – 由 Google 提供</translation>
<translation id="8298278839890148234">网络浏览器活动</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_zh-HK.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_zh-HK.xtb
index abd42fba040..c9a21f7345a 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_zh-HK.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_zh-HK.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="zh-HK">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" />:由 Google 提供</translation>
<translation id="8298278839890148234">網絡瀏覽器活動</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_zh-TW.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_zh-TW.xtb
index ecea64ea7f4..46f2e7c76c1 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_zh-TW.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_zh-TW.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="zh-TW">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" />:由 Google 提供</translation>
<translation id="8298278839890148234">網路瀏覽器活動</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/translations/weblayer_strings_zu.xtb b/chromium/weblayer/browser/java/translations/weblayer_strings_zu.xtb
index 1da5d91a768..0059b6efe09 100644
--- a/chromium/weblayer/browser/java/translations/weblayer_strings_zu.xtb
+++ b/chromium/weblayer/browser/java/translations/weblayer_strings_zu.xtb
@@ -1,5 +1,6 @@
<?xml version="1.0" ?>
<!DOCTYPE translationbundle>
<translationbundle lang="zu">
+<translation id="3345071039229881713"><ph name="PUBLISHER_ORIGIN" /> – ilethwe yi-Google</translation>
<translation id="8298278839890148234">Umsebenzi wesiphequluli sewebhu</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/weblayer/browser/java/weblayer_strings.grd b/chromium/weblayer/browser/java/weblayer_strings.grd
index cd1e72cc645..6bfa0c4d8ee 100644
--- a/chromium/weblayer/browser/java/weblayer_strings.grd
+++ b/chromium/weblayer/browser/java/weblayer_strings.grd
@@ -172,6 +172,9 @@
<message name="IDS_WEBLAYER_NOTIFICATION_CHANNEL_GROUP_NAME" desc="The user-facing label for the notification channel group used for notifications arising from web browsing activity.">
Web browser activity
</message>
+ <message name="IDS_AMP_PUBLISHER_URL" desc="Text shown in WebLayer url bar for a web page that is hosted by the Google content delivery network but was originally published by someone else.">
+ <ph name="PUBLISHER_ORIGIN">%1$s<ex>example.com</ex></ph> – delivered by Google
+ </message>
</messages>
</release>
</grit>
diff --git a/chromium/weblayer/browser/java/weblayer_strings_grd/IDS_AMP_PUBLISHER_URL.png.sha1 b/chromium/weblayer/browser/java/weblayer_strings_grd/IDS_AMP_PUBLISHER_URL.png.sha1
new file mode 100644
index 00000000000..e3a5a425530
--- /dev/null
+++ b/chromium/weblayer/browser/java/weblayer_strings_grd/IDS_AMP_PUBLISHER_URL.png.sha1
@@ -0,0 +1 @@
+fdd1f7e78bdd42094f42487217e5cabd0fa6f5ce \ No newline at end of file
diff --git a/chromium/weblayer/browser/media/media_router_factory.cc b/chromium/weblayer/browser/media/media_router_factory.cc
index be8e600804f..50462c1e627 100644
--- a/chromium/weblayer/browser/media/media_router_factory.cc
+++ b/chromium/weblayer/browser/media/media_router_factory.cc
@@ -21,6 +21,13 @@ MediaRouterFactory* MediaRouterFactory::GetInstance() {
}
// static
+bool MediaRouterFactory::IsFeatureEnabled() {
+ static bool enabled = Java_MediaRouterClientImpl_isMediaRouterEnabled(
+ base::android::AttachCurrentThread());
+ return enabled;
+}
+
+// static
void MediaRouterFactory::DoPlatformInitIfNeeded() {
static bool init_done = false;
if (init_done)
diff --git a/chromium/weblayer/browser/media/media_router_factory.h b/chromium/weblayer/browser/media/media_router_factory.h
index 947e750f9df..f66bd5d5be0 100644
--- a/chromium/weblayer/browser/media/media_router_factory.h
+++ b/chromium/weblayer/browser/media/media_router_factory.h
@@ -25,6 +25,9 @@ class MediaRouterFactory : public media_router::MediaRouterFactory {
static MediaRouterFactory* GetInstance();
+ // Determines if media router related features should be enabled.
+ static bool IsFeatureEnabled();
+
// Performs platform and WebLayer-specific initialization for media_router.
static void DoPlatformInitIfNeeded();
diff --git a/chromium/weblayer/browser/navigation_browsertest.cc b/chromium/weblayer/browser/navigation_browsertest.cc
index 283e284874f..e6864844d9b 100644
--- a/chromium/weblayer/browser/navigation_browsertest.cc
+++ b/chromium/weblayer/browser/navigation_browsertest.cc
@@ -6,7 +6,9 @@
#include "base/callback.h"
#include "base/files/file_path.h"
-#include "base/test/bind_test_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/bind.h"
+#include "build/build_config.h"
#include "components/variations/net/variations_http_headers.h"
#include "components/variations/variations_ids_provider.h"
#include "content/public/browser/web_contents_observer.h"
@@ -122,11 +124,11 @@ IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, HttpClientError) {
embedded_test_server()->GetURL("/non_existent.html"));
observer.WaitForNavigation();
- EXPECT_TRUE(observer.completed());
- EXPECT_FALSE(observer.is_error_page());
+ EXPECT_FALSE(observer.completed());
+ EXPECT_TRUE(observer.is_error_page());
EXPECT_EQ(observer.load_error(), Navigation::kHttpClientError);
EXPECT_EQ(observer.http_status_code(), 404);
- EXPECT_EQ(observer.navigation_state(), NavigationState::kComplete);
+ EXPECT_EQ(observer.navigation_state(), NavigationState::kFailed);
}
IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, HttpServerError) {
@@ -792,4 +794,27 @@ IN_PROC_BROWSER_TEST_F(NavigationBrowserTest2, SetXClientDataHeaderInRedirect) {
EXPECT_EQ(header_value, last_header_value);
}
+#if defined(OS_ANDROID)
+// Verifies setting the 'referer' to an android-app url works.
+IN_PROC_BROWSER_TEST_F(NavigationBrowserTest, AndroidAppReferer) {
+ net::test_server::ControllableHttpResponse response(embedded_test_server(),
+ "", true);
+ ASSERT_TRUE(embedded_test_server()->Start());
+
+ const std::string header_name = "Referer";
+ const std::string header_value = "android-app://google.com/";
+ NavigationObserverImpl observer(GetNavigationController());
+ observer.SetStartedCallback(
+ base::BindLambdaForTesting([&](Navigation* navigation) {
+ navigation->SetRequestHeader(header_name, header_value);
+ }));
+
+ shell()->LoadURL(embedded_test_server()->GetURL("/simple_page.html"));
+ response.WaitForRequest();
+
+ // Verify 'referer' matches expected value.
+ EXPECT_EQ(header_value, response.http_request()->headers.at(header_name));
+}
+#endif
+
} // namespace weblayer
diff --git a/chromium/weblayer/browser/navigation_controller_impl.cc b/chromium/weblayer/browser/navigation_controller_impl.cc
index e201632a838..92995df7643 100644
--- a/chromium/weblayer/browser/navigation_controller_impl.cc
+++ b/chromium/weblayer/browser/navigation_controller_impl.cc
@@ -9,11 +9,13 @@
#include "base/auto_reset.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
+#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/navigation_throttle.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/page_transition_types.h"
+#include "weblayer/browser/navigation_entry_data.h"
#include "weblayer/browser/navigation_ui_data_impl.h"
#include "weblayer/browser/tab_impl.h"
#include "weblayer/public/navigation_observer.h"
@@ -152,6 +154,42 @@ NavigationImpl* NavigationControllerImpl::GetNavigationImplFromId(
return nullptr;
}
+void NavigationControllerImpl::OnFirstContentfulPaint(
+ const base::TimeTicks& navigation_start,
+ const base::TimeDelta& first_contentful_paint) {
+#if defined(OS_ANDROID)
+ TRACE_EVENT0("weblayer",
+ "Java_NavigationControllerImpl_onFirstContentfulPaint2");
+ int64_t first_contentful_paint_ms = first_contentful_paint.InMilliseconds();
+ Java_NavigationControllerImpl_onFirstContentfulPaint2(
+ AttachCurrentThread(), java_controller_,
+ (navigation_start - base::TimeTicks()).InMicroseconds(),
+ first_contentful_paint_ms);
+#endif
+
+ for (auto& observer : observers_)
+ observer.OnFirstContentfulPaint(navigation_start, first_contentful_paint);
+}
+
+void NavigationControllerImpl::OnLargestContentfulPaint(
+ const base::TimeTicks& navigation_start,
+ const base::TimeDelta& largest_contentful_paint) {
+#if defined(OS_ANDROID)
+ TRACE_EVENT0("weblayer",
+ "Java_NavigationControllerImpl_onLargestContentfulPaint2");
+ int64_t largest_contentful_paint_ms =
+ largest_contentful_paint.InMilliseconds();
+ Java_NavigationControllerImpl_onLargestContentfulPaint(
+ AttachCurrentThread(), java_controller_,
+ (navigation_start - base::TimeTicks()).InMicroseconds(),
+ largest_contentful_paint_ms);
+#endif
+
+ for (auto& observer : observers_)
+ observer.OnLargestContentfulPaint(navigation_start,
+ largest_contentful_paint);
+}
+
#if defined(OS_ANDROID)
void NavigationControllerImpl::SetNavigationControllerImpl(
JNIEnv* env,
@@ -259,11 +297,6 @@ void NavigationControllerImpl::Navigate(
std::make_unique<content::NavigationController::LoadURLParams>(url);
load_params->should_replace_current_entry =
params.should_replace_current_entry;
- if (params.disable_network_error_auto_reload) {
- auto data = std::make_unique<NavigationUIDataImpl>();
- data->set_disable_network_error_auto_reload(true);
- load_params->navigation_ui_data = std::move(data);
- }
if (params.enable_auto_play)
load_params->was_activated = content::mojom::WasActivatedOption::kYes;
@@ -353,7 +386,19 @@ void NavigationControllerImpl::DidStartNavigation(
base::AutoReset<NavigationImpl*> auto_reset(&navigation_starting_,
navigation);
navigation->set_safe_to_set_request_headers(true);
- navigation->set_safe_to_set_user_agent(true);
+ navigation->set_safe_to_disable_network_error_auto_reload(true);
+
+#if defined(OS_ANDROID)
+ // Desktop mode and per-navigation UA use the same mechanism and so don't
+ // interact well. It's not possible to support both at the same time since
+ // if there's a per-navigation UA active and desktop mode is turned on, or
+ // was on previously, the WebContent's state would have to change before
+ // navigation even though that would be wrong for the previous navigation if
+ // the new navigation didn't commit.
+ if (!TabImpl::FromWebContents(web_contents())->desktop_user_agent_enabled())
+#endif
+ navigation->set_safe_to_set_user_agent(true);
+
#if defined(OS_ANDROID)
NavigationUIDataImpl* navigation_ui_data = static_cast<NavigationUIDataImpl*>(
navigation_handle->GetNavigationUIData());
@@ -380,6 +425,7 @@ void NavigationControllerImpl::DidStartNavigation(
observer.NavigationStarted(navigation);
navigation->set_safe_to_set_user_agent(false);
navigation->set_safe_to_set_request_headers(false);
+ navigation->set_safe_to_disable_network_error_auto_reload(false);
}
void NavigationControllerImpl::DidRedirectNavigation(
@@ -416,6 +462,21 @@ void NavigationControllerImpl::DidFinishNavigation(
DelayDeletionHelper deletion_helper(this);
DCHECK(navigation_map_.find(navigation_handle) != navigation_map_.end());
auto* navigation = navigation_map_[navigation_handle].get();
+
+ if (navigation_handle->HasCommitted()) {
+ // Set state on NavigationEntry user data if a per-navigation user agent was
+ // specified. This can't be done earlier because a NavigationEntry might not
+ // have existed at the time that SetUserAgentString was called.
+ if (navigation->set_user_agent_string_called()) {
+ auto* entry = web_contents()->GetController().GetLastCommittedEntry();
+ if (entry) {
+ auto* entry_data = NavigationEntryData::Get(entry);
+ if (entry_data)
+ entry_data->set_per_navigation_user_agent_override(true);
+ }
+ }
+ }
+
if (navigation_handle->GetNetErrorCode() == net::OK &&
!navigation_handle->IsErrorPage()) {
#if defined(OS_ANDROID)
@@ -528,10 +589,18 @@ void NavigationControllerImpl::NotifyLoadStateChanged() {
void NavigationControllerImpl::DoNavigate(
std::unique_ptr<content::NavigationController::LoadURLParams> params) {
- // Navigations should use the default user-agent. If the embedder wants a
- // custom user-agent, the embedder will call Navigation::SetUserAgentString().
- params->override_user_agent =
- content::NavigationController::UA_OVERRIDE_FALSE;
+ // Navigations should use the default user-agent (which may be overridden if
+ // desktop mode is turned on). If the embedder wants a custom user-agent, the
+ // embedder will call Navigation::SetUserAgentString() in DidStartNavigation.
+#if defined(OS_ANDROID)
+ // We need to set UA_OVERRIDE_FALSE if per navigation UA is set. However at
+ // this point we don't know if the embedder will call that later. Since we
+ // ensure that the two can't be set at the same time, it's sufficient to
+ // not enable it if desktop mode is turned on.
+ if (!TabImpl::FromWebContents(web_contents())->desktop_user_agent_enabled())
+#endif
+ params->override_user_agent =
+ content::NavigationController::UA_OVERRIDE_FALSE;
if (navigation_starting_) {
// DoNavigate() is being called reentrantly. Delay processing until it's
// safe.
diff --git a/chromium/weblayer/browser/navigation_controller_impl.h b/chromium/weblayer/browser/navigation_controller_impl.h
index 8a2669ec305..3a285435a10 100644
--- a/chromium/weblayer/browser/navigation_controller_impl.h
+++ b/chromium/weblayer/browser/navigation_controller_impl.h
@@ -48,6 +48,21 @@ class NavigationControllerImpl : public NavigationController,
// Returns the NavigationImpl for |navigation_id|, or null if there isn't one.
NavigationImpl* GetNavigationImplFromId(int64_t navigation_id);
+ // Called when the first contentful paint page load metric is available.
+ // |navigation_start| is the navigation start time.
+ // |first_contentful_paint_ms| is the duration to first contentful paint from
+ // navigation start.
+ void OnFirstContentfulPaint(const base::TimeTicks& navigation_start,
+ const base::TimeDelta& first_contentful_paint);
+
+ // Called when the largest contentful paint page load metric is available.
+ // |navigation_start| is the navigation start time.
+ // |largest_contentful_paint| is the duration to largest contentful paint from
+ // navigation start.
+ void OnLargestContentfulPaint(
+ const base::TimeTicks& navigation_start,
+ const base::TimeDelta& largest_contentful_paint);
+
#if defined(OS_ANDROID)
void SetNavigationControllerImpl(
JNIEnv* env,
diff --git a/chromium/weblayer/browser/navigation_entry_data.cc b/chromium/weblayer/browser/navigation_entry_data.cc
new file mode 100644
index 00000000000..159425ba44d
--- /dev/null
+++ b/chromium/weblayer/browser/navigation_entry_data.cc
@@ -0,0 +1,47 @@
+// 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/browser/navigation_entry_data.h"
+
+#include "base/memory/ptr_util.h"
+#include "content/public/browser/navigation_entry.h"
+
+namespace weblayer {
+
+namespace {
+
+const char kCacheKey[] = "weblayer_navigation_entry_data";
+
+} // namespace
+
+NavigationEntryData::ResponseData::ResponseData() = default;
+NavigationEntryData::ResponseData::~ResponseData() = default;
+
+NavigationEntryData::NavigationEntryData() = default;
+NavigationEntryData::~NavigationEntryData() = default;
+
+std::unique_ptr<base::SupportsUserData::Data> NavigationEntryData::Clone() {
+ auto rv = base::WrapUnique(new NavigationEntryData);
+ rv->per_navigation_user_agent_override_ = per_navigation_user_agent_override_;
+ if (response_data_) {
+ rv->response_data_ = std::make_unique<ResponseData>();
+ rv->response_data_->response_head = response_data_->response_head.Clone();
+ rv->response_data_->data = response_data_->data;
+ rv->response_data_->request_time = response_data_->request_time;
+ rv->response_data_->response_time = response_data_->response_time;
+ }
+ return rv;
+}
+
+NavigationEntryData* NavigationEntryData::Get(content::NavigationEntry* entry) {
+ auto* data = static_cast<NavigationEntryData*>(entry->GetUserData(kCacheKey));
+ if (!data) {
+ auto data_object = base::WrapUnique(new NavigationEntryData);
+ data = data_object.get();
+ entry->SetUserData(kCacheKey, std::move(data_object));
+ }
+ return data;
+}
+
+} // namespace weblayer
diff --git a/chromium/weblayer/browser/navigation_entry_data.h b/chromium/weblayer/browser/navigation_entry_data.h
new file mode 100644
index 00000000000..c027c063b9f
--- /dev/null
+++ b/chromium/weblayer/browser/navigation_entry_data.h
@@ -0,0 +1,63 @@
+// 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_BROWSER_NAVIGATION_ENTRY_DATA_H_
+#define WEBLAYER_BROWSER_NAVIGATION_ENTRY_DATA_H_
+
+#include "base/supports_user_data.h"
+#include "base/time/time.h"
+#include "services/network/public/mojom/url_response_head.mojom.h"
+
+namespace content {
+class NavigationEntry;
+}
+
+namespace weblayer {
+
+// Holds extra data stored on content::NavigationEntry.
+class NavigationEntryData : public base::SupportsUserData::Data {
+ public:
+ ~NavigationEntryData() override;
+
+ // base::SupportsUserData::Data implementation:
+ std::unique_ptr<Data> Clone() override;
+
+ static NavigationEntryData* Get(content::NavigationEntry* entry);
+
+ // Stored on the NavigationEntry when we have a cached response from an
+ // InputStream.
+ struct ResponseData {
+ ResponseData();
+ ~ResponseData();
+ network::mojom::URLResponseHeadPtr response_head;
+ std::string data;
+ base::Time request_time;
+ base::Time response_time;
+ };
+
+ void set_response_data(std::unique_ptr<ResponseData> data) {
+ response_data_ = std::move(data);
+ }
+
+ void reset_response_data() { response_data_.reset(); }
+
+ ResponseData* response_data() { return response_data_.get(); }
+
+ void set_per_navigation_user_agent_override(bool value) {
+ per_navigation_user_agent_override_ = value;
+ }
+ bool per_navigation_user_agent_override() {
+ return per_navigation_user_agent_override_;
+ }
+
+ private:
+ NavigationEntryData();
+
+ std::unique_ptr<ResponseData> response_data_;
+ bool per_navigation_user_agent_override_ = false;
+};
+
+} // namespace weblayer
+
+#endif // WEBLAYER_BROWSER_NAVIGATION_ENTRY_DATA_H_
diff --git a/chromium/weblayer/browser/navigation_impl.cc b/chromium/weblayer/browser/navigation_impl.cc
index a3f5d007e89..c303acca835 100644
--- a/chromium/weblayer/browser/navigation_impl.cc
+++ b/chromium/weblayer/browser/navigation_impl.cc
@@ -94,6 +94,13 @@ jboolean NavigationImpl::SetUserAgentString(
return true;
}
+jboolean NavigationImpl::DisableNetworkErrorAutoReload(JNIEnv* env) {
+ if (!safe_to_disable_network_error_auto_reload_)
+ return false;
+ DisableNetworkErrorAutoReload();
+ return true;
+}
+
void NavigationImpl::SetResponse(
std::unique_ptr<embedder_support::WebResourceResponse> response) {
response_ = std::move(response);
@@ -166,6 +173,11 @@ Navigation::LoadError NavigationImpl::GetLoadError() {
if (error_code == net::OK)
return kNoError;
+ // The safe browsing navigation throttle fails navigations with
+ // ERR_BLOCKED_BY_CLIENT when showing safe browsing interstitials.
+ if (error_code == net::ERR_BLOCKED_BY_CLIENT)
+ return kSafeBrowsingError;
+
if (net::IsCertificateError(error_code))
return kSSLError;
@@ -192,10 +204,22 @@ void NavigationImpl::SetRequestHeader(const std::string& name,
void NavigationImpl::SetUserAgentString(const std::string& value) {
DCHECK(safe_to_set_user_agent_);
+ // By default renderer initiated navigations inherit the user-agent override
+ // of the current NavigationEntry. But we don't want this per-navigation UA to
+ // be inherited.
+ navigation_handle_->GetWebContents()
+ ->SetRendererInitiatedUserAgentOverrideOption(
+ content::NavigationController::UA_OVERRIDE_FALSE);
navigation_handle_->GetWebContents()->SetUserAgentOverride(
blink::UserAgentOverride::UserAgentOnly(value),
/* override_in_new_tabs */ false);
navigation_handle_->SetIsOverridingUserAgent(!value.empty());
+ set_user_agent_string_called_ = true;
+}
+
+void NavigationImpl::DisableNetworkErrorAutoReload() {
+ DCHECK(safe_to_disable_network_error_auto_reload_);
+ disable_network_error_auto_reload_ = true;
}
#if defined(OS_ANDROID)
diff --git a/chromium/weblayer/browser/navigation_impl.h b/chromium/weblayer/browser/navigation_impl.h
index 9307bcfa94c..cf69abd3cfb 100644
--- a/chromium/weblayer/browser/navigation_impl.h
+++ b/chromium/weblayer/browser/navigation_impl.h
@@ -49,8 +49,18 @@ class NavigationImpl : public Navigation {
safe_to_set_user_agent_ = value;
}
+ void set_safe_to_disable_network_error_auto_reload(bool value) {
+ safe_to_disable_network_error_auto_reload_ = value;
+ }
+
void set_was_stopped() { was_stopped_ = true; }
+ bool set_user_agent_string_called() { return set_user_agent_string_called_; }
+
+ bool disable_network_error_auto_reload() {
+ return disable_network_error_auto_reload_;
+ }
+
void SetParamsToLoadWhenSafe(
std::unique_ptr<content::NavigationController::LoadURLParams> params);
std::unique_ptr<content::NavigationController::LoadURLParams>
@@ -77,6 +87,7 @@ class NavigationImpl : public Navigation {
const base::android::JavaParamRef<jstring>& value);
jboolean IsPageInitiated(JNIEnv* env) { return IsPageInitiated(); }
jboolean IsReload(JNIEnv* env) { return IsReload(); }
+ jboolean DisableNetworkErrorAutoReload(JNIEnv* env);
void SetResponse(
std::unique_ptr<embedder_support::WebResourceResponse> response);
@@ -100,6 +111,7 @@ class NavigationImpl : public Navigation {
void SetRequestHeader(const std::string& name,
const std::string& value) override;
void SetUserAgentString(const std::string& value) override;
+ void DisableNetworkErrorAutoReload() override;
bool IsPageInitiated() override;
bool IsReload() override;
@@ -123,6 +135,14 @@ class NavigationImpl : public Navigation {
// Whether NavigationController::Stop() was called for this navigation.
bool was_stopped_ = false;
+ // Whether SetUserAgentString was called.
+ bool set_user_agent_string_called_ = false;
+
+ // Whether DisableNetworkErrorAutoReload is allowed at this time.
+ bool safe_to_disable_network_error_auto_reload_ = false;
+
+ bool disable_network_error_auto_reload_ = false;
+
#if defined(OS_ANDROID)
base::android::ScopedJavaGlobalRef<jobject> java_navigation_;
std::unique_ptr<embedder_support::WebResourceResponse> response_;
diff --git a/chromium/weblayer/browser/new_tab_delegate_browsertest.cc b/chromium/weblayer/browser/new_tab_delegate_browsertest.cc
new file mode 100644
index 00000000000..5c13568ccb7
--- /dev/null
+++ b/chromium/weblayer/browser/new_tab_delegate_browsertest.cc
@@ -0,0 +1,58 @@
+// 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/new_tab_delegate.h"
+
+#include "base/strings/stringprintf.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "weblayer/browser/tab_impl.h"
+#include "weblayer/public/browser.h"
+#include "weblayer/public/new_tab_delegate.h"
+#include "weblayer/public/tab.h"
+#include "weblayer/shell/browser/shell.h"
+#include "weblayer/test/weblayer_browser_test.h"
+#include "weblayer/test/weblayer_browser_test_utils.h"
+
+namespace weblayer {
+
+namespace {
+
+class DestroyingNewTabDelegate : public NewTabDelegate {
+ public:
+ void WaitForOnNewTab() { run_loop_.Run(); }
+
+ bool was_on_new_tab_called() const { return was_on_new_tab_called_; }
+
+ // NewTabDelegate:
+ void OnNewTab(Tab* new_tab, NewTabType type) override {
+ was_on_new_tab_called_ = true;
+ new_tab->GetBrowser()->DestroyTab(new_tab);
+ run_loop_.Quit();
+ }
+
+ private:
+ base::RunLoop run_loop_;
+ bool was_on_new_tab_called_ = false;
+};
+
+} // namespace
+
+using NewTabDelegateTest = WebLayerBrowserTest;
+
+IN_PROC_BROWSER_TEST_F(NewTabDelegateTest, DestroyTabOnNewTab) {
+ ASSERT_TRUE(embedded_test_server()->Start());
+ NavigateAndWaitForCompletion(embedded_test_server()->GetURL("/echo"),
+ shell()->tab());
+ DestroyingNewTabDelegate new_tab_delegate;
+ shell()->tab()->SetNewTabDelegate(&new_tab_delegate);
+ GURL popup_url = embedded_test_server()->GetURL("/echo?popup");
+ ExecuteScriptWithUserGesture(
+ shell()->tab(),
+ base::StringPrintf("window.open('%s')", popup_url.spec().c_str()));
+ new_tab_delegate.WaitForOnNewTab();
+ EXPECT_TRUE(new_tab_delegate.was_on_new_tab_called());
+ EXPECT_EQ(1u, shell()->tab()->GetBrowser()->GetTabs().size());
+}
+
+} // namespace weblayer
diff --git a/chromium/weblayer/browser/no_state_prefetch/no_state_prefetch_browsertest.cc b/chromium/weblayer/browser/no_state_prefetch/no_state_prefetch_browsertest.cc
index 6c20eb885e5..539ba425605 100644
--- a/chromium/weblayer/browser/no_state_prefetch/no_state_prefetch_browsertest.cc
+++ b/chromium/weblayer/browser/no_state_prefetch/no_state_prefetch_browsertest.cc
@@ -5,11 +5,12 @@
#include <memory>
#include "base/run_loop.h"
+#include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/threading/platform_thread.h"
#include "build/build_config.h"
-#include "components/prerender/browser/prerender_histograms.h"
-#include "components/prerender/browser/prerender_manager.h"
+#include "components/no_state_prefetch/browser/prerender_histograms.h"
+#include "components/no_state_prefetch/browser/prerender_manager.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/url_loader_monitor.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
@@ -37,7 +38,7 @@ class NoStatePrefetchBrowserTest : public WebLayerBrowserTest {
public:
#if defined(OS_ANDROID)
void SetUp() override {
- InstallTestGmsBridge(/* user_consent= */ true);
+ InstallTestGmsBridge(ConsentType::kConsent);
WebLayerBrowserTest::SetUp();
}
@@ -196,21 +197,23 @@ IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest,
prerendered_page_fetched_->Run();
}
-// link-rel="next" happens even when NoStatePrefetch has been disabled.
+// link-rel="next" URLs should not be prefetched.
IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, LinkRelNextWithNSPDisabled) {
- GetProfile()->SetBooleanSetting(SettingType::NETWORK_PREDICTION_ENABLED,
- false);
NavigateAndWaitForCompletion(
GURL(https_server_->GetURL("/link_rel_next_parent.html")), shell());
-
- prerendered_page_fetched_->Run();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(prerendered_page_was_fetched_);
}
// Non-web initiated prerender succeeds and subsequent navigations reuse
// previously downloaded resources.
-IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, ExternalPrerender) {
- // std::unique_ptr<PrerenderControllerImpl> controller =
- // PrerenderControllerImpl::Create(shell()->browser());
+// TODO(https://crbug.com/1144282): Fix failures on Asan.
+#if defined(ADDRESS_SANITIZER)
+#define MAYBE_ExternalPrerender DISABLED_ExternalPrerender
+#else
+#define MAYBE_ExternalPrerender ExternalPrerender
+#endif
+IN_PROC_BROWSER_TEST_F(NoStatePrefetchBrowserTest, MAYBE_ExternalPrerender) {
GetProfile()->GetPrerenderController()->Prerender(
GURL(https_server_->GetURL("/prerendered_page.html")));
diff --git a/chromium/weblayer/browser/no_state_prefetch/prerender_controller_impl.cc b/chromium/weblayer/browser/no_state_prefetch/prerender_controller_impl.cc
index a5dd8f788a1..ccefb205263 100644
--- a/chromium/weblayer/browser/no_state_prefetch/prerender_controller_impl.cc
+++ b/chromium/weblayer/browser/no_state_prefetch/prerender_controller_impl.cc
@@ -5,8 +5,8 @@
#include "weblayer/browser/no_state_prefetch/prerender_controller_impl.h"
#include "build/build_config.h"
-#include "components/prerender/browser/prerender_handle.h"
-#include "components/prerender/browser/prerender_manager.h"
+#include "components/no_state_prefetch/browser/prerender_handle.h"
+#include "components/no_state_prefetch/browser/prerender_manager.h"
#include "content/public/browser/browser_context.h"
#include "ui/gfx/geometry/rect.h"
#include "url/gurl.h"
diff --git a/chromium/weblayer/browser/no_state_prefetch/prerender_link_manager_factory.cc b/chromium/weblayer/browser/no_state_prefetch/prerender_link_manager_factory.cc
index d7f715628e3..4b453fae327 100644
--- a/chromium/weblayer/browser/no_state_prefetch/prerender_link_manager_factory.cc
+++ b/chromium/weblayer/browser/no_state_prefetch/prerender_link_manager_factory.cc
@@ -5,8 +5,8 @@
#include "weblayer/browser/no_state_prefetch/prerender_link_manager_factory.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
-#include "components/prerender/browser/prerender_link_manager.h"
-#include "components/prerender/browser/prerender_manager.h"
+#include "components/no_state_prefetch/browser/prerender_link_manager.h"
+#include "components/no_state_prefetch/browser/prerender_manager.h"
#include "weblayer/browser/no_state_prefetch/prerender_manager_factory.h"
namespace weblayer {
diff --git a/chromium/weblayer/browser/no_state_prefetch/prerender_link_manager_factory.h b/chromium/weblayer/browser/no_state_prefetch/prerender_link_manager_factory.h
index 7369249c063..a4d4d72e951 100644
--- a/chromium/weblayer/browser/no_state_prefetch/prerender_link_manager_factory.h
+++ b/chromium/weblayer/browser/no_state_prefetch/prerender_link_manager_factory.h
@@ -7,7 +7,7 @@
#include "base/memory/singleton.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
-#include "components/prerender/browser/prerender_link_manager.h"
+#include "components/no_state_prefetch/browser/prerender_link_manager.h"
namespace content {
class BrowserContext;
diff --git a/chromium/weblayer/browser/no_state_prefetch/prerender_manager_delegate_impl.cc b/chromium/weblayer/browser/no_state_prefetch/prerender_manager_delegate_impl.cc
index 7194cdb225e..66f074e52a8 100644
--- a/chromium/weblayer/browser/no_state_prefetch/prerender_manager_delegate_impl.cc
+++ b/chromium/weblayer/browser/no_state_prefetch/prerender_manager_delegate_impl.cc
@@ -4,7 +4,7 @@
#include "weblayer/browser/no_state_prefetch/prerender_manager_delegate_impl.h"
-#include "components/prerender/browser/prerender_contents_delegate.h"
+#include "components/no_state_prefetch/browser/prerender_contents_delegate.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "weblayer/browser/browser_context_impl.h"
diff --git a/chromium/weblayer/browser/no_state_prefetch/prerender_manager_delegate_impl.h b/chromium/weblayer/browser/no_state_prefetch/prerender_manager_delegate_impl.h
index 788a8cad121..9dd3189d04d 100644
--- a/chromium/weblayer/browser/no_state_prefetch/prerender_manager_delegate_impl.h
+++ b/chromium/weblayer/browser/no_state_prefetch/prerender_manager_delegate_impl.h
@@ -6,7 +6,7 @@
#define WEBLAYER_BROWSER_NO_STATE_PREFETCH_PRERENDER_MANAGER_DELEGATE_IMPL_H_
#include "components/content_settings/core/browser/cookie_settings.h"
-#include "components/prerender/browser/prerender_manager_delegate.h"
+#include "components/no_state_prefetch/browser/prerender_manager_delegate.h"
namespace content {
class BrowserContext;
diff --git a/chromium/weblayer/browser/no_state_prefetch/prerender_manager_factory.cc b/chromium/weblayer/browser/no_state_prefetch/prerender_manager_factory.cc
index b99e036662f..700f38773e9 100644
--- a/chromium/weblayer/browser/no_state_prefetch/prerender_manager_factory.cc
+++ b/chromium/weblayer/browser/no_state_prefetch/prerender_manager_factory.cc
@@ -5,7 +5,7 @@
#include "weblayer/browser/no_state_prefetch/prerender_manager_factory.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
-#include "components/prerender/browser/prerender_manager.h"
+#include "components/no_state_prefetch/browser/prerender_manager.h"
#include "weblayer/browser/no_state_prefetch/prerender_manager_delegate_impl.h"
namespace weblayer {
diff --git a/chromium/weblayer/browser/no_state_prefetch/prerender_processor_impl_delegate_impl.cc b/chromium/weblayer/browser/no_state_prefetch/prerender_processor_impl_delegate_impl.cc
index 1bc7022b279..e6ce7de3c6d 100644
--- a/chromium/weblayer/browser/no_state_prefetch/prerender_processor_impl_delegate_impl.cc
+++ b/chromium/weblayer/browser/no_state_prefetch/prerender_processor_impl_delegate_impl.cc
@@ -4,7 +4,7 @@
#include "weblayer/browser/no_state_prefetch/prerender_processor_impl_delegate_impl.h"
-#include "components/prerender/browser/prerender_link_manager.h"
+#include "components/no_state_prefetch/browser/prerender_link_manager.h"
#include "content/public/browser/browser_context.h"
#include "weblayer/browser/no_state_prefetch/prerender_link_manager_factory.h"
diff --git a/chromium/weblayer/browser/no_state_prefetch/prerender_processor_impl_delegate_impl.h b/chromium/weblayer/browser/no_state_prefetch/prerender_processor_impl_delegate_impl.h
index 1221e85b2da..322bdc25594 100644
--- a/chromium/weblayer/browser/no_state_prefetch/prerender_processor_impl_delegate_impl.h
+++ b/chromium/weblayer/browser/no_state_prefetch/prerender_processor_impl_delegate_impl.h
@@ -5,7 +5,7 @@
#ifndef WEBLAYER_BROWSER_NO_STATE_PREFETCH_PRERENDER_PROCESSOR_IMPL_DELEGATE_IMPL_H_
#define WEBLAYER_BROWSER_NO_STATE_PREFETCH_PRERENDER_PROCESSOR_IMPL_DELEGATE_IMPL_H_
-#include "components/prerender/browser/prerender_processor_impl_delegate.h"
+#include "components/no_state_prefetch/browser/prerender_processor_impl_delegate.h"
namespace content {
class BrowserContext;
diff --git a/chromium/weblayer/browser/no_state_prefetch/prerender_tab_helper.cc b/chromium/weblayer/browser/no_state_prefetch/prerender_tab_helper.cc
index 2825aa9b8a5..438ccf4c98b 100644
--- a/chromium/weblayer/browser/no_state_prefetch/prerender_tab_helper.cc
+++ b/chromium/weblayer/browser/no_state_prefetch/prerender_tab_helper.cc
@@ -4,7 +4,7 @@
#include "weblayer/browser/no_state_prefetch/prerender_tab_helper.h"
-#include "components/prerender/browser/prerender_manager.h"
+#include "components/no_state_prefetch/browser/prerender_manager.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/web_contents.h"
#include "weblayer/browser/no_state_prefetch/prerender_manager_factory.h"
diff --git a/chromium/weblayer/browser/no_state_prefetch/prerender_utils.cc b/chromium/weblayer/browser/no_state_prefetch/prerender_utils.cc
index 177a16adbea..0162939bd3f 100644
--- a/chromium/weblayer/browser/no_state_prefetch/prerender_utils.cc
+++ b/chromium/weblayer/browser/no_state_prefetch/prerender_utils.cc
@@ -4,8 +4,8 @@
#include "weblayer/browser/no_state_prefetch/prerender_utils.h"
-#include "components/prerender/browser/prerender_contents.h"
-#include "components/prerender/browser/prerender_manager.h"
+#include "components/no_state_prefetch/browser/prerender_contents.h"
+#include "components/no_state_prefetch/browser/prerender_manager.h"
#include "content/public/browser/web_contents.h"
#include "weblayer/browser/no_state_prefetch/prerender_manager_factory.h"
diff --git a/chromium/weblayer/browser/page_load_metrics_browsertest.cc b/chromium/weblayer/browser/page_load_metrics_browsertest.cc
index 64303678263..c82e49975a9 100644
--- a/chromium/weblayer/browser/page_load_metrics_browsertest.cc
+++ b/chromium/weblayer/browser/page_load_metrics_browsertest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/test/bind_test_util.h"
+#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "components/page_load_metrics/browser/page_load_metrics_observer.h"
#include "components/page_load_metrics/browser/page_load_tracker.h"
diff --git a/chromium/weblayer/browser/page_load_metrics_initialize.cc b/chromium/weblayer/browser/page_load_metrics_initialize.cc
index 740b83fd1c8..a2d19f4bf7c 100644
--- a/chromium/weblayer/browser/page_load_metrics_initialize.cc
+++ b/chromium/weblayer/browser/page_load_metrics_initialize.cc
@@ -10,7 +10,7 @@
#include "components/page_load_metrics/browser/page_load_metrics_observer.h"
#include "components/page_load_metrics/browser/page_load_tracker.h"
#include "weblayer/browser/no_state_prefetch/prerender_utils.h"
-#include "weblayer/browser/ukm_page_load_metrics_observer.h"
+#include "weblayer/browser/page_load_metrics_observer_impl.h"
namespace weblayer {
@@ -39,10 +39,7 @@ class PageLoadMetricsEmbedder
// page_load_metrics::PageLoadMetricsEmbedderBase:
void RegisterEmbedderObservers(
page_load_metrics::PageLoadTracker* tracker) override {
- std::unique_ptr<page_load_metrics::PageLoadMetricsObserver> ukm_observer =
- UkmPageLoadMetricsObserver::CreateIfNeeded();
- if (ukm_observer)
- tracker->AddObserver(std::move(ukm_observer));
+ tracker->AddObserver(std::make_unique<PageLoadMetricsObserverImpl>());
if (g_callback_for_testing)
(*g_callback_for_testing).Run(tracker);
diff --git a/chromium/weblayer/browser/page_load_metrics_observer_impl.cc b/chromium/weblayer/browser/page_load_metrics_observer_impl.cc
new file mode 100644
index 00000000000..f73117a2ae7
--- /dev/null
+++ b/chromium/weblayer/browser/page_load_metrics_observer_impl.cc
@@ -0,0 +1,111 @@
+// 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/browser/page_load_metrics_observer_impl.h"
+
+#include "base/time/time.h"
+#include "build/build_config.h"
+#include "components/no_state_prefetch/browser/prerender_manager.h"
+#include "components/no_state_prefetch/browser/prerender_util.h"
+#include "components/page_load_metrics/browser/observers/core/largest_contentful_paint_handler.h"
+#include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/web_contents.h"
+#include "services/metrics/public/cpp/ukm_recorder.h"
+#include "weblayer/browser/navigation_controller_impl.h"
+#include "weblayer/browser/no_state_prefetch/prerender_manager_factory.h"
+#include "weblayer/browser/tab_impl.h"
+
+namespace weblayer {
+
+PageLoadMetricsObserverImpl::ObservePolicy
+PageLoadMetricsObserverImpl::OnCommit(
+ content::NavigationHandle* navigation_handle,
+ ukm::SourceId source_id) {
+#if defined(OS_ANDROID)
+ if (!ukm::UkmRecorder::Get())
+ return CONTINUE_OBSERVING;
+
+ // If URL-Keyed-Metrics (UKM) is enabled in the system, this is used to
+ // populate it with top-level page-load metrics.
+ prerender::PrerenderManager* const prerender_manager =
+ PrerenderManagerFactory::GetForBrowserContext(
+ navigation_handle->GetWebContents()->GetBrowserContext());
+ if (!prerender_manager)
+ return CONTINUE_OBSERVING;
+ prerender::RecordNoStatePrefetchMetrics(navigation_handle, source_id,
+ prerender_manager);
+#endif
+ return CONTINUE_OBSERVING;
+}
+
+page_load_metrics::PageLoadMetricsObserver::ObservePolicy
+PageLoadMetricsObserverImpl::FlushMetricsOnAppEnterBackground(
+ const page_load_metrics::mojom::PageLoadTiming& timing) {
+ // FlushMetricsOnAppEnterBackground is invoked on Android in cases where the
+ // app is about to be backgrounded, as part of the Activity.onPause()
+ // flow. After this method is invoked, WebLayer may be killed without further
+ // notification, so we record final metrics collected up to this point.
+ ReportBufferedMetrics(timing);
+
+ // We continue observing after being backgrounded, in case we are foregrounded
+ // again without being killed. In those cases we may still report non-buffered
+ // metrics such as FCP after being re-foregrounded.
+ return CONTINUE_OBSERVING;
+}
+
+PageLoadMetricsObserverImpl::ObservePolicy
+PageLoadMetricsObserverImpl::OnHidden(
+ const page_load_metrics::mojom::PageLoadTiming& timing) {
+ ReportBufferedMetrics(timing);
+ return CONTINUE_OBSERVING;
+}
+
+void PageLoadMetricsObserverImpl::OnComplete(
+ const page_load_metrics::mojom::PageLoadTiming& timing) {
+ ReportBufferedMetrics(timing);
+}
+
+void PageLoadMetricsObserverImpl::OnFirstContentfulPaintInPage(
+ const page_load_metrics::mojom::PageLoadTiming& timing) {
+ auto* tab = TabImpl::FromWebContents(GetDelegate().GetWebContents());
+ if (!tab)
+ return;
+
+ auto* nav_controller =
+ static_cast<NavigationControllerImpl*>(tab->GetNavigationController());
+ nav_controller->OnFirstContentfulPaint(
+ GetDelegate().GetNavigationStart(),
+ *timing.paint_timing->first_contentful_paint);
+}
+
+void PageLoadMetricsObserverImpl::ReportBufferedMetrics(
+ const page_load_metrics::mojom::PageLoadTiming& timing) {
+ // This method may be invoked multiple times. Make sure that if we already
+ // reported, we do not report again.
+ if (reported_buffered_metrics_)
+ return;
+ reported_buffered_metrics_ = true;
+
+ // Buffered metrics aren't available until after the navigation commits.
+ if (!GetDelegate().DidCommit())
+ return;
+
+ auto* tab = TabImpl::FromWebContents(GetDelegate().GetWebContents());
+ if (!tab)
+ return;
+
+ const page_load_metrics::ContentfulPaintTimingInfo& largest_contentful_paint =
+ GetDelegate()
+ .GetLargestContentfulPaintHandler()
+ .MergeMainFrameAndSubframes();
+ if (!largest_contentful_paint.ContainsValidTime())
+ return;
+
+ auto* nav_controller =
+ static_cast<NavigationControllerImpl*>(tab->GetNavigationController());
+ nav_controller->OnLargestContentfulPaint(GetDelegate().GetNavigationStart(),
+ *largest_contentful_paint.Time());
+}
+
+} // namespace weblayer
diff --git a/chromium/weblayer/browser/page_load_metrics_observer_impl.h b/chromium/weblayer/browser/page_load_metrics_observer_impl.h
new file mode 100644
index 00000000000..7a58da52d0e
--- /dev/null
+++ b/chromium/weblayer/browser/page_load_metrics_observer_impl.h
@@ -0,0 +1,39 @@
+// 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_BROWSER_PAGE_LOAD_METRICS_OBSERVER_IMPL_H_
+#define WEBLAYER_BROWSER_PAGE_LOAD_METRICS_OBSERVER_IMPL_H_
+
+#include "components/page_load_metrics/browser/page_load_metrics_observer.h"
+
+namespace weblayer {
+
+class PageLoadMetricsObserverImpl
+ : public page_load_metrics::PageLoadMetricsObserver {
+ public:
+ PageLoadMetricsObserverImpl() = default;
+ ~PageLoadMetricsObserverImpl() override = default;
+
+ // page_load_metrics::PageLoadMetricsObserver implementation:
+ ObservePolicy FlushMetricsOnAppEnterBackground(
+ const page_load_metrics::mojom::PageLoadTiming& timing) override;
+ ObservePolicy OnHidden(
+ const page_load_metrics::mojom::PageLoadTiming& timing) override;
+ void OnComplete(
+ const page_load_metrics::mojom::PageLoadTiming& timing) override;
+ ObservePolicy OnCommit(content::NavigationHandle* navigation_handle,
+ ukm::SourceId source_id) override;
+ void OnFirstContentfulPaintInPage(
+ const page_load_metrics::mojom::PageLoadTiming& timing) override;
+
+ void ReportBufferedMetrics(
+ const page_load_metrics::mojom::PageLoadTiming& timing);
+
+ private:
+ bool reported_buffered_metrics_ = false;
+};
+
+} // namespace weblayer
+
+#endif // WEBLAYER_BROWSER_PAGE_LOAD_METRICS_OBSERVER_IMPL_H_
diff --git a/chromium/weblayer/browser/page_specific_content_settings_delegate.cc b/chromium/weblayer/browser/page_specific_content_settings_delegate.cc
index 817af927de0..39a8d0f2443 100644
--- a/chromium/weblayer/browser/page_specific_content_settings_delegate.cc
+++ b/chromium/weblayer/browser/page_specific_content_settings_delegate.cc
@@ -4,7 +4,7 @@
#include "weblayer/browser/page_specific_content_settings_delegate.h"
-#include "base/bind_helpers.h"
+#include "base/callback_helpers.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/permissions/permission_decision_auto_blocker.h"
#include "content/public/browser/render_process_host.h"
diff --git a/chromium/weblayer/browser/password_manager_driver_factory.cc b/chromium/weblayer/browser/password_manager_driver_factory.cc
index 2b59c275ccd..67eb3cd6b5e 100644
--- a/chromium/weblayer/browser/password_manager_driver_factory.cc
+++ b/chromium/weblayer/browser/password_manager_driver_factory.cc
@@ -61,6 +61,7 @@ class PasswordManagerDriverFactory::PasswordManagerDriver
}
void SameDocumentNavigation(autofill::mojom::SubmissionIndicatorEvent
submission_indication_event) override {}
+ void PasswordFormCleared(const autofill::FormData& form_data) override {}
void RecordSavePasswordProgress(const std::string& log) override {}
void UserModifiedPasswordField() override {}
void UserModifiedNonPasswordField(autofill::FieldRendererId renderer_id,
diff --git a/chromium/weblayer/browser/permissions/permission_manager_factory.cc b/chromium/weblayer/browser/permissions/permission_manager_factory.cc
index 0360af83c7b..348c40eb5b0 100644
--- a/chromium/weblayer/browser/permissions/permission_manager_factory.cc
+++ b/chromium/weblayer/browser/permissions/permission_manager_factory.cc
@@ -5,6 +5,7 @@
#include "weblayer/browser/permissions/permission_manager_factory.h"
#include "build/build_config.h"
+#include "components/background_sync/background_sync_permission_context.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/permissions/permission_context_base.h"
@@ -81,6 +82,8 @@ permissions::PermissionManager::PermissionContextMap CreatePermissionContexts(
std::make_unique<SafePermissionContext>(
browser_context, ContentSettingsType::MEDIASTREAM_CAMERA,
blink::mojom::FeaturePolicyFeature::kCamera);
+ permission_contexts[ContentSettingsType::BACKGROUND_SYNC] =
+ std::make_unique<BackgroundSyncPermissionContext>(browser_context);
// For now, all requests are denied. As features are added, their permission
// contexts can be added here instead of DeniedPermissionContext.
diff --git a/chromium/weblayer/browser/persistence/browser_persister_browsertest.cc b/chromium/weblayer/browser/persistence/browser_persister_browsertest.cc
index 7a7572cae05..8f26a2d6d56 100644
--- a/chromium/weblayer/browser/persistence/browser_persister_browsertest.cc
+++ b/chromium/weblayer/browser/persistence/browser_persister_browsertest.cc
@@ -4,13 +4,13 @@
#include "weblayer/browser/persistence/browser_persister.h"
-#include "base/bind_helpers.h"
+#include "base/callback_helpers.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/guid.h"
#include "base/path_service.h"
#include "base/run_loop.h"
-#include "base/test/bind_test_util.h"
+#include "base/test/bind.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "components/sessions/core/command_storage_manager_test_helper.h"
diff --git a/chromium/weblayer/browser/popup_blocker_browsertest.cc b/chromium/weblayer/browser/popup_blocker_browsertest.cc
index 664548ae5cc..0ad8e7aa77d 100644
--- a/chromium/weblayer/browser/popup_blocker_browsertest.cc
+++ b/chromium/weblayer/browser/popup_blocker_browsertest.cc
@@ -166,7 +166,7 @@ IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
GetWebContents(original_tab())->GetBrowserContext())
->SetContentSettingDefaultScope(popup_url, GURL(),
ContentSettingsType::POPUPS,
- std::string(), CONTENT_SETTING_ALLOW);
+ CONTENT_SETTING_ALLOW);
ExecuteScript(
original_tab(),
base::StringPrintf("window.open('%s')", popup_url.spec().c_str()), true);
@@ -201,7 +201,7 @@ IN_PROC_BROWSER_TEST_F(PopupBlockerBrowserTest,
GetWebContents(original_tab())->GetBrowserContext())
->SetContentSettingDefaultScope(popup_url, GURL(),
ContentSettingsType::POPUPS,
- std::string(), CONTENT_SETTING_BLOCK);
+ CONTENT_SETTING_BLOCK);
ExecuteScript(
original_tab(),
base::StringPrintf("window.open('%s')", popup_url.spec().c_str()), true);
diff --git a/chromium/weblayer/browser/prefetch_browsertest.cc b/chromium/weblayer/browser/prefetch_browsertest.cc
index 796d8905d73..df3bcafc68a 100644
--- a/chromium/weblayer/browser/prefetch_browsertest.cc
+++ b/chromium/weblayer/browser/prefetch_browsertest.cc
@@ -3,7 +3,9 @@
// found in the LICENSE file.
#include "base/files/file_path.h"
-#include "base/test/bind_test_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/bind.h"
+#include "build/build_config.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
@@ -78,7 +80,13 @@ IN_PROC_BROWSER_TEST_F(PrefetchBrowserTest, PrefetchWorks) {
// https://crbug.com/922362: When the prefetched request is redirected, DCHECKs
// in PrefetchURLLoader::FollowRedirect() failed due to "X-Client-Data" in
// removed_headers. Verify that it no longer does.
-IN_PROC_BROWSER_TEST_F(PrefetchBrowserTest, RedirectedPrefetch) {
+// TODO(https://crbug.com/1144142): Fails on TSan due to data race.
+#if defined(THREAD_SANITIZER)
+#define MAYBE_RedirectedPrefetch DISABLED_RedirectedPrefetch
+#else
+#define MAYBE_RedirectedPrefetch RedirectedPrefetch
+#endif
+IN_PROC_BROWSER_TEST_F(PrefetchBrowserTest, MAYBE_RedirectedPrefetch) {
std::vector<net::test_server::HttpRequest> requests;
net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
https_server.RegisterRequestHandler(base::BindLambdaForTesting(
diff --git a/chromium/weblayer/browser/profile_browsertest.cc b/chromium/weblayer/browser/profile_browsertest.cc
index e651d75f75e..e4fe35db188 100644
--- a/chromium/weblayer/browser/profile_browsertest.cc
+++ b/chromium/weblayer/browser/profile_browsertest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "base/test/bind_test_util.h"
+#include "base/test/bind.h"
#include "build/build_config.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "ui/gfx/image/image_unittest_util.h"
@@ -145,17 +145,15 @@ IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, ClearSiteSettings) {
->web_contents()
->GetBrowserContext());
EXPECT_EQ(settings_map->GetContentSetting(dse_origin, dse_origin,
- ContentSettingsType::GEOLOCATION,
- std::string()),
+ ContentSettingsType::GEOLOCATION),
CONTENT_SETTING_ALLOW);
EXPECT_EQ(settings_map->GetContentSetting(foo_origin, foo_origin,
- ContentSettingsType::GEOLOCATION,
- std::string()),
+ ContentSettingsType::GEOLOCATION),
CONTENT_SETTING_ASK);
- settings_map->SetContentSettingDefaultScope(
- foo_origin, foo_origin, ContentSettingsType::GEOLOCATION, std::string(),
- CONTENT_SETTING_ALLOW);
+ settings_map->SetContentSettingDefaultScope(foo_origin, foo_origin,
+ ContentSettingsType::GEOLOCATION,
+ CONTENT_SETTING_ALLOW);
// Ensure clearing things other than site data doesn't change it
base::RunLoop run_loop;
@@ -167,13 +165,11 @@ IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, ClearSiteSettings) {
run_loop.Run();
EXPECT_EQ(settings_map->GetContentSetting(dse_origin, dse_origin,
- ContentSettingsType::GEOLOCATION,
- std::string()),
+ ContentSettingsType::GEOLOCATION),
CONTENT_SETTING_ALLOW);
EXPECT_EQ(settings_map->GetContentSetting(foo_origin, foo_origin,
- ContentSettingsType::GEOLOCATION,
- std::string()),
+ ContentSettingsType::GEOLOCATION),
CONTENT_SETTING_ALLOW);
// Now clear site data.
@@ -183,12 +179,10 @@ IN_PROC_BROWSER_TEST_F(ProfileBrowserTest, ClearSiteSettings) {
run_loop2.Run();
EXPECT_EQ(settings_map->GetContentSetting(dse_origin, dse_origin,
- ContentSettingsType::GEOLOCATION,
- std::string()),
+ ContentSettingsType::GEOLOCATION),
CONTENT_SETTING_ALLOW);
EXPECT_EQ(settings_map->GetContentSetting(foo_origin, foo_origin,
- ContentSettingsType::GEOLOCATION,
- std::string()),
+ ContentSettingsType::GEOLOCATION),
CONTENT_SETTING_ASK);
}
diff --git a/chromium/weblayer/browser/profile_impl.cc b/chromium/weblayer/browser/profile_impl.cc
index b4abb9c6a66..0895e8fe1ba 100644
--- a/chromium/weblayer/browser/profile_impl.cc
+++ b/chromium/weblayer/browser/profile_impl.cc
@@ -32,7 +32,6 @@
#include "services/network/public/mojom/network_context.mojom.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
-#include "weblayer/browser/android/metrics/weblayer_metrics_service_client.h"
#include "weblayer/browser/browser_context_impl.h"
#include "weblayer/browser/browser_impl.h"
#include "weblayer/browser/browser_list.h"
@@ -52,6 +51,7 @@
#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
#include "components/unified_consent/pref_names.h"
#include "ui/gfx/android/java_bitmap.h"
+#include "weblayer/browser/android/metrics/weblayer_metrics_service_client.h"
#include "weblayer/browser/browser_process.h"
#include "weblayer/browser/java/jni/ProfileImpl_jni.h"
#include "weblayer/browser/safe_browsing/safe_browsing_service.h"
@@ -124,7 +124,7 @@ void OnDidGetCachedFaviconForPageUrl(
gfx::Image image) {
SkBitmap favicon = image.AsImageSkia().GetRepresentation(1.0f).GetBitmap();
base::android::RunObjectCallbackAndroid(
- callback, favicon.empty() ? nullptr : gfx::ConvertToJavaBitmap(&favicon));
+ callback, favicon.empty() ? nullptr : gfx::ConvertToJavaBitmap(favicon));
}
#endif // OS_ANDROID
diff --git a/chromium/weblayer/browser/proxying_url_loader_factory_impl.cc b/chromium/weblayer/browser/proxying_url_loader_factory_impl.cc
index f086c1f7ccb..4bad9f63551 100644
--- a/chromium/weblayer/browser/proxying_url_loader_factory_impl.cc
+++ b/chromium/weblayer/browser/proxying_url_loader_factory_impl.cc
@@ -13,13 +13,12 @@
#include "content/public/browser/web_contents.h"
#include "mojo/public/cpp/system/data_pipe_producer.h"
#include "mojo/public/cpp/system/string_data_source.h"
+#include "weblayer/browser/navigation_entry_data.h"
namespace weblayer {
namespace {
-const char kCacheKey[] = "weblayer_entry_cache_data";
-
struct WriteData {
mojo::Remote<network::mojom::URLLoaderClient> client;
std::string data;
@@ -109,37 +108,6 @@ bool IsCachedResponseValid(net::HttpResponseHeaders* headers,
base::Time::Now()) == net::VALIDATION_NONE;
}
-// Stored on the NavigationEntry when we have a cached response from an
-// InputStream.
-class NavigationEntryCache : public base::SupportsUserData::Data {
- public:
- NavigationEntryCache(network::mojom::URLResponseHeadPtr response_head,
- const std::string& data,
- base::Time request_time,
- base::Time response_time)
- : response_head_(std::move(response_head)),
- data_(data),
- request_time_(request_time),
- response_time_(response_time) {}
-
- std::unique_ptr<Data> Clone() override {
- return std::make_unique<NavigationEntryCache>(
- response_head_.Clone(), data_, request_time_, response_time_);
- }
-
- network::mojom::URLResponseHead* response_head() {
- return response_head_.get();
- }
- const std::string& data() const { return data_; }
- const base::Time& request_time() const { return request_time_; }
- const base::Time& response_time() const { return response_time_; }
-
- private:
- network::mojom::URLResponseHeadPtr response_head_;
- std::string data_;
- base::Time request_time_;
- base::Time response_time_;
-};
// A ResponseDelegate for AndroidStreamReaderURLLoader which will cache the
// response if it's successful. This allows back-forward navigations to reuse an
@@ -177,9 +145,13 @@ class CachingResponseDelegate : public embedder_support::ResponseDelegateImpl {
if (!entry)
return;
- auto cache_data = std::make_unique<NavigationEntryCache>(
- std::move(response_head_), data, request_time_, response_time_);
- entry->SetUserData(kCacheKey, std::move(cache_data));
+ auto* entry_data = NavigationEntryData::Get(entry);
+ auto response_data = std::make_unique<NavigationEntryData::ResponseData>();
+ response_data->response_head = std::move(response_head_);
+ response_data->data = data;
+ response_data->request_time = request_time_;
+ response_data->response_time = response_time_;
+ entry_data->set_response_data(std::move(response_data));
}
private:
@@ -230,15 +202,19 @@ bool ProxyingURLLoaderFactoryImpl::HasCachedInputStream(
if (!entry)
return false;
- auto* cache =
- static_cast<NavigationEntryCache*>(entry->GetUserData(kCacheKey));
- if (!cache)
+ auto* entry_data = NavigationEntryData::Get(entry);
+ if (!entry_data)
+ return false;
+
+ auto* response_data = entry_data->response_data();
+ if (!response_data)
return false;
- if (!IsCachedResponseValid(cache->response_head()->headers.get(),
- cache->request_time(), cache->response_time())) {
+ if (!IsCachedResponseValid(response_data->response_head->headers.get(),
+ response_data->request_time,
+ response_data->response_time)) {
// Cache expired so remove it.
- entry->RemoveUserData(kCacheKey);
+ entry_data->reset_response_data();
return false;
}
@@ -269,10 +245,10 @@ void ProxyingURLLoaderFactoryImpl::CreateLoaderAndStart(
navigation_entry_unique_id_)) {
auto* entry = GetNavigationEntryFromUniqueId(frame_tree_node_id_,
navigation_entry_unique_id_);
- auto* cache =
- static_cast<NavigationEntryCache*>(entry->GetUserData(kCacheKey));
- StartCachedLoad(std::move(client), cache->response_head()->Clone(),
- cache->data());
+ auto* entry_data = NavigationEntryData::Get(entry);
+ auto* response_data = entry_data->response_data();
+ StartCachedLoad(std::move(client), response_data->response_head->Clone(),
+ response_data->data);
return;
}
}
diff --git a/chromium/weblayer/browser/resources/weblayer_internals/weblayer_internals.html b/chromium/weblayer/browser/resources/weblayer_internals/weblayer_internals.html
index 196be1150d6..8c10a03d531 100644
--- a/chromium/weblayer/browser/resources/weblayer_internals/weblayer_internals.html
+++ b/chromium/weblayer/browser/resources/weblayer_internals/weblayer_internals.html
@@ -6,6 +6,7 @@
<link rel="stylesheet" href="chrome://resources/css/text_defaults.css">
<script src="chrome://resources/js/cr.js"></script>
+ <script src="chrome://resources/js/assert.js"></script>
<script src="chrome://resources/js/promise_resolver.js"></script>
<script src="chrome://resources/js/util.js"></script>
<script src="chrome://resources/mojo/mojo/public/js/mojo_bindings_lite.js"></script>
diff --git a/chromium/weblayer/browser/safe_browsing/safe_browsing_blocking_page.cc b/chromium/weblayer/browser/safe_browsing/safe_browsing_blocking_page.cc
index 5be57facbb1..f32cc925207 100644
--- a/chromium/weblayer/browser/safe_browsing/safe_browsing_blocking_page.cc
+++ b/chromium/weblayer/browser/safe_browsing/safe_browsing_blocking_page.cc
@@ -4,6 +4,7 @@
#include "weblayer/browser/safe_browsing/safe_browsing_blocking_page.h"
+#include "base/metrics/histogram_macros.h"
#include "components/security_interstitials/content/security_interstitial_controller_client.h"
#include "components/security_interstitials/content/settings_page_helper.h"
#include "components/security_interstitials/content/unsafe_resource_util.h"
@@ -35,11 +36,15 @@ SafeBrowsingBlockingPage::SafeBrowsingBlockingPage(
std::move(controller_client),
display_options) {}
+// static
SafeBrowsingBlockingPage* SafeBrowsingBlockingPage::CreateBlockingPage(
SafeBrowsingUIManager* ui_manager,
content::WebContents* web_contents,
const GURL& main_frame_url,
const UnsafeResource& unsafe_resource) {
+ // Log the resource type that triggers the safe browsing blocking page.
+ UMA_HISTOGRAM_ENUMERATION("SafeBrowsing.BlockingPage.ResourceType",
+ unsafe_resource.resource_type);
const UnsafeResourceList unsafe_resources{unsafe_resource};
content::NavigationEntry* entry =
security_interstitials::GetNavigationEntryForResource(unsafe_resource);
diff --git a/chromium/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc b/chromium/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc
index 0af1ccd68e7..505e0567fd5 100644
--- a/chromium/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc
+++ b/chromium/weblayer/browser/safe_browsing/safe_browsing_browsertest.cc
@@ -25,6 +25,7 @@
#include "weblayer/browser/tab_impl.h"
#include "weblayer/public/navigation.h"
#include "weblayer/public/navigation_controller.h"
+#include "weblayer/public/navigation_observer.h"
#include "weblayer/public/profile.h"
#include "weblayer/public/tab.h"
#include "weblayer/shell/browser/shell.h"
@@ -36,6 +37,38 @@ namespace weblayer {
namespace {
+// Observer customized for safe browsing navigation failures.
+class SafeBrowsingErrorNavigationObserver : public NavigationObserver {
+ public:
+ SafeBrowsingErrorNavigationObserver(const GURL& url, Shell* shell)
+ : url_(url), tab_(shell->tab()) {
+ tab_->GetNavigationController()->AddObserver(this);
+ }
+
+ ~SafeBrowsingErrorNavigationObserver() override {
+ tab_->GetNavigationController()->RemoveObserver(this);
+ }
+
+ void NavigationFailed(Navigation* navigation) override {
+ if (navigation->GetURL() != url_)
+ return;
+
+ EXPECT_EQ(navigation->GetLoadError(),
+ Navigation::LoadError::kSafeBrowsingError);
+ run_loop_.Quit();
+ }
+
+ // Begins waiting for a Navigation within |shell_| and to |url_| to fail. In
+ // the failure callback verifies that the navigation failed with a safe
+ // browsing error.
+ void WaitForNavigationFailureWithSafeBrowsingError() { run_loop_.Run(); }
+
+ private:
+ const GURL url_;
+ Tab* tab_;
+ base::RunLoop run_loop_;
+};
+
void RunCallbackOnIOThread(
std::unique_ptr<safe_browsing::SafeBrowsingApiHandler::URLCheckCallbackMeta>
callback,
@@ -68,6 +101,8 @@ class FakeSafeBrowsingApiHandler
restrictions_[url] = threat_type;
}
+ void ClearRestrictions() { restrictions_.clear(); }
+
private:
safe_browsing::SBThreatType GetSafeBrowsingRestriction(const GURL& url) {
auto restrictions_iter = restrictions_.find(url);
@@ -210,6 +245,25 @@ IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, ShowsInterstitial_Phishing) {
NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_PHISHING, true);
}
+IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, CheckNavigationErrorType) {
+ auto threat_types = {
+ safe_browsing::SB_THREAT_TYPE_URL_PHISHING,
+ safe_browsing::SB_THREAT_TYPE_URL_MALWARE,
+ safe_browsing::SB_THREAT_TYPE_URL_UNWANTED,
+ safe_browsing::SB_THREAT_TYPE_BILLING,
+ };
+
+ for (auto threat_type : threat_types) {
+ SafeBrowsingErrorNavigationObserver observer(url_, shell());
+
+ fake_handler_->ClearRestrictions();
+ fake_handler_->AddRestriction(url_, threat_type);
+ shell()->tab()->GetNavigationController()->Navigate(url_);
+
+ observer.WaitForNavigationFailureWithSafeBrowsingError();
+ }
+}
+
IN_PROC_BROWSER_TEST_F(SafeBrowsingBrowserTest, ShowsInterstitial_Unwanted) {
NavigateWithThreatType(safe_browsing::SB_THREAT_TYPE_URL_UNWANTED, true);
}
diff --git a/chromium/weblayer/browser/safe_browsing/safe_browsing_service.cc b/chromium/weblayer/browser/safe_browsing/safe_browsing_service.cc
index 632d2f84d53..adb19d1909c 100644
--- a/chromium/weblayer/browser/safe_browsing/safe_browsing_service.cc
+++ b/chromium/weblayer/browser/safe_browsing/safe_browsing_service.cc
@@ -160,12 +160,35 @@ void SafeBrowsingService::CreateSafeBrowsingUIManager() {
}
void SafeBrowsingService::CreateAndStartSafeBrowsingDBManager() {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
DCHECK(!safe_browsing_db_manager_);
safe_browsing_db_manager_ =
new safe_browsing::RemoteSafeBrowsingDatabaseManager();
+ if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
+ // Posting a task to start the DB here ensures that it will be started by
+ // the time that a consumer uses it on the IO thread, as such a consumer
+ // would need to make it available for usage on the IO thread via a
+ // PostTask() that will be ordered after this one.
+ content::GetIOThreadTaskRunner({})->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &SafeBrowsingService::StartSafeBrowsingDBManagerOnIOThread,
+ base::Unretained(this)));
+ } else {
+ StartSafeBrowsingDBManagerOnIOThread();
+ }
+}
+
+void SafeBrowsingService::StartSafeBrowsingDBManagerOnIOThread() {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ DCHECK(safe_browsing_db_manager_);
+
+ if (started_db_manager_)
+ return;
+
+ started_db_manager_ = true;
+
// V4ProtocolConfig is not used. Just create one with empty values.
safe_browsing::V4ProtocolConfig config("", false, "", "");
safe_browsing_db_manager_->StartOnIOThread(GetURLLoaderFactoryOnIOThread(),
@@ -225,6 +248,7 @@ void SafeBrowsingService::StopDBManagerOnIOThread() {
if (safe_browsing_db_manager_) {
safe_browsing_db_manager_->StopOnIOThread(true /*shutdown*/);
safe_browsing_db_manager_.reset();
+ started_db_manager_ = false;
}
}
diff --git a/chromium/weblayer/browser/safe_browsing/safe_browsing_service.h b/chromium/weblayer/browser/safe_browsing/safe_browsing_service.h
index 129a0ea1234..197f1ca160b 100644
--- a/chromium/weblayer/browser/safe_browsing/safe_browsing_service.h
+++ b/chromium/weblayer/browser/safe_browsing/safe_browsing_service.h
@@ -65,14 +65,19 @@ class SafeBrowsingService {
scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory();
+ // May be called on the UI or IO thread. The instance returned should be
+ // *accessed* only on the IO thread.
+ safe_browsing::RemoteSafeBrowsingDatabaseManager* GetSafeBrowsingDBManager();
+
private:
SafeBrowsingUIManager* GetSafeBrowsingUIManager();
- safe_browsing::RemoteSafeBrowsingDatabaseManager* GetSafeBrowsingDBManager();
// Executed on IO thread
scoped_refptr<safe_browsing::UrlCheckerDelegate>
GetSafeBrowsingUrlCheckerDelegate();
+ // Safe to call multiple times; invocations after the first will be no-ops.
+ void StartSafeBrowsingDBManagerOnIOThread();
void CreateSafeBrowsingUIManager();
void CreateAndStartSafeBrowsingDBManager();
scoped_refptr<network::SharedURLLoaderFactory>
@@ -89,7 +94,9 @@ class SafeBrowsingService {
// is used by SimpleURLLoader for Safe Browsing requests.
std::unique_ptr<safe_browsing::SafeBrowsingNetworkContext> network_context_;
- // Accessed on IO thread only.
+ // May be created on UI thread and have references obtained to it on that
+ // thread for later passing to the IO thread, but should be *accessed* only
+ // on the IO thread.
scoped_refptr<safe_browsing::RemoteSafeBrowsingDatabaseManager>
safe_browsing_db_manager_;
@@ -105,6 +112,10 @@ class SafeBrowsingService {
std::string user_agent_;
+ // Whether |safe_browsing_db_manager_| has been started. Accessed only on the
+ // IO thread.
+ bool started_db_manager_ = false;
+
DISALLOW_COPY_AND_ASSIGN(SafeBrowsingService);
};
diff --git a/chromium/weblayer/browser/safe_browsing/url_checker_delegate_impl.cc b/chromium/weblayer/browser/safe_browsing/url_checker_delegate_impl.cc
index 9bd4352df62..ecb3fbec548 100644
--- a/chromium/weblayer/browser/safe_browsing/url_checker_delegate_impl.cc
+++ b/chromium/weblayer/browser/safe_browsing/url_checker_delegate_impl.cc
@@ -5,7 +5,7 @@
#include "weblayer/browser/safe_browsing/url_checker_delegate_impl.h"
#include "base/bind.h"
-#include "components/prerender/browser/prerender_manager.h"
+#include "components/no_state_prefetch/browser/prerender_manager.h"
#include "components/safe_browsing/core/db/database_manager.h"
#include "components/security_interstitials/core/unsafe_resource.h"
#include "content/public/browser/browser_task_traits.h"
diff --git a/chromium/weblayer/browser/signin_url_loader_throttle.cc b/chromium/weblayer/browser/signin_url_loader_throttle.cc
index 1fee7fec0de..e5660f55808 100644
--- a/chromium/weblayer/browser/signin_url_loader_throttle.cc
+++ b/chromium/weblayer/browser/signin_url_loader_throttle.cc
@@ -141,8 +141,12 @@ void SigninURLLoaderThrottle::ProcessRequest(
// Disable incognito and adding accounts for now. This shouldn't matter in
// practice though since we are skipping the /SignOutOptions page completely
// with the manage=true param.
+ //
+ // TODO(crbug.com/1134042): Check whether the child account status should also
+ // be sent in the Mirror request header from WebLayer.
signin::AppendOrRemoveMirrorRequestHeader(
&request_adapter, new_url, delegate->GetGaiaId(),
+ base::nullopt /* is_child_account */,
signin::AccountConsistencyMethod::kMirror,
CookieSettingsFactory::GetForBrowserContext(browser_context_).get(),
signin::PROFILE_MODE_INCOGNITO_DISABLED |
diff --git a/chromium/weblayer/browser/subresource_filter_browsertest.cc b/chromium/weblayer/browser/subresource_filter_browsertest.cc
index 8f5435e3dd7..b8948812fdb 100644
--- a/chromium/weblayer/browser/subresource_filter_browsertest.cc
+++ b/chromium/weblayer/browser/subresource_filter_browsertest.cc
@@ -2,8 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/json/json_reader.h"
+#include "components/subresource_filter/content/browser/ruleset_service.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/resource/resource_bundle.h"
#include "weblayer/browser/browser_process.h"
+#include "weblayer/grit/weblayer_resources.h"
#include "weblayer/test/weblayer_browser_test.h"
namespace weblayer {
@@ -23,4 +27,36 @@ IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, RulesetService) {
nullptr);
}
+// Tests that the ruleset is published as part of startup.
+IN_PROC_BROWSER_TEST_F(SubresourceFilterBrowserTest, RulesArePublished) {
+ auto* ruleset_service =
+ BrowserProcess::GetInstance()->subresource_filter_ruleset_service();
+
+ // Publishing might or might not have already finished at this point; wait for
+ // it to finish if necessary.
+ if (!ruleset_service->GetMostRecentlyIndexedVersion().IsValid()) {
+ base::RunLoop run_loop;
+ ruleset_service->SetRulesetPublishedCallbackForTesting(
+ run_loop.QuitClosure());
+
+ run_loop.Run();
+ }
+
+ auto ruleset_version = ruleset_service->GetMostRecentlyIndexedVersion();
+ EXPECT_TRUE(ruleset_version.IsValid());
+
+ std::string most_recently_indexed_content_version =
+ ruleset_version.content_version;
+
+ std::string packaged_ruleset_manifest_string =
+ ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
+ IDR_SUBRESOURCE_FILTER_UNINDEXED_RULESET_MANIFEST_JSON);
+ auto packaged_ruleset_manifest =
+ base::JSONReader::Read(packaged_ruleset_manifest_string);
+ std::string* packaged_content_version =
+ packaged_ruleset_manifest->FindStringKey("version");
+
+ EXPECT_EQ(most_recently_indexed_content_version, *packaged_content_version);
+}
+
} // namespace weblayer
diff --git a/chromium/weblayer/browser/tab_impl.cc b/chromium/weblayer/browser/tab_impl.cc
index 98d19f83b06..9ee00624c5a 100644
--- a/chromium/weblayer/browser/tab_impl.cc
+++ b/chromium/weblayer/browser/tab_impl.cc
@@ -22,6 +22,7 @@
#include "components/blocked_content/popup_tracker.h"
#include "components/captive_portal/core/buildflags.h"
#include "components/content_settings/browser/page_specific_content_settings.h"
+#include "components/embedder_support/android/util/user_agent_utils.h"
#include "components/find_in_page/find_tab_helper.h"
#include "components/find_in_page/find_types.h"
#include "components/js_injection/browser/js_communication_host.h"
@@ -37,8 +38,10 @@
#include "components/webrtc/media_stream_devices_controller.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/context_menu_params.h"
#include "content/public/browser/file_select_listener.h"
#include "content/public/browser/navigation_controller.h"
+#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
@@ -46,8 +49,8 @@
#include "content/public/browser/renderer_preferences_util.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_observer.h"
+#include "third_party/blink/public/common/renderer_preferences/renderer_preferences.h"
#include "third_party/blink/public/common/web_preferences/web_preferences.h"
-#include "third_party/blink/public/mojom/renderer_preferences.mojom.h"
#include "third_party/blink/public/mojom/window_features/window_features.mojom.h"
#include "ui/base/window_open_disposition.h"
#include "weblayer/browser/autofill_client_impl.h"
@@ -63,6 +66,7 @@
#include "weblayer/browser/infobar_service.h"
#include "weblayer/browser/js_communication/web_message_host_factory_wrapper.h"
#include "weblayer/browser/navigation_controller_impl.h"
+#include "weblayer/browser/navigation_entry_data.h"
#include "weblayer/browser/no_state_prefetch/prerender_tab_helper.h"
#include "weblayer/browser/page_load_metrics_initialize.h"
#include "weblayer/browser/page_specific_content_settings_delegate.h"
@@ -72,6 +76,7 @@
#include "weblayer/browser/popup_navigation_delegate_impl.h"
#include "weblayer/browser/profile_impl.h"
#include "weblayer/browser/translate_client_impl.h"
+#include "weblayer/browser/user_agent.h"
#include "weblayer/browser/weblayer_features.h"
#include "weblayer/common/isolated_world_ids.h"
#include "weblayer/public/fullscreen_delegate.h"
@@ -92,6 +97,7 @@
#include "base/trace_event/trace_event.h"
#include "components/autofill/android/provider/autofill_provider_android.h"
#include "components/browser_ui/sms/android/sms_infobar.h"
+#include "components/download/content/public/context_menu_download.h"
#include "components/embedder_support/android/contextmenu/context_menu_builder.h"
#include "components/embedder_support/android/delegate/color_chooser_android.h"
#include "components/javascript_dialogs/tab_modal_dialog_manager.h" // nogncheck
@@ -105,6 +111,7 @@
#include "weblayer/browser/javascript_tab_modal_dialog_manager_delegate_android.h"
#include "weblayer/browser/js_communication/web_message_host_factory_proxy.h"
#include "weblayer/browser/translate_client_impl.h"
+#include "weblayer/browser/url_bar/trusted_cdn_observer.h"
#include "weblayer/browser/weblayer_factory_impl_android.h"
#include "weblayer/browser/webrtc/media_stream_manager.h"
#endif
@@ -201,7 +208,7 @@ void ConvertToJavaBitmapBackgroundThread(
base::OnceCallback<void(const ScopedJavaGlobalRef<jobject>&)> callback) {
// Make sure to only pass ScopedJavaGlobalRef between threads.
ScopedJavaGlobalRef<jobject> java_bitmap = ScopedJavaGlobalRef<jobject>(
- gfx::ConvertToJavaBitmap(&bitmap, gfx::OomBehavior::kReturnNullOnOom));
+ gfx::ConvertToJavaBitmap(bitmap, gfx::OomBehavior::kReturnNullOnOom));
content::GetUIThreadTaskRunner({})->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), std::move(java_bitmap)));
}
@@ -256,6 +263,15 @@ static ScopedJavaLocalRef<jobject> JNI_TabImpl_FromWebContents(
return nullptr;
}
+static void JNI_TabImpl_DestroyContextMenuParams(
+ JNIEnv* env,
+ jlong native_context_menu_params) {
+ // Note: this runs on the finalizer thread which isn't the UI thread.
+ auto* context_menu_params =
+ reinterpret_cast<content::ContextMenuParams*>(native_context_menu_params);
+ delete context_menu_params;
+}
+
TabImpl::TabImpl(ProfileImpl* profile,
const JavaParamRef<jobject>& java_impl,
std::unique_ptr<content::WebContents> web_contents)
@@ -281,12 +297,6 @@ TabImpl::TabImpl(ProfileImpl* profile,
// notifying weblayer observers of changes.
FaviconTabHelper::CreateForWebContents(web_contents_.get());
- // By default renderer initiated navigations inherit the user-agent override
- // of the current NavigationEntry. For WebLayer, the user-agent override is
- // set on a per NavigationEntry entry basis.
- web_contents_->SetRendererInitiatedUserAgentOverrideOption(
- content::NavigationController::UA_OVERRIDE_FALSE);
-
UpdateRendererPrefs(false);
locale_change_subscription_ =
i18n::RegisterLocaleChangeCallback(base::BindRepeating(
@@ -301,10 +311,6 @@ TabImpl::TabImpl(ProfileImpl* profile,
navigation_controller_ = std::make_unique<NavigationControllerImpl>(this);
-#if defined(OS_ANDROID)
- InfoBarService::CreateForWebContents(web_contents_.get());
-#endif
-
find_in_page::FindTabHelper::CreateForWebContents(web_contents_.get());
GetFindTabHelper()->AddObserver(this);
@@ -341,6 +347,8 @@ TabImpl::TabImpl(ProfileImpl* profile,
browser_controls_navigation_state_handler_ =
std::make_unique<BrowserControlsNavigationStateHandler>(
web_contents_.get(), this);
+
+ TrustedCDNObserver::CreateForWebContents(web_contents_.get());
#endif
#if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
@@ -410,6 +418,10 @@ void TabImpl::RemoveDataObserver(DataObserver* observer) {
data_observers_.RemoveObserver(observer);
}
+Browser* TabImpl::GetBrowser() {
+ return browser_;
+}
+
void TabImpl::SetErrorPageDelegate(ErrorPageDelegate* delegate) {
error_page_delegate_ = delegate;
}
@@ -543,7 +555,8 @@ void TabImpl::ShowContextMenu(const content::ContextMenuParams& params) {
#if defined(OS_ANDROID)
Java_TabImpl_showContextMenu(
base::android::AttachCurrentThread(), java_impl_,
- context_menu::BuildJavaContextMenuParams(params));
+ context_menu::BuildJavaContextMenuParams(params),
+ reinterpret_cast<jlong>(new content::ContextMenuParams(params)));
#endif
}
@@ -795,6 +808,58 @@ void TabImpl::SetTranslateTargetLanguage(
translate_manager->SetPredefinedTargetLanguage(
base::android::ConvertJavaStringToUTF8(env, translate_target_lang));
}
+
+void TabImpl::SetDesktopUserAgentEnabled(JNIEnv* env, jboolean enable) {
+ if (desktop_user_agent_enabled_ == enable)
+ return;
+
+ desktop_user_agent_enabled_ = enable;
+
+ // Reset state that an earlier call to Navigation::SetUserAgentString()
+ // could have modified.
+ embedder_support::SetDesktopUserAgentOverride(web_contents_.get(),
+ GetUserAgentMetadata());
+ web_contents_->SetRendererInitiatedUserAgentOverrideOption(
+ content::NavigationController::UA_OVERRIDE_INHERIT);
+
+ content::NavigationEntry* entry =
+ web_contents_->GetController().GetLastCommittedEntry();
+ if (!entry)
+ return;
+
+ entry->SetIsOverridingUserAgent(enable);
+ web_contents_->NotifyPreferencesChanged();
+ web_contents_->GetController().Reload(
+ content::ReloadType::ORIGINAL_REQUEST_URL, true);
+}
+
+jboolean TabImpl::IsDesktopUserAgentEnabled(JNIEnv* env) {
+ auto* entry = web_contents_->GetController().GetLastCommittedEntry();
+ if (!entry)
+ return false;
+
+ // The same user agent override mechanism is used for per-navigation user
+ // agent and desktop mode. Make sure not to return desktop mode for
+ // navigation entries which used a per-navigation user agent.
+ auto* entry_data = NavigationEntryData::Get(entry);
+ if (entry_data && entry_data->per_navigation_user_agent_override())
+ return false;
+
+ return entry->GetIsOverridingUserAgent();
+}
+
+void TabImpl::Download(JNIEnv* env, jlong native_context_menu_params) {
+ auto* context_menu_params =
+ reinterpret_cast<content::ContextMenuParams*>(native_context_menu_params);
+
+ bool is_link = context_menu_params->media_type !=
+ blink::ContextMenuDataMediaType::kImage &&
+ context_menu_params->media_type !=
+ blink::ContextMenuDataMediaType::kVideo;
+
+ download::CreateContextMenuDownload(web_contents_.get(), *context_menu_params,
+ std::string(), is_link);
+}
#endif // OS_ANDROID
content::WebContents* TabImpl::OpenURLFromTab(
@@ -975,10 +1040,6 @@ bool TabImpl::OnlyExpandTopControlsAtPageTop() {
#endif
}
-bool TabImpl::EmbedsFullscreenWidget() {
- return true;
-}
-
void TabImpl::RequestMediaAccessPermission(
content::WebContents* web_contents,
const content::MediaStreamRequest& request,
@@ -1171,6 +1232,30 @@ void TabImpl::OnUpdateBrowserControlsStateBecauseOfProcessSwitch(
// bounce around.
UpdateBrowserControlsState(content::BROWSER_CONTROLS_STATE_SHOWN, false);
} else {
+ if (did_commit && current_browser_controls_visibility_constraint_ ==
+ content::BROWSER_CONTROLS_STATE_BOTH) {
+ // If the current state is BROWSER_CONTROLS_STATE_BOTH, then
+ // TabImpl::UpdateBrowserControlsState() is going to call
+ // WebContents::UpdateBrowserControlsState() with both current and
+ // constraints set to BROWSER_CONTROLS_STATE_BOTH. cc does
+ // nothing in this case. During a navigation the top-view needs to be
+ // shown. To force the top-view to show, supply
+ // BROWSER_CONTROLS_STATE_SHOWN. This path is only hit if top-view
+ // is configured to only-expand-at-top, as in this case the top-view isn't
+ // forced shown during a page load.
+ //
+ // It's entirely possible the scroll offset is changed as part of the
+ // loading process (such as happens with back/forward navigation or
+ // links part way down a page). Trying to detect this and compensate
+ // here is likely to be racy, so the top-view is always shown.
+ const bool animate =
+ !base::FeatureList::IsEnabled(kImmediatelyHideBrowserControlsForTest);
+ web_contents_->GetMainFrame()->UpdateBrowserControlsState(
+ content::BROWSER_CONTROLS_STATE_BOTH,
+ content::BROWSER_CONTROLS_STATE_SHOWN, animate);
+ // This falls through to call UpdateBrowserControlsState() again to
+ // ensure the constraint is set back to BOTH.
+ }
UpdateBrowserControlsState(
content::BROWSER_CONTROLS_STATE_BOTH,
current_browser_controls_visibility_constraint_ !=
@@ -1199,8 +1284,7 @@ void TabImpl::OnExitFullscreen() {
}
void TabImpl::UpdateRendererPrefs(bool should_sync_prefs) {
- blink::mojom::RendererPreferences* prefs =
- web_contents_->GetMutableRendererPrefs();
+ blink::RendererPreferences* prefs = web_contents_->GetMutableRendererPrefs();
content::UpdateFontRendererPreferencesFromSystemSettings(prefs);
prefs->accept_languages = i18n::GetAcceptLangs();
if (should_sync_prefs)
diff --git a/chromium/weblayer/browser/tab_impl.h b/chromium/weblayer/browser/tab_impl.h
index 7dfcf1ef5e7..5ce0833556e 100644
--- a/chromium/weblayer/browser/tab_impl.h
+++ b/chromium/weblayer/browser/tab_impl.h
@@ -139,6 +139,8 @@ class TabImpl : public Tab,
return java_impl_;
}
+ bool desktop_user_agent_enabled() { return desktop_user_agent_enabled_; }
+
// Call this method to disable integration with the system-level Autofill
// infrastructure. Useful in conjunction with InitializeAutofillForTests().
// Should be called early in the lifetime of WebLayer, and in
@@ -194,6 +196,9 @@ class TabImpl : public Tab,
void SetTranslateTargetLanguage(
JNIEnv* env,
const base::android::JavaParamRef<jstring>& translate_target_lang);
+ void SetDesktopUserAgentEnabled(JNIEnv* env, jboolean enable);
+ jboolean IsDesktopUserAgentEnabled(JNIEnv* env);
+ void Download(JNIEnv* env, jlong native_context_menu_params);
#endif
ErrorPageDelegate* error_page_delegate() { return error_page_delegate_; }
@@ -206,6 +211,7 @@ class TabImpl : public Tab,
}
// Tab:
+ Browser* GetBrowser() override;
void SetErrorPageDelegate(ErrorPageDelegate* delegate) override;
void SetFullscreenDelegate(FullscreenDelegate* delegate) override;
void SetNewTabDelegate(NewTabDelegate* delegate) override;
@@ -271,7 +277,6 @@ class TabImpl : public Tab,
content::WebContents* web_contents) override;
bool OnlyExpandTopControlsAtPageTop() override;
bool ShouldAnimateBrowserControlsHeightChanges() override;
- bool EmbedsFullscreenWidget() override;
void RequestMediaAccessPermission(
content::WebContents* web_contents,
const content::MediaStreamRequest& request,
@@ -387,6 +392,8 @@ class TabImpl : public Tab,
std::map<std::string, std::unique_ptr<WebMessageHostFactoryProxy>>
js_name_to_proxy_;
+
+ bool desktop_user_agent_enabled_ = false;
#endif
bool is_fullscreen_ = false;
diff --git a/chromium/weblayer/browser/translate_client_impl.cc b/chromium/weblayer/browser/translate_client_impl.cc
index 89d1b13e72d..450cce98ddd 100644
--- a/chromium/weblayer/browser/translate_client_impl.cc
+++ b/chromium/weblayer/browser/translate_client_impl.cc
@@ -132,6 +132,11 @@ bool TranslateClientImpl::IsTranslatableURL(const GURL& url) {
return translate::IsTranslatableURL(url);
}
+bool TranslateClientImpl::IsAutofillAssistantRunning() const {
+ // TODO(crbug.com/1051559): Revise if/when WebLayer supports Autobot.
+ return false;
+}
+
void TranslateClientImpl::ShowReportLanguageDetectionErrorUI(
const GURL& report_url) {
NOTREACHED();
diff --git a/chromium/weblayer/browser/translate_client_impl.h b/chromium/weblayer/browser/translate_client_impl.h
index 99709246818..592336dda0a 100644
--- a/chromium/weblayer/browser/translate_client_impl.h
+++ b/chromium/weblayer/browser/translate_client_impl.h
@@ -64,6 +64,7 @@ class TranslateClientImpl
bool triggered_from_menu) override;
bool IsTranslatableURL(const GURL& url) override;
void ShowReportLanguageDetectionErrorUI(const GURL& report_url) override;
+ bool IsAutofillAssistantRunning() const override;
// ContentTranslateDriver::Observer implementation.
void OnLanguageDetermined(
diff --git a/chromium/weblayer/browser/translate_compact_infobar.cc b/chromium/weblayer/browser/translate_compact_infobar.cc
index 808fb81b19c..7c7719a25c6 100644
--- a/chromium/weblayer/browser/translate_compact_infobar.cc
+++ b/chromium/weblayer/browser/translate_compact_infobar.cc
@@ -221,6 +221,13 @@ void TranslateCompactInfoBar::OnTranslateStepChanged(
}
}
+void TranslateCompactInfoBar::OnTargetLanguageChanged(
+ const std::string& target_language_code) {
+ // In WebLayer, target language changes are only initiated by the UI. This
+ // method should always be a no-op.
+ DCHECK_EQ(GetDelegate()->target_language_code(), target_language_code);
+}
+
bool TranslateCompactInfoBar::IsDeclinedByUser() {
// Whether there is any affirmative action bit.
return action_flags_ == FLAG_NONE;
diff --git a/chromium/weblayer/browser/translate_compact_infobar.h b/chromium/weblayer/browser/translate_compact_infobar.h
index 2e85f5ba2d1..52253bf50e6 100644
--- a/chromium/weblayer/browser/translate_compact_infobar.h
+++ b/chromium/weblayer/browser/translate_compact_infobar.h
@@ -53,6 +53,8 @@ class TranslateCompactInfoBar
void OnTranslateStepChanged(
translate::TranslateStep step,
translate::TranslateErrors::Type error_type) override;
+ void OnTargetLanguageChanged(
+ const std::string& target_language_code) override;
// Returns true if the user didn't take any affirmative action.
// The function will be called when the translate infobar is dismissed.
// If it's true, we will record a declined event.
diff --git a/chromium/weblayer/browser/ukm_page_load_metrics_observer.cc b/chromium/weblayer/browser/ukm_page_load_metrics_observer.cc
deleted file mode 100644
index d84009acbd9..00000000000
--- a/chromium/weblayer/browser/ukm_page_load_metrics_observer.cc
+++ /dev/null
@@ -1,41 +0,0 @@
-// 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/browser/ukm_page_load_metrics_observer.h"
-
-#include "build/build_config.h"
-#include "components/prerender/browser/prerender_manager.h"
-#include "components/prerender/browser/prerender_util.h"
-#include "content/public/browser/navigation_handle.h"
-#include "content/public/browser/web_contents.h"
-#include "services/metrics/public/cpp/ukm_recorder.h"
-#include "weblayer/browser/no_state_prefetch/prerender_manager_factory.h"
-
-namespace weblayer {
-
-// static
-std::unique_ptr<page_load_metrics::PageLoadMetricsObserver>
-UkmPageLoadMetricsObserver::CreateIfNeeded() {
- if (!ukm::UkmRecorder::Get()) {
- return nullptr;
- }
- return std::make_unique<UkmPageLoadMetricsObserver>();
-}
-
-UkmPageLoadMetricsObserver::ObservePolicy UkmPageLoadMetricsObserver::OnCommit(
- content::NavigationHandle* navigation_handle,
- ukm::SourceId source_id) {
-#if defined(OS_ANDROID)
- prerender::PrerenderManager* const prerender_manager =
- PrerenderManagerFactory::GetForBrowserContext(
- navigation_handle->GetWebContents()->GetBrowserContext());
- if (!prerender_manager)
- return CONTINUE_OBSERVING;
- prerender::RecordNoStatePrefetchMetrics(navigation_handle, source_id,
- prerender_manager);
-#endif
- return CONTINUE_OBSERVING;
-}
-
-} // namespace weblayer
diff --git a/chromium/weblayer/browser/ukm_page_load_metrics_observer.h b/chromium/weblayer/browser/ukm_page_load_metrics_observer.h
deleted file mode 100644
index 30e17b39c87..00000000000
--- a/chromium/weblayer/browser/ukm_page_load_metrics_observer.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// 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_BROWSER_UKM_PAGE_LOAD_METRICS_OBSERVER_H_
-#define WEBLAYER_BROWSER_UKM_PAGE_LOAD_METRICS_OBSERVER_H_
-
-#include "components/page_load_metrics/browser/page_load_metrics_observer.h"
-
-namespace content {
-class NavigationHandle;
-}
-
-namespace weblayer {
-
-// If URL-Keyed-Metrics (UKM) is enabled in the system, this is used to
-// populate it with top-level page-load metrics.
-class UkmPageLoadMetricsObserver
- : public page_load_metrics::PageLoadMetricsObserver {
- public:
- // Returns a UkmPageLoadMetricsObserver, or nullptr if it is not needed.
- static std::unique_ptr<page_load_metrics::PageLoadMetricsObserver>
- CreateIfNeeded();
-
- UkmPageLoadMetricsObserver() = default;
- ~UkmPageLoadMetricsObserver() override = default;
-
- // page_load_metrics::PageLoadMetricsObserver implementation:
- ObservePolicy OnCommit(content::NavigationHandle* navigation_handle,
- ukm::SourceId source_id) override;
-};
-
-} // namespace weblayer
-
-#endif // WEBLAYER_BROWSER_UKM_PAGE_LOAD_METRICS_OBSERVER_H_
diff --git a/chromium/weblayer/browser/url_bar/page_info_browsertest.cc b/chromium/weblayer/browser/url_bar/page_info_browsertest.cc
index 6c5971995ab..33c81e4219f 100644
--- a/chromium/weblayer/browser/url_bar/page_info_browsertest.cc
+++ b/chromium/weblayer/browser/url_bar/page_info_browsertest.cc
@@ -65,8 +65,7 @@ IN_PROC_BROWSER_TEST_F(PageInfoBrowserTest, PermissionStatus) {
auto* content_settings_map = page_info_delegate->GetContentSettings();
ASSERT_TRUE(content_settings_map);
content_settings_map->SetContentSettingDefaultScope(
- url, url, ContentSettingsType::BACKGROUND_SYNC, std::string(),
- CONTENT_SETTING_BLOCK);
+ url, url, ContentSettingsType::BACKGROUND_SYNC, CONTENT_SETTING_BLOCK);
// Check that |page_info_delegate| returns expected ContentSettingsType.
EXPECT_EQ(page_info_delegate
diff --git a/chromium/weblayer/browser/url_bar/trusted_cdn_observer.cc b/chromium/weblayer/browser/url_bar/trusted_cdn_observer.cc
new file mode 100644
index 00000000000..2d05df50c55
--- /dev/null
+++ b/chromium/weblayer/browser/url_bar/trusted_cdn_observer.cc
@@ -0,0 +1,36 @@
+// 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/browser/url_bar/trusted_cdn_observer.h"
+
+#include "components/embedder_support/android/util/cdn_utils.h"
+#include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/web_contents.h"
+
+namespace weblayer {
+
+TrustedCDNObserver::TrustedCDNObserver(content::WebContents* web_contents)
+ : WebContentsObserver(web_contents) {}
+
+TrustedCDNObserver::~TrustedCDNObserver() = default;
+
+void TrustedCDNObserver::DidFinishNavigation(
+ content::NavigationHandle* navigation_handle) {
+ // Skip subframe, same-document, or non-committed navigations (downloads or
+ // 204/205 responses).
+ if (!navigation_handle->IsInMainFrame() ||
+ navigation_handle->IsSameDocument() ||
+ !navigation_handle->HasCommitted()) {
+ return;
+ }
+
+ publisher_url_ = embedder_support::GetPublisherURL(navigation_handle);
+
+ // Trigger url bar update.
+ web_contents()->DidChangeVisibleSecurityState();
+}
+
+WEB_CONTENTS_USER_DATA_KEY_IMPL(TrustedCDNObserver)
+
+} // namespace weblayer \ No newline at end of file
diff --git a/chromium/weblayer/browser/url_bar/trusted_cdn_observer.h b/chromium/weblayer/browser/url_bar/trusted_cdn_observer.h
new file mode 100644
index 00000000000..e756b88bb6d
--- /dev/null
+++ b/chromium/weblayer/browser/url_bar/trusted_cdn_observer.h
@@ -0,0 +1,39 @@
+// 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_BROWSER_URL_BAR_TRUSTED_CDN_OBSERVER_H_
+#define WEBLAYER_BROWSER_URL_BAR_TRUSTED_CDN_OBSERVER_H_
+
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/browser/web_contents_user_data.h"
+#include "url/gurl.h"
+
+namespace weblayer {
+
+// Monitors navigations to see if a publisher URL exists.
+class TrustedCDNObserver
+ : public content::WebContentsObserver,
+ public content::WebContentsUserData<TrustedCDNObserver> {
+ public:
+ ~TrustedCDNObserver() override;
+
+ const GURL& publisher_url() const { return publisher_url_; }
+
+ private:
+ friend class content::WebContentsUserData<TrustedCDNObserver>;
+
+ explicit TrustedCDNObserver(content::WebContents* web_contents);
+
+ // content::WebContentsObserver implementation:
+ void DidFinishNavigation(
+ content::NavigationHandle* navigation_handle) override;
+
+ GURL publisher_url_;
+
+ WEB_CONTENTS_USER_DATA_KEY_DECL();
+};
+
+} // namespace weblayer
+
+#endif // WEBLAYER_BROWSER_URL_BAR_TRUSTED_CDN_OBSERVER_H_ \ No newline at end of file
diff --git a/chromium/weblayer/browser/url_bar/url_bar_controller_impl.cc b/chromium/weblayer/browser/url_bar/url_bar_controller_impl.cc
index 4a43cee4a38..a6ad1251c6f 100644
--- a/chromium/weblayer/browser/url_bar/url_bar_controller_impl.cc
+++ b/chromium/weblayer/browser/url_bar/url_bar_controller_impl.cc
@@ -21,6 +21,7 @@
#if defined(OS_ANDROID)
#include "base/android/jni_string.h"
#include "weblayer/browser/java/jni/UrlBarControllerImpl_jni.h"
+#include "weblayer/browser/url_bar/trusted_cdn_observer.h"
#endif
namespace weblayer {
@@ -62,6 +63,21 @@ UrlBarControllerImpl::GetUrlForDisplay(JNIEnv* env) {
base::android::ConvertUTF16ToJavaString(env, GetUrlForDisplay()));
}
+base::android::ScopedJavaLocalRef<jstring>
+UrlBarControllerImpl::GetPublisherUrl(JNIEnv* env) {
+ GURL url;
+
+ auto* active_web_contents = GetActiveWebContents();
+ if (active_web_contents) {
+ auto* trusted_cdn_observer =
+ TrustedCDNObserver::FromWebContents(active_web_contents);
+ if (trusted_cdn_observer)
+ url = trusted_cdn_observer->publisher_url();
+ }
+ return base::android::ScopedJavaLocalRef<jstring>(
+ base::android::ConvertUTF8ToJavaString(env, url.spec()));
+}
+
jint UrlBarControllerImpl::GetConnectionSecurityLevel(JNIEnv* env) {
return GetConnectionSecurityLevel();
}
diff --git a/chromium/weblayer/browser/url_bar/url_bar_controller_impl.h b/chromium/weblayer/browser/url_bar/url_bar_controller_impl.h
index 3e564133d95..c973d0d1d79 100644
--- a/chromium/weblayer/browser/url_bar/url_bar_controller_impl.h
+++ b/chromium/weblayer/browser/url_bar/url_bar_controller_impl.h
@@ -33,6 +33,7 @@ class UrlBarControllerImpl : public UrlBarController,
#if defined(OS_ANDROID)
base::android::ScopedJavaLocalRef<jstring> GetUrlForDisplay(JNIEnv* env);
+ base::android::ScopedJavaLocalRef<jstring> GetPublisherUrl(JNIEnv* env);
jint GetConnectionSecurityLevel(JNIEnv* env);
jboolean ShouldShowDangerTriangleForWarningLevel(JNIEnv* env);
#endif
diff --git a/chromium/weblayer/browser/weblayer_browser_interface_binders.cc b/chromium/weblayer/browser/weblayer_browser_interface_binders.cc
index 5813a0cb3de..57431384626 100644
--- a/chromium/weblayer/browser/weblayer_browser_interface_binders.cc
+++ b/chromium/weblayer/browser/weblayer_browser_interface_binders.cc
@@ -6,14 +6,15 @@
#include "base/bind.h"
#include "build/build_config.h"
-#include "components/prerender/browser/prerender_contents.h"
-#include "components/prerender/browser/prerender_processor_impl.h"
-#include "components/prerender/common/prerender_canceler.mojom.h"
+#include "components/no_state_prefetch/browser/prerender_contents.h"
+#include "components/no_state_prefetch/browser/prerender_processor_impl.h"
+#include "components/no_state_prefetch/common/prerender_canceler.mojom.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_controller.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/installedapp/installed_app_provider.mojom.h"
#include "third_party/blink/public/mojom/installedapp/related_application.mojom.h"
#include "third_party/blink/public/mojom/prerender/prerender.mojom.h"
@@ -136,8 +137,11 @@ void PopulateWebLayerFrameBinders(
map->Add<translate::mojom::ContentTranslateDriver>(
base::BindRepeating(&BindContentTranslateDriver));
- map->Add<blink::mojom::PrerenderProcessor>(
- base::BindRepeating(&BindPrerenderProcessor));
+ // When Prerender2 is enabled, the content layer already added a binder.
+ if (!base::FeatureList::IsEnabled(blink::features::kPrerender2)) {
+ map->Add<blink::mojom::PrerenderProcessor>(
+ base::BindRepeating(&BindPrerenderProcessor));
+ }
map->Add<prerender::mojom::PrerenderCanceler>(
base::BindRepeating(&BindPrerenderCanceler));
diff --git a/chromium/weblayer/browser/weblayer_field_trials.h b/chromium/weblayer/browser/weblayer_field_trials.h
index a2fc67cfb89..0c682125154 100644
--- a/chromium/weblayer/browser/weblayer_field_trials.h
+++ b/chromium/weblayer/browser/weblayer_field_trials.h
@@ -21,6 +21,7 @@ class WebLayerFieldTrials : public variations::PlatformFieldTrials {
void SetupFieldTrials() override;
void SetupFeatureControllingFieldTrials(
bool has_seed,
+ const base::FieldTrial::EntropyProvider& low_entropy_provider,
base::FeatureList* feature_list) override {}
private:
diff --git a/chromium/weblayer/browser/webrtc/media_stream_manager.cc b/chromium/weblayer/browser/webrtc/media_stream_manager.cc
index 604f36ec3f6..a92c95516d5 100644
--- a/chromium/weblayer/browser/webrtc/media_stream_manager.cc
+++ b/chromium/weblayer/browser/webrtc/media_stream_manager.cc
@@ -56,13 +56,22 @@ class MediaStreamManager::StreamUi : public content::MediaStreamUI {
}
// content::MediaStreamUi:
- gfx::NativeViewId OnStarted(base::OnceClosure stop,
- SourceCallback source) override {
+ gfx::NativeViewId OnStarted(
+ base::OnceClosure stop,
+ SourceCallback source,
+ const std::string& label,
+ std::vector<content::DesktopMediaID> screen_capture_ids,
+ StateChangeCallback state_change) override {
stop_ = std::move(stop);
if (manager_)
manager_->RegisterStream(this);
return 0;
}
+ void OnDeviceStopped(const std::string& label,
+ const content::DesktopMediaID& media_id) override {}
+ void SetStopCallback(base::OnceClosure stop) override {
+ stop_ = std::move(stop);
+ }
bool streaming_audio() const { return streaming_audio_; }
diff --git a/chromium/weblayer/common/content_client_impl.cc b/chromium/weblayer/common/content_client_impl.cc
index fe83648f1dd..c75adc7e065 100644
--- a/chromium/weblayer/common/content_client_impl.cc
+++ b/chromium/weblayer/common/content_client_impl.cc
@@ -62,4 +62,13 @@ blink::OriginTrialPolicy* ContentClientImpl::GetOriginTrialPolicy() {
return origin_trial_policy_.get();
}
+void ContentClientImpl::AddAdditionalSchemes(Schemes* schemes) {
+#if defined(OS_ANDROID)
+ // TODO(sky): refactor. This comes from chrome/common/url_constants.cc's
+ // kAndroidAppScheme.
+ schemes->standard_schemes.push_back("android-app");
+ schemes->referrer_schemes.push_back("android-app");
+#endif
+}
+
} // namespace weblayer
diff --git a/chromium/weblayer/common/content_client_impl.h b/chromium/weblayer/common/content_client_impl.h
index f2533b4df55..37589970cf4 100644
--- a/chromium/weblayer/common/content_client_impl.h
+++ b/chromium/weblayer/common/content_client_impl.h
@@ -28,6 +28,7 @@ class ContentClientImpl : public content::ContentClient {
void SetGpuInfo(const gpu::GPUInfo& gpu_info) override;
gfx::Image& GetNativeImageNamed(int resource_id) override;
blink::OriginTrialPolicy* GetOriginTrialPolicy() override;
+ void AddAdditionalSchemes(Schemes* schemes) override;
private:
// Used to lock when |origin_trial_policy_| is initialized.
diff --git a/chromium/weblayer/common/features.cc b/chromium/weblayer/common/features.cc
index 162e5cec6d9..69ac12bee3b 100644
--- a/chromium/weblayer/common/features.cc
+++ b/chromium/weblayer/common/features.cc
@@ -9,11 +9,6 @@ namespace features {
// Weblayer features in alphabetical order.
-// Covers all media router features, i.e. Presentation API, Remote Playback API,
-// and Media Fling (automatic casting of html5 videos).
-const base::Feature kMediaRouter{"WebLayerMediaRouter",
- base::FEATURE_DISABLED_BY_DEFAULT};
-
// Safebrowsing support for weblayer.
const base::Feature kWebLayerSafeBrowsing{"WebLayerSafeBrowsing",
base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chromium/weblayer/common/features.h b/chromium/weblayer/common/features.h
index 295ca6d8e1f..cf083ad9cb5 100644
--- a/chromium/weblayer/common/features.h
+++ b/chromium/weblayer/common/features.h
@@ -12,8 +12,6 @@ namespace features {
// Weblayer features in alphabetical order.
-extern const base::Feature kMediaRouter;
-
extern const base::Feature kWebLayerSafeBrowsing;
} // namespace features
diff --git a/chromium/weblayer/public/common/switches.cc b/chromium/weblayer/public/common/switches.cc
index ad034f35a9e..4021c608a05 100644
--- a/chromium/weblayer/public/common/switches.cc
+++ b/chromium/weblayer/public/common/switches.cc
@@ -14,6 +14,9 @@ const char kDisableAutoReload[] = "disable-auto-reload";
const char kEnableAutoReload[] = "enable-auto-reload";
// Makes WebLayer Shell use the given path for its data directory.
+// NOTE: If changing this value, change the corresponding Java-side value in
+// WebLayerBrowserTestsActivity.java#getUserDataDirectoryCommandLineSwitch() to
+// match.
const char kWebLayerUserDataDir[] = "weblayer-user-data-dir";
} // namespace switches
diff --git a/chromium/weblayer/public/java/AndroidManifest.xml b/chromium/weblayer/public/java/AndroidManifest.xml
index fc088aac56f..20fc81b610a 100644
--- a/chromium/weblayer/public/java/AndroidManifest.xml
+++ b/chromium/weblayer/public/java/AndroidManifest.xml
@@ -85,6 +85,13 @@
</intent-filter>
</service>
+ <service android:name="org.chromium.weblayer.RemoteMediaService"
+ android:exported="false">
+ <intent-filter>
+ <action android:name="android.intent.action.MEDIA_BUTTON" />
+ </intent-filter>
+ </service>
+
<!-- Service for decoding images in a sandboxed process. -->
<service
android:name="org.chromium.weblayer.ImageDecoderService"
diff --git a/chromium/weblayer/public/java/BUILD.gn b/chromium/weblayer/public/java/BUILD.gn
index 451bac65d51..3252520f7e6 100644
--- a/chromium/weblayer/public/java/BUILD.gn
+++ b/chromium/weblayer/public/java/BUILD.gn
@@ -35,8 +35,11 @@ android_resources("client_resources") {
android_library("java") {
sources = [
+ "org/chromium/weblayer/ActionModeCallback.java",
+ "org/chromium/weblayer/ActionModeItemType.java",
"org/chromium/weblayer/BroadcastReceiver.java",
"org/chromium/weblayer/Browser.java",
+ "org/chromium/weblayer/BrowserControlsOffsetCallback.java",
"org/chromium/weblayer/BrowserFragment.java",
"org/chromium/weblayer/BrowserRestoreCallback.java",
"org/chromium/weblayer/BrowsingDataType.java",
@@ -67,6 +70,7 @@ android_library("java") {
"org/chromium/weblayer/LoadError.java",
"org/chromium/weblayer/MediaCaptureCallback.java",
"org/chromium/weblayer/MediaCaptureController.java",
+ "org/chromium/weblayer/MediaPlaybackBaseService.java",
"org/chromium/weblayer/MediaRouteDialogFragment.java",
"org/chromium/weblayer/MediaSessionService.java",
"org/chromium/weblayer/NavigateParams.java",
@@ -80,6 +84,7 @@ android_library("java") {
"org/chromium/weblayer/PrerenderController.java",
"org/chromium/weblayer/Profile.java",
"org/chromium/weblayer/RemoteFragment.java",
+ "org/chromium/weblayer/RemoteMediaService.java",
"org/chromium/weblayer/ScrollNotificationType.java",
"org/chromium/weblayer/ScrollOffsetCallback.java",
"org/chromium/weblayer/SettingType.java",
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/ActionModeCallback.java b/chromium/weblayer/public/java/org/chromium/weblayer/ActionModeCallback.java
new file mode 100644
index 00000000000..7014837e212
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/ActionModeCallback.java
@@ -0,0 +1,19 @@
+// 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;
+
+/**
+ * Used to override floating some action mode menu items.
+ *
+ * @since 88
+ */
+public abstract class ActionModeCallback {
+ /**
+ * Called when an overridden item type is clicked. The action mode is closed after this returns.
+ * @param selectedText the raw selected text. Client is responsible for trimming it to fit into
+ * some use cases as the text can be very large.
+ */
+ public void onActionItemClicked(@ActionModeItemType int item, String selectedText) {}
+}
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/ActionModeItemType.java b/chromium/weblayer/public/java/org/chromium/weblayer/ActionModeItemType.java
new file mode 100644
index 00000000000..b85fcd1ea03
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/ActionModeItemType.java
@@ -0,0 +1,17 @@
+// 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;
+
+@IntDef({ActionModeItemType.SHARE, ActionModeItemType.WEB_SEARCH})
+@Retention(RetentionPolicy.SOURCE)
+public @interface ActionModeItemType {
+ int SHARE = org.chromium.weblayer_private.interfaces.ActionModeItemType.SHARE;
+ int WEB_SEARCH = org.chromium.weblayer_private.interfaces.ActionModeItemType.WEB_SEARCH;
+}
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/Browser.java b/chromium/weblayer/public/java/org/chromium/weblayer/Browser.java
index f8a02de5b8b..4c791087abc 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/Browser.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/Browser.java
@@ -35,6 +35,7 @@ public class Browser {
private final ObserverList<TabListCallback> mTabListCallbacks;
private final UrlBarController mUrlBarController;
+ private final ObserverList<BrowserControlsOffsetCallback> mBrowserControlsOffsetCallbacks;
private final ObserverList<BrowserRestoreCallback> mBrowserRestoreCallbacks;
// Constructor for test mocking.
@@ -42,6 +43,7 @@ public class Browser {
mImpl = null;
mTabListCallbacks = null;
mUrlBarController = null;
+ mBrowserControlsOffsetCallbacks = null;
mBrowserRestoreCallbacks = null;
}
@@ -49,6 +51,7 @@ public class Browser {
mImpl = impl;
mFragment = fragment;
mTabListCallbacks = new ObserverList<TabListCallback>();
+ mBrowserControlsOffsetCallbacks = new ObserverList<BrowserControlsOffsetCallback>();
mBrowserRestoreCallbacks = new ObserverList<BrowserRestoreCallback>();
try {
@@ -65,6 +68,10 @@ public class Browser {
}
}
+ IBrowser getIBrowser() {
+ return mImpl;
+ }
+
/**
* Returns the Browser for the supplied Fragment; null if
* {@link fragment} was not created by WebLayer.
@@ -77,6 +84,14 @@ public class Browser {
: null;
}
+ /**
+ * Returns true if this Browser has been destroyed.
+ */
+ public boolean isDestroyed() {
+ ThreadCheck.ensureOnUiThread();
+ return mImpl == null;
+ }
+
// Called prior to notifying IBrowser of destroy().
void prepareForDestroy() {
mFragment = null;
@@ -331,6 +346,55 @@ public class Browser {
}
/**
+ * Registers {@link callback} to be notified when the offset of the top or bottom view changes.
+ *
+ * @param callback The BrowserControlsOffsetCallback to notify
+ *
+ * @since 88
+ */
+ public void registerBrowserControlsOffsetCallback(
+ @NonNull BrowserControlsOffsetCallback callback) {
+ ThreadCheck.ensureOnUiThread();
+ throwIfDestroyed();
+ if (WebLayer.getSupportedMajorVersionInternal() < 88) {
+ throw new UnsupportedOperationException();
+ }
+ if (mBrowserControlsOffsetCallbacks.isEmpty()) {
+ try {
+ mImpl.setBrowserControlsOffsetsEnabled(true);
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+ mBrowserControlsOffsetCallbacks.addObserver(callback);
+ }
+
+ /**
+ * Removes a BrowserControlsOffsetCallback that was added using {@link
+ * registerBrowserControlsOffsetCallback}.
+ *
+ * @param callback The BrowserControlsOffsetCallback to remove.
+ *
+ * @since 88
+ */
+ public void unregisterBrowserControlsOffsetCallback(
+ @NonNull BrowserControlsOffsetCallback callback) {
+ ThreadCheck.ensureOnUiThread();
+ throwIfDestroyed();
+ if (WebLayer.getSupportedMajorVersionInternal() < 88) {
+ throw new UnsupportedOperationException();
+ }
+ mBrowserControlsOffsetCallbacks.removeObserver(callback);
+ if (mBrowserControlsOffsetCallbacks.isEmpty()) {
+ try {
+ mImpl.setBrowserControlsOffsetsEnabled(false);
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+ }
+
+ /**
* Creates a new tab attached to this browser. This will call {@link TabListCallback#onTabAdded}
* with the new tab.
*
@@ -454,6 +518,17 @@ public class Browser {
}
@Override
+ public void onBrowserControlsOffsetsChanged(boolean isTop, int offset) {
+ for (BrowserControlsOffsetCallback callback : mBrowserControlsOffsetCallbacks) {
+ if (isTop) {
+ callback.onTopViewOffsetChanged(offset);
+ } else {
+ callback.onBottomViewOffsetChanged(offset);
+ }
+ }
+ }
+
+ @Override
public void onRestoreCompleted() {
for (BrowserRestoreCallback callback : mBrowserRestoreCallbacks) {
callback.onRestoreCompleted();
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/BrowserControlsOffsetCallback.java b/chromium/weblayer/public/java/org/chromium/weblayer/BrowserControlsOffsetCallback.java
new file mode 100644
index 00000000000..edf1d3d8b32
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/BrowserControlsOffsetCallback.java
@@ -0,0 +1,39 @@
+// 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;
+
+/**
+ * Callback notified when the vertical location of the top or bottom View changes.
+ *
+ * WebLayer maintains a snapshot (bitmap) of the browser controls. During a scroll, the snapshot is
+ * scrolled and not the actual View. A ramification of this is any updates to the View during a
+ * scroll are not reflected to the user. If the contents of the controls needs to change during a
+ * scroll, than an empty View should be set as the top/bottom control and the real View should be
+ * positioned based on the offsets supplied to the callback.
+ *
+ * @since 88
+ */
+public abstract class BrowserControlsOffsetCallback {
+ /**
+ * Called when the vertical location of the top view changes. The value varies from 0
+ * (completely shown) to -(height - minHeight), where height is the preferred height of the view
+ * and minHeight is the minimum height supplied to {@link Tab#setTopView}.
+ *
+ * If the top view is removed, this is called with a value of 0.
+ *
+ * @param offset The vertical offset.
+ */
+ public void onTopViewOffsetChanged(int offset) {}
+
+ /**
+ * Called when the vertical location of the bottom view changes. The value varies from 0
+ * (completely shown) to the preferred height of the bottom view.
+ *
+ * If the bottom view is removed, this is called with a value of 0.
+ *
+ * @param offset The vertical offset.
+ */
+ public void onBottomViewOffsetChanged(int offset) {}
+}
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/BrowserFragment.java b/chromium/weblayer/public/java/org/chromium/weblayer/BrowserFragment.java
index 4262fc9f70c..a269a1a1cfd 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/BrowserFragment.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/BrowserFragment.java
@@ -11,6 +11,7 @@ import android.os.RemoteException;
import androidx.annotation.NonNull;
import org.chromium.weblayer_private.interfaces.APICallException;
+import org.chromium.weblayer_private.interfaces.BrowserFragmentArgs;
import org.chromium.weblayer_private.interfaces.IBrowserFragment;
import org.chromium.weblayer_private.interfaces.IRemoteFragment;
@@ -67,12 +68,24 @@ public final class BrowserFragment extends RemoteFragment {
@Override
protected IRemoteFragment createRemoteFragment(Context appContext) {
+ Bundle args = getArguments();
+ if (args == null) {
+ throw new RuntimeException("BrowserFragment was created without arguments.");
+ }
try {
- Bundle args = getArguments();
- if (args == null) {
- throw new RuntimeException("BrowserFragment was created without arguments.");
- }
mWebLayer = WebLayer.loadSync(appContext);
+ } catch (Exception e) {
+ throw new RuntimeException("Failed to initialize WebLayer", e);
+ }
+ // Ideally this would be in WebLayer when the fragment is created, but at that time we don't
+ // want to trigger loading WebLayer.
+ if (args.getBoolean(BrowserFragmentArgs.IS_INCOGNITO, false)) {
+ String name = args.getString(BrowserFragmentArgs.PROFILE_NAME);
+ if (!"".equals(name) && WebLayer.getSupportedMajorVersionInternal() < 87) {
+ throw new UnsupportedOperationException("Named incognito profile requires 87");
+ }
+ }
+ try {
mImpl = mWebLayer.connectFragment(getRemoteFragmentClient(), args);
return mImpl.asRemoteFragment();
} catch (Exception e) {
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/ContextMenuParams.java b/chromium/weblayer/public/java/org/chromium/weblayer/ContextMenuParams.java
index 6c907d8e1b9..94a4277c7fc 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/ContextMenuParams.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/ContextMenuParams.java
@@ -9,6 +9,8 @@ import android.net.Uri;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import org.chromium.weblayer_private.interfaces.IContextMenuParams;
+
/**
* Parameters for constructing context menu.
*/
@@ -45,12 +47,46 @@ public class ContextMenuParams {
@Nullable
public final Uri srcUri;
- public ContextMenuParams(
+ /**
+ * Whether srcUri points to an image.
+ *
+ * @since 88
+ */
+ public final boolean isImage;
+
+ /**
+ * Whether srcUri points to a video.
+ *
+ * @since 88
+ */
+ public final boolean isVideo;
+
+ /**
+ * Whether this link or image/video can be downloaded. Only if this is true can
+ * {@link Tab.download} be called.
+ *
+ * @since 88
+ */
+ public final boolean canDownload;
+
+ final IContextMenuParams mContextMenuParams;
+
+ protected ContextMenuParams(
Uri pageUri, Uri linkUri, String linkText, String titleOrAltText, Uri srcUri) {
+ this(pageUri, linkUri, linkText, titleOrAltText, srcUri, false, false, false, null);
+ }
+
+ protected ContextMenuParams(Uri pageUri, Uri linkUri, String linkText, String titleOrAltText,
+ Uri srcUri, boolean isImage, boolean isVideo, boolean canDownload,
+ IContextMenuParams contextMenuParams) {
this.pageUri = pageUri;
this.linkUri = linkUri;
this.linkText = linkText;
this.titleOrAltText = titleOrAltText;
this.srcUri = srcUri;
+ this.isImage = isImage;
+ this.isVideo = isVideo;
+ this.canDownload = canDownload;
+ this.mContextMenuParams = contextMenuParams;
}
}
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/CrashReporterCallback.java b/chromium/weblayer/public/java/org/chromium/weblayer/CrashReporterCallback.java
index 0e73360a5a0..a267f98a827 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/CrashReporterCallback.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/CrashReporterCallback.java
@@ -39,5 +39,5 @@ public abstract class CrashReporterCallback {
* @param localId the local identifier of the crash that failed to upload.
* @param failureReason a free text string giving the failure reason.
*/
- public void onCrashUploadFailed(@NonNull String localId, @NonNull String faulreReason) {}
+ public void onCrashUploadFailed(@NonNull String localId, @NonNull String failureReason) {}
}
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/LoadError.java b/chromium/weblayer/public/java/org/chromium/weblayer/LoadError.java
index 77b45e40851..e411f6905ec 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/LoadError.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/LoadError.java
@@ -41,7 +41,15 @@ public @interface LoadError {
int CONNECTIVITY_ERROR = org.chromium.weblayer_private.interfaces.LoadError.CONNECTIVITY_ERROR;
/**
- * An error not listed above occurred.
+ * An error not listed above or below occurred.
*/
int OTHER_ERROR = org.chromium.weblayer_private.interfaces.LoadError.OTHER_ERROR;
+
+ /**
+ * Safe browsing error.
+ *
+ * @since 88
+ */
+ int SAFE_BROWSING_ERROR =
+ org.chromium.weblayer_private.interfaces.LoadError.SAFE_BROWSING_ERROR;
}
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/MediaPlaybackBaseService.java b/chromium/weblayer/public/java/org/chromium/weblayer/MediaPlaybackBaseService.java
new file mode 100644
index 00000000000..31847353415
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/MediaPlaybackBaseService.java
@@ -0,0 +1,101 @@
+// 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.Intent;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+/**
+ * Base class that provides common functionality for media playback services that are associated
+ * with an active media session and Android notification.
+ */
+abstract class MediaPlaybackBaseService extends Service {
+ // True when the start command has been forwarded to the impl.
+ boolean mStarted;
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ if (!WebLayer.hasWebLayerInitializationStarted()) {
+ stopSelf();
+ return;
+ }
+
+ init();
+ }
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ WebLayer webLayer = getWebLayer();
+ if (webLayer == null) {
+ stopSelf();
+ } else {
+ try {
+ forwardStartCommandToImpl(webLayer, intent);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ mStarted = true;
+ }
+
+ return START_NOT_STICKY;
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+
+ if (!mStarted) return;
+
+ try {
+ forwardDestroyToImpl();
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /** Called to do initialization when the service is created. */
+ void init() {}
+
+ /**
+ * Called to forward {@link onStartCommand()} to the WebLayer implementation.
+ *
+ * @param webLayer the implementation.
+ * @param intent the intent that started the service.
+ */
+ abstract void forwardStartCommandToImpl(@NonNull WebLayer webLayer, Intent intent)
+ throws RemoteException;
+
+ /**
+ * Called to forward {@link onDestroy()} to the WebLayer implementation.
+ *
+ * This will only be called if {@link forwardStartCommandToImpl()} was previously called, and
+ * there should always be a loaded {@link WebLayer} available via {@link getWebLayer()}.
+ */
+ abstract void forwardDestroyToImpl() throws RemoteException;
+
+ /** Returns the loaded {@link WebLayer}, or null if none is loaded. */
+ @Nullable
+ WebLayer getWebLayer() {
+ WebLayer webLayer;
+ try {
+ webLayer = WebLayer.getLoadedWebLayer(getApplication());
+ } catch (UnsupportedVersionException e) {
+ throw new RuntimeException(e);
+ }
+ return webLayer;
+ }
+}
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/MediaRouteDialogFragment.java b/chromium/weblayer/public/java/org/chromium/weblayer/MediaRouteDialogFragment.java
index 5780c7d2cbd..fb75ae634ec 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/MediaRouteDialogFragment.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/MediaRouteDialogFragment.java
@@ -16,7 +16,7 @@ import org.chromium.weblayer_private.interfaces.IRemoteFragment;
*
* @since 87
*/
-class MediaRouteDialogFragment extends RemoteFragment {
+public class MediaRouteDialogFragment extends RemoteFragment {
private static final String FRAGMENT_TAG = "WebLayerMediaRouteDialogFragment";
static IRemoteFragment create(BrowserFragment browserFragment) {
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/MediaSessionService.java b/chromium/weblayer/public/java/org/chromium/weblayer/MediaSessionService.java
index e3cf06e3602..e1a60032a37 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/MediaSessionService.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/MediaSessionService.java
@@ -9,9 +9,10 @@ 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 androidx.annotation.NonNull;
+
import org.chromium.weblayer_private.interfaces.ObjectWrapper;
/**
@@ -21,24 +22,20 @@ import org.chromium.weblayer_private.interfaces.ObjectWrapper;
* foreground when the MediaSession is active.
* @since 85
*/
-public class MediaSessionService extends Service {
+public class MediaSessionService extends MediaPlaybackBaseService {
// A helper to automatically pause the media session when a user removes headphones.
private BroadcastReceiver mAudioBecomingNoisyReceiver;
@Override
- public IBinder onBind(Intent intent) {
- return null;
+ public void onDestroy() {
+ super.onDestroy();
+ if (mAudioBecomingNoisyReceiver != null) {
+ unregisterReceiver(mAudioBecomingNoisyReceiver);
+ }
}
@Override
- public void onCreate() {
- super.onCreate();
-
- if (!WebLayer.hasWebLayerInitializationStarted()) {
- stopSelf();
- return;
- }
-
+ void init() {
mAudioBecomingNoisyReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -57,43 +54,13 @@ public class MediaSessionService extends Service {
}
@Override
- public void onDestroy() {
- super.onDestroy();
-
- if (mAudioBecomingNoisyReceiver == null) return;
-
- try {
- getWebLayer().getImpl().onMediaSessionServiceDestroyed();
- } catch (RemoteException e) {
- throw new RuntimeException(e);
- }
-
- unregisterReceiver(mAudioBecomingNoisyReceiver);
+ void forwardStartCommandToImpl(@NonNull WebLayer webLayer, Intent intent)
+ throws RemoteException {
+ webLayer.getImpl().onMediaSessionServiceStarted(ObjectWrapper.wrap(this), intent);
}
@Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- try {
- WebLayer webLayer = getWebLayer();
- if (webLayer == null) {
- stopSelf();
- } else {
- webLayer.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);
- }
- return webLayer;
+ void forwardDestroyToImpl() throws RemoteException {
+ getWebLayer().getImpl().onMediaSessionServiceDestroyed();
}
}
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/NavigateParams.java b/chromium/weblayer/public/java/org/chromium/weblayer/NavigateParams.java
index 74be97ceb27..6fc29933dd1 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/NavigateParams.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/NavigateParams.java
@@ -73,9 +73,10 @@ public class NavigateParams {
/**
* Disables auto-reload for this navigation if the network is down and comes back later.
- * Auto-reload is enabled by default.
- *
- * @since 86
+ * Auto-reload is enabled by default. This is deprecated as of 88, instead use
+ * {@link Navigation#disableNetworkErrorAutoReload} which works for both embedder-initiated
+ * navigations and also user-initiated navigations (such as back or forward). Auto-reload
+ * is disabled if either method is called.
*/
@NonNull
public Builder disableNetworkErrorAutoReload() {
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/Navigation.java b/chromium/weblayer/public/java/org/chromium/weblayer/Navigation.java
index ce062564dbb..b020b43b047 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/Navigation.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/Navigation.java
@@ -170,6 +170,10 @@ public class Navigation extends IClientNavigation.Stub {
* 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}.
*
+ * Note that any headers that are set here won't be sent again if the frame html is fetched
+ * again due to a user reloading the page, navigating back and forth etc... when this fetch
+ * couldn't be cached (either in the disk cache or in the back-forward cache).
+ *
* @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'.
*
@@ -188,15 +192,42 @@ public class Navigation extends IClientNavigation.Stub {
}
/**
+ * Disables auto-reload for this navigation if the network is down and comes back later.
+ * Auto-reload is enabled by default. This method may only be called from
+ * {@link NavigationCallback.onNavigationStarted}.
+ *
+ * @throws IllegalStateException If not called during start.
+ *
+ * @since 88
+ */
+ public void disableNetworkErrorAutoReload() {
+ ThreadCheck.ensureOnUiThread();
+ if (WebLayer.shouldPerformVersionChecks()
+ && WebLayer.getSupportedMajorVersionInternal() < 88) {
+ throw new UnsupportedOperationException();
+ }
+ try {
+ mNavigationImpl.disableNetworkErrorAutoReload();
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
+ /**
* Sets the user-agent string that applies to the current navigation. This user-agent is not
* sticky, it applies to this navigation only (and any redirects or resources that are loaded).
* This method may only be called from {@link NavigationCallback.onNavigationStarted}.
*
+ * Note that this user agent won't be sent again if the frame html is fetched again due to a
+ * user reloading the page, navigating back and forth etc... when this fetch couldn't be cached
+ * (either in the disk cache or in the back-forward cache).
+ *
* @param value The user-agent string. The value must not contain '\0', '\n' or '\r'. An empty
* string results in the default user-agent string.
*
* @throws IllegalArgumentException If supplied an invalid value.
- * @throws IllegalStateException If not called during start.
+ * @throws IllegalStateException If not called during start or if {@link
+ * Tab.setDesktopUserAgent} was called with a value of true.
*
* @since 84
*/
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/NavigationCallback.java b/chromium/weblayer/public/java/org/chromium/weblayer/NavigationCallback.java
index 3b85def6ef8..1276343663b 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/NavigationCallback.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/NavigationCallback.java
@@ -116,6 +116,32 @@ public abstract class NavigationCallback {
public void onFirstContentfulPaint() {}
/**
+ * Similar to onFirstContentfulPaint but contains timing information from the renderer process
+ * to better align with the Navigation Timing API.
+ *
+ * @param navigationStartMs the absolute navigation start time in milliseconds since boot,
+ * not counting time spent in deep sleep. This comes from SystemClock.uptimeMillis().
+ * @param firstContentfulPaintDurationMs the number of milliseconds to first contentful paint
+ * from navigation start.
+ * @since 88
+ */
+ public void onFirstContentfulPaint(
+ long navigationStartMs, long firstContentfulPaintDurationMs) {}
+
+ /**
+ * This is fired when the largest contentful paint metric is available.
+ *
+ * @param navigationStartMs the absolute navigation start time in milliseconds since boot,
+ * not counting time spent in deep sleep. This comes from SystemClock.uptimeMillis().
+ * @param largestContentfulPaintDurationMs the number of milliseconds to largest contentful
+ * paint
+ * from navigation start.
+ * @since 88
+ */
+ public void onLargestContentfulPaint(
+ long navigationStartMs, long largestContentfulPaintDurationMs) {}
+
+ /**
* 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.
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/NavigationController.java b/chromium/weblayer/public/java/org/chromium/weblayer/NavigationController.java
index b007e6e214b..0e815d1a282 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/NavigationController.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/NavigationController.java
@@ -379,6 +379,25 @@ public class NavigationController {
}
@Override
+ public void onFirstContentfulPaint2(
+ long navigationStartMs, long firstContentfulPaintDurationMs) {
+ StrictModeWorkaround.apply();
+ for (NavigationCallback callback : mCallbacks) {
+ callback.onFirstContentfulPaint(navigationStartMs, firstContentfulPaintDurationMs);
+ }
+ }
+
+ @Override
+ public void onLargestContentfulPaint(
+ long navigationStartMs, long largestContentfulPaintDurationMs) {
+ StrictModeWorkaround.apply();
+ for (NavigationCallback callback : mCallbacks) {
+ callback.onLargestContentfulPaint(
+ navigationStartMs, largestContentfulPaintDurationMs);
+ }
+ }
+
+ @Override
public void onOldPageNoLongerRendered(String uri) {
StrictModeWorkaround.apply();
for (NavigationCallback callback : mCallbacks) {
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/Profile.java b/chromium/weblayer/public/java/org/chromium/weblayer/Profile.java
index 0b604863abe..eb362b3ab53 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/Profile.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/Profile.java
@@ -124,7 +124,7 @@ public class Profile {
}
/**
- * Returns the name of the profile. While added in 88, this can be used with any version.
+ * Returns the name of the profile. While added in 87, this can be used with any version.
*
* @return The name of the profile.
*
@@ -136,7 +136,7 @@ public class Profile {
}
/**
- * Returns true if the profile is incognito. While added in 88, this can be used with any
+ * Returns true if the profile is incognito. While added in 87, this can be used with any
* version.
*
* @return True if the profile is incognito.
@@ -308,7 +308,7 @@ public class Profile {
/**
* Gets the prerender controller for this profile.
*
- * @since 88
+ * @since 87
*/
@NonNull
public PrerenderController getPrerenderController() {
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/RemoteMediaService.java b/chromium/weblayer/public/java/org/chromium/weblayer/RemoteMediaService.java
new file mode 100644
index 00000000000..6add1485e3c
--- /dev/null
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/RemoteMediaService.java
@@ -0,0 +1,51 @@
+// 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.content.Intent;
+import android.os.RemoteException;
+
+import androidx.annotation.NonNull;
+
+import org.chromium.weblayer_private.interfaces.ObjectWrapper;
+import org.chromium.weblayer_private.interfaces.RemoteMediaServiceConstants;
+
+/**
+ * A foreground {@link Service} for Presentation API and Remote Playback API.
+ *
+ * Like {@link MediaSessionService}, this class is associated with a notification for an ongoing
+ * media session. The difference is that the media for this service is played back on a remote
+ * device, i.e. casting. This class can be considered an implementation detail of WebLayer.
+ *
+ * In order to set the Cast application (optional but recommended), the client should add the
+ * following to its manifest:
+ *
+ * <meta-data
+ * android:name="org.chromium.content.browser.REMOTE_PLAYBACK_APP_ID"
+ * android:value="$APP_ID"/>
+ *
+ * Where $APP_ID is the value assigned to your app by the Google Cast SDK Developer Console. If
+ * the cast application ID is not set, the app will appear as "Default Media Receiver" in the
+ * notification, device selection dialog, etc.
+ *
+ * @since 88
+ */
+public class RemoteMediaService extends MediaPlaybackBaseService {
+ private int mId;
+
+ @Override
+ void forwardStartCommandToImpl(@NonNull WebLayer webLayer, Intent intent)
+ throws RemoteException {
+ mId = intent.getIntExtra(RemoteMediaServiceConstants.NOTIFICATION_ID_KEY, 0);
+ if (mId == 0) throw new RuntimeException("Invalid RemoteMediaService notification id");
+
+ webLayer.getImpl().onRemoteMediaServiceStarted(ObjectWrapper.wrap(this), intent);
+ }
+
+ @Override
+ void forwardDestroyToImpl() throws RemoteException {
+ getWebLayer().getImpl().onRemoteMediaServiceDestroyed(mId);
+ }
+}
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/ScrollOffsetCallback.java b/chromium/weblayer/public/java/org/chromium/weblayer/ScrollOffsetCallback.java
index e0e5d724586..f661b0f72b3 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/ScrollOffsetCallback.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/ScrollOffsetCallback.java
@@ -19,7 +19,10 @@ package org.chromium.weblayer;
*/
public abstract class ScrollOffsetCallback {
/**
- * Called when the scroll offset of the content of a Tab changes.
+ * Called when the vertical scroll location of the content of a Tab changes.
+ *
+ * @param scrollLocation The new vertical location. More specifically, the 'scrollTop' html
+ * property.
*/
- public abstract void onVerticalScrollOffsetChanged(int scrollOffset);
+ public abstract void onVerticalScrollOffsetChanged(int scrollLocation);
}
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/Tab.java b/chromium/weblayer/public/java/org/chromium/weblayer/Tab.java
index 32495e01941..9c652b61aaf 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/Tab.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/Tab.java
@@ -18,6 +18,7 @@ import org.json.JSONObject;
import org.chromium.weblayer_private.interfaces.APICallException;
import org.chromium.weblayer_private.interfaces.IClientNavigation;
+import org.chromium.weblayer_private.interfaces.IContextMenuParams;
import org.chromium.weblayer_private.interfaces.IErrorPageCallbackClient;
import org.chromium.weblayer_private.interfaces.IFullscreenCallbackClient;
import org.chromium.weblayer_private.interfaces.IGoogleAccountsCallbackClient;
@@ -56,6 +57,7 @@ public class Tab {
private FullscreenCallbackClientImpl mFullscreenCallbackClient;
private NewTabCallback mNewTabCallback;
private final ObserverList<ScrollOffsetCallback> mScrollOffsetCallbacks;
+ private @Nullable ActionModeCallback mActionModeCallback;
// Id from the remote side.
private final int mId;
@@ -128,6 +130,35 @@ public class Tab {
mBrowser = browser;
}
+ /**
+ * Returns true if this Tab has been destroyed.
+ */
+ public boolean isDestroyed() {
+ ThreadCheck.ensureOnUiThread();
+ return mImpl == null;
+ }
+
+ /**
+ * Returns whether the tab will automatically reload after its renderer process is lost.
+ *
+ * This returns true if the tab is known not to be visible, specifically if the tab is not
+ * active in its browser or its Fragment is not started. When a tab in this state loses its
+ * renderer process to a crash (or due to system memory reclamation), it will automatically
+ * reload next the time it becomes possibly visible.
+ */
+ public boolean willAutomaticallyReloadAfterCrash() {
+ ThreadCheck.ensureOnUiThread();
+ throwIfDestroyed();
+ if (WebLayer.getSupportedMajorVersionInternal() < 88) {
+ throw new UnsupportedOperationException();
+ }
+ try {
+ return mImpl.willAutomaticallyReloadAfterCrash();
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
@NonNull
public Browser getBrowser() {
ThreadCheck.ensureOnUiThread();
@@ -732,10 +763,98 @@ public class Tab {
}
}
+ /**
+ * Allow controlling and overriding custom items in the floating seleciton menu.
+ * Note floating action mode is available on M and up.
+ * @param actionModeItemTypes a bit field of values in ActionModeItemType.
+ * @param callback can be null if actionModeItemTypes is 0.
+ *
+ * @since 88
+ */
+ public void setFloatingActionModeOverride(
+ int actionModeItemTypes, @Nullable ActionModeCallback callback) {
+ ThreadCheck.ensureOnUiThread();
+ throwIfDestroyed();
+ if (WebLayer.getSupportedMajorVersionInternal() < 88) {
+ throw new UnsupportedOperationException();
+ }
+ mActionModeCallback = callback;
+ try {
+ mImpl.setFloatingActionModeOverride(actionModeItemTypes);
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
+ /**
+ * Turns on desktop user agent if enable is true, otherwise reverts back to mobile user agent.
+ * The selected user agent will be used for future navigations until this method is called
+ * again. Each navigation saves the user agent mode it was navigated with and will reuse that on
+ * back/forward navigations. The tab will be reloaded with the new user agent.
+ * @param enable if true requests desktop site, otherwise mobile site.
+ *
+ * @since 88
+ */
+ public void setDesktopUserAgentEnabled(boolean enable) {
+ if (WebLayer.getSupportedMajorVersionInternal() < 88) {
+ throw new UnsupportedOperationException();
+ }
+ try {
+ mImpl.setDesktopUserAgentEnabled(enable);
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
+ /**
+ * Returns true if the currently loaded page used a desktop user agent.
+ *
+ * @since 88
+ */
+ public boolean isDesktopUserAgentEnabled() {
+ if (WebLayer.getSupportedMajorVersionInternal() < 88) {
+ throw new UnsupportedOperationException();
+ }
+ try {
+ return mImpl.isDesktopUserAgentEnabled();
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
+ /**
+ * Downloads the item linked to from the context menu. This could be an image/video or link.
+ * This will request the WRITE_EXTERNAL_STORAGE permission if it's not granted to the app.
+ *
+ * @throws IllegalArgumentException if {@link ContextMenuParams.canDownload} is false or if
+ * the ContextMenuParams object parameter wasn't constructed by WebLayer.
+ *
+ * @since 88
+ */
+ public void download(ContextMenuParams contextMenuParams) {
+ if (WebLayer.getSupportedMajorVersionInternal() < 88) {
+ throw new UnsupportedOperationException();
+ }
+ if (!contextMenuParams.canDownload) {
+ throw new IllegalArgumentException("ContextMenuParams not downloadable.");
+ }
+ if (contextMenuParams.mContextMenuParams == null) {
+ throw new IllegalArgumentException("ContextMenuParams not constructed by WebLayer.");
+ }
+
+ try {
+ mImpl.download(contextMenuParams.mContextMenuParams);
+ } catch (RemoteException e) {
+ throw new APICallException(e);
+ }
+ }
+
// Called by Browser when removed.
void onRemovedFromBrowser() {
if (mDestroyOnRemove) {
- unregisterTab(this);
+ // If this is destroyed as part of destroying the browser, then the tab has already been
+ // unregistered.
+ if (getTabById(mId) == this) unregisterTab(this);
mDestroyOnRemove = false;
mImpl = null;
}
@@ -801,9 +920,9 @@ public class Tab {
@Override
public void onTabDestroyed() {
- // Prior to 87 this was called *before* onTabRemoved(). Post 87 this is called after
- // onTabRemoved(). onTabRemoved() needs the Tab to be registered, so unregisterTab()
- // should only be called in >= 87 (in < 87 it is called from
+ // Prior to 87 this was potentially called *before* onTabRemoved(). Post 87 this is
+ // called after onTabRemoved(). onTabRemoved() needs the Tab to be registered, so
+ // unregisterTab() should only be called in >= 87 (in < 87 it is called from
// Browser.prepareForDestroy()).
if (WebLayer.getSupportedMajorVersionInternal() >= 87) {
unregisterTab(Tab.this);
@@ -811,7 +930,12 @@ public class Tab {
// into the implementation via this Tab.
mImpl = null;
} else {
+ // This Tab should not have been destroyed yet.
+ assert mImpl != null;
mDestroyOnRemove = true;
+ // If the tab isn't registered, it means the Browser fragment was destroyed, in
+ // which case there is no call to onTabRemoved().
+ if (getTabById(mId) == null) onRemovedFromBrowser();
}
}
@@ -826,6 +950,15 @@ public class Tab {
@Override
public void showContextMenu(IObjectWrapper pageUrl, IObjectWrapper linkUrl,
IObjectWrapper linkText, IObjectWrapper titleOrAltText, IObjectWrapper srcUrl) {
+ showContextMenu2(
+ pageUrl, linkUrl, linkText, titleOrAltText, srcUrl, false, false, false, null);
+ }
+
+ @Override
+ public void showContextMenu2(IObjectWrapper pageUrl, IObjectWrapper linkUrl,
+ IObjectWrapper linkText, IObjectWrapper titleOrAltText, IObjectWrapper srcUrl,
+ boolean isImage, boolean isVideo, boolean canDownload,
+ IContextMenuParams contextMenuParams) {
StrictModeWorkaround.apply();
String pageUrlString = ObjectWrapper.unwrap(pageUrl, String.class);
String linkUrlString = ObjectWrapper.unwrap(linkUrl, String.class);
@@ -834,7 +967,8 @@ public class Tab {
linkUrlString != null ? Uri.parse(linkUrlString) : null,
ObjectWrapper.unwrap(linkText, String.class),
ObjectWrapper.unwrap(titleOrAltText, String.class),
- srcUrlString != null ? Uri.parse(srcUrlString) : null);
+ srcUrlString != null ? Uri.parse(srcUrlString) : null, isImage, isVideo,
+ canDownload, contextMenuParams);
for (TabCallback callback : mCallbacks) {
callback.showContextMenu(params);
}
@@ -889,6 +1023,16 @@ public class Tab {
callback.onVerticalScrollOffsetChanged(value);
}
}
+
+ @Override
+ public void onActionItemClicked(
+ int actionModeItemType, IObjectWrapper selectedStringWrapper) {
+ StrictModeWorkaround.apply();
+ String selectedString = ObjectWrapper.unwrap(selectedStringWrapper, String.class);
+ if (mActionModeCallback != null) {
+ mActionModeCallback.onActionItemClicked(actionModeItemType, selectedString);
+ }
+ }
}
private static final class ErrorPageCallbackClientImpl extends IErrorPageCallbackClient.Stub {
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/UrlBarOptions.java b/chromium/weblayer/public/java/org/chromium/weblayer/UrlBarOptions.java
index ba206443ce7..1db00d7667a 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/UrlBarOptions.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/UrlBarOptions.java
@@ -73,6 +73,15 @@ public final class UrlBarOptions {
}
/**
+ * Specifies whether the publisher URL is shown.
+ */
+ @NonNull
+ public Builder showPublisherUrl() {
+ mOptions.putBoolean(UrlBarOptionsKeys.SHOW_PUBLISHER_URL, true);
+ return this;
+ }
+
+ /**
* Sets the color of the URL bar text.
*
* @param textColor The color for the Url bar text.
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/WebLayer.java b/chromium/weblayer/public/java/org/chromium/weblayer/WebLayer.java
index cc60cbe2163..e15189d19eb 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/WebLayer.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/WebLayer.java
@@ -14,6 +14,7 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.StrictMode;
+import android.os.SystemClock;
import android.util.AndroidRuntimeException;
import android.util.Log;
import android.webkit.ValueCallback;
@@ -71,6 +72,11 @@ public class WebLayer {
@NonNull
private final IWebLayer mImpl;
+ // Times used for logging UMA histograms.
+ private static long sClassLoaderCreationTime;
+ private static long sContextCreationTime;
+ private static long sWebLayerLoaderCreationTime;
+
/** The result of calling {@link #initializeWebViewCompatibilityMode}. */
public enum WebViewCompatibilityResult {
/** Compatibility mode has been successfully set up. */
@@ -274,13 +280,16 @@ public class WebLayer {
mContext = mContext.createAttributionContext(context.getAttributionTag());
}
try {
- Class factoryClass = getOrCreateRemoteClassLoader(mContext).loadClass(
- "org.chromium.weblayer_private.WebLayerFactoryImpl");
+ ClassLoader classLoader = getOrCreateRemoteClassLoader(mContext);
+ long start = SystemClock.elapsedRealtime();
+ Class factoryClass =
+ classLoader.loadClass("org.chromium.weblayer_private.WebLayerFactoryImpl");
mFactory = IWebLayerFactory.Stub.asInterface(
(IBinder) factoryClass
.getMethod("create", String.class, int.class, int.class)
.invoke(null, WebLayerClientVersionConstants.PRODUCT_VERSION,
WebLayerClientVersionConstants.PRODUCT_MAJOR_VERSION, -1));
+ sWebLayerLoaderCreationTime = SystemClock.elapsedRealtime() - start;
available = mFactory.isClientSupported();
majorVersion = mFactory.getImplementationMajorVersion();
version = mFactory.getImplementationVersion();
@@ -535,7 +544,8 @@ public class WebLayer {
* state.
*
* @throws UnsupportedOperationException If {@link params} is incognito and name is not empty
- * and <= 87.
+ * and <= 87. In order for this function not to trigger loading of WebLayer the
+ * exception is thrown later on.
*
* @since 87
*/
@@ -548,12 +558,8 @@ public class WebLayer {
private static Fragment createBrowserFragmentImpl(
@NonNull String profileName, @Nullable String persistenceId, boolean isIncognito) {
ThreadCheck.ensureOnUiThread();
- if (WebLayer.getSupportedMajorVersionInternal() < 87 && isIncognito
- && !"".equals(profileName)) {
- // Incognito profiles are only allowed to have non-empty names in >= 87.
- throw new UnsupportedOperationException();
- }
-
+ // Support for named incognito profiles was added in 87. Checking is done in
+ // BrowserFragment, as this code should not trigger loading WebLayer.
Bundle args = new Bundle();
args.putString(BrowserFragmentArgs.PROFILE_NAME, profileName);
if (persistenceId != null) {
@@ -651,6 +657,7 @@ public class WebLayer {
return sRemoteClassLoader;
}
+ long start = SystemClock.elapsedRealtime();
// Child processes do not need WebView compatibility since there is no chance
// WebView will run in the same process.
if (sDisableWebViewCompatibilityMode) {
@@ -670,6 +677,7 @@ public class WebLayer {
} else {
sRemoteClassLoader = WebViewCompatibilityHelper.initialize(appContext);
}
+ sClassLoaderCreationTime = SystemClock.elapsedRealtime() - start;
return sRemoteClassLoader;
}
@@ -681,6 +689,7 @@ public class WebLayer {
if (sRemoteContext != null) {
return sRemoteContext;
}
+ long start = SystemClock.elapsedRealtime();
Class<?> webViewFactoryClass = Class.forName("android.webkit.WebViewFactory");
String implPackageName = getImplPackageName(appContext);
sAppContext = appContext;
@@ -696,6 +705,7 @@ public class WebLayer {
(String) webViewFactoryClass.getMethod("getWebViewPackageName").invoke(null);
sRemoteContext = createRemoteContextFromPackageName(appContext, implPackageName);
}
+ sContextCreationTime = SystemClock.elapsedRealtime() - start;
return sRemoteContext;
}
@@ -774,6 +784,41 @@ public class WebLayer {
// The id is part of the public library to avoid conflicts.
return R.id.weblayer_media_session_notification;
}
+
+ @Override
+ public long getClassLoaderCreationTime() {
+ return sClassLoaderCreationTime;
+ }
+
+ @Override
+ public long getContextCreationTime() {
+ return sContextCreationTime;
+ }
+
+ @Override
+ public long getWebLayerLoaderCreationTime() {
+ return sWebLayerLoaderCreationTime;
+ }
+
+ @Override
+ public Intent createRemoteMediaServiceIntent() {
+ StrictModeWorkaround.apply();
+ return new Intent(WebLayer.getAppContext(), RemoteMediaService.class);
+ }
+
+ @Override
+ public int getPresentationApiNotificationId() {
+ StrictModeWorkaround.apply();
+ // The id is part of the public library to avoid conflicts.
+ return R.id.weblayer_presentation_api_notification;
+ }
+
+ @Override
+ public int getRemotePlaybackApiNotificationId() {
+ StrictModeWorkaround.apply();
+ // The id is part of the public library to avoid conflicts.
+ return R.id.weblayer_remote_playback_api_notification;
+ }
}
@VerifiesOnO
diff --git a/chromium/weblayer/public/java/org/chromium/weblayer/WebViewCompatibilityHelper.java b/chromium/weblayer/public/java/org/chromium/weblayer/WebViewCompatibilityHelper.java
index c334de6d64c..fe42b2b7919 100644
--- a/chromium/weblayer/public/java/org/chromium/weblayer/WebViewCompatibilityHelper.java
+++ b/chromium/weblayer/public/java/org/chromium/weblayer/WebViewCompatibilityHelper.java
@@ -46,8 +46,11 @@ final class WebViewCompatibilityHelper {
// this to a background thread.
StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
try {
+ // Use the system class loader's parent here, since it is much more efficient. This
+ // matches what Android does when constructing class loaders, see
+ // android.app.ApplicationLoaders.
return new PathClassLoader(
- dexPath, librarySearchPath, ClassLoader.getSystemClassLoader()) {
+ dexPath, librarySearchPath, ClassLoader.getSystemClassLoader().getParent()) {
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
// TODO(crbug.com/1112001): Investigate why loading classes causes strict mode
diff --git a/chromium/weblayer/public/java/res/values/ids.xml b/chromium/weblayer/public/java/res/values/ids.xml
index 300c7e62a50..ed73b87a887 100644
--- a/chromium/weblayer/public/java/res/values/ids.xml
+++ b/chromium/weblayer/public/java/res/values/ids.xml
@@ -5,4 +5,6 @@
<resources>
<item type="id" name="weblayer_media_session_notification" />
+ <item type="id" name="weblayer_presentation_api_notification" />
+ <item type="id" name="weblayer_remote_playback_api_notification" />
</resources>
diff --git a/chromium/weblayer/public/javatestutil/org/chromium/weblayer/TestWebLayer.java b/chromium/weblayer/public/javatestutil/org/chromium/weblayer/TestWebLayer.java
index 084c2f8f2b2..8b6cd91f8f8 100644
--- a/chromium/weblayer/public/javatestutil/org/chromium/weblayer/TestWebLayer.java
+++ b/chromium/weblayer/public/javatestutil/org/chromium/weblayer/TestWebLayer.java
@@ -10,6 +10,7 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.util.AndroidRuntimeException;
import android.view.View;
+import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -138,4 +139,28 @@ public final class TestWebLayer {
public boolean didShowFullscreenToast(Tab tab) throws RemoteException {
return mITestWebLayer.didShowFullscreenToast(tab.getITab());
}
+
+ public void initializeMockMediaRouteProvider(boolean closeRouteWithErrorOnSend,
+ boolean disableIsSupportsSource, @Nullable String createRouteErrorMessage,
+ @Nullable String joinRouteErrorMessage) throws RemoteException {
+ mITestWebLayer.initializeMockMediaRouteProvider(closeRouteWithErrorOnSend,
+ disableIsSupportsSource, createRouteErrorMessage, joinRouteErrorMessage);
+ }
+
+ public View getMediaRouteButton(String name) throws RemoteException {
+ return (View) ObjectWrapper.unwrap(mITestWebLayer.getMediaRouteButton(name), View.class);
+ }
+
+ public void crashTab(Tab tab) throws RemoteException {
+ mITestWebLayer.crashTab(tab.getITab());
+ }
+
+ public boolean isWindowOnSmallDevice(Browser browser) throws RemoteException {
+ return mITestWebLayer.isWindowOnSmallDevice(browser.getIBrowser());
+ }
+
+ public ImageView getSecurityButton(View urlBarView) throws RemoteException {
+ return (ImageView) ObjectWrapper.unwrap(
+ mITestWebLayer.getSecurityButton(ObjectWrapper.wrap(urlBarView)), ImageView.class);
+ }
}
diff --git a/chromium/weblayer/public/navigation.h b/chromium/weblayer/public/navigation.h
index b61da6cb1a5..a5fcf592831 100644
--- a/chromium/weblayer/public/navigation.h
+++ b/chromium/weblayer/public/navigation.h
@@ -82,7 +82,8 @@ class Navigation {
kHttpServerError = 2, // Server responded with 5xx status code.
kSSLError = 3, // Certificate error.
kConnectivityError = 4, // Problem connecting to server.
- kOtherError = 5, // An error not listed above occurred.
+ kOtherError = 5, // An error not listed above or below occurred.
+ kSafeBrowsingError = 6, // Safe browsing error.
};
// Return information about the error, if any, that was encountered while
@@ -110,6 +111,11 @@ class Navigation {
// SetRequestHeader().
virtual void SetUserAgentString(const std::string& value) = 0;
+ // Disables auto-reload for this navigation if the network is down and comes
+ // back later. Auto-reload is enabled by default. This function may only be
+ // called from NavigationObserver::NavigationStarted().
+ virtual void DisableNetworkErrorAutoReload() = 0;
+
// Whether the navigation was initiated by the page. Examples of
// page-initiated navigations include:
// * <a> link click
diff --git a/chromium/weblayer/public/navigation_controller.h b/chromium/weblayer/public/navigation_controller.h
index 56691c87bec..9216002f150 100644
--- a/chromium/weblayer/public/navigation_controller.h
+++ b/chromium/weblayer/public/navigation_controller.h
@@ -19,7 +19,6 @@ class NavigationController {
// |NavigationController::LoadURLParams|.
struct NavigateParams {
bool should_replace_current_entry = false;
- bool disable_network_error_auto_reload = false;
bool enable_auto_play = false;
};
diff --git a/chromium/weblayer/public/navigation_observer.h b/chromium/weblayer/public/navigation_observer.h
index 86567cb5255..c9aa14f056d 100644
--- a/chromium/weblayer/public/navigation_observer.h
+++ b/chromium/weblayer/public/navigation_observer.h
@@ -7,6 +7,11 @@
class GURL;
+namespace base {
+class TimeDelta;
+class TimeTicks;
+} // namespace base
+
namespace weblayer {
class Navigation;
@@ -98,6 +103,23 @@ class NavigationObserver {
// first paint after a non-empty layout has finished.
virtual void OnFirstContentfulPaint() {}
+ // Similar to OnFirstContentfulPaint but contains timing information from the
+ // renderer process to better align with the Navigation Timing API.
+ // |navigation_start| is the navigation start time.
+ // |first_contentful_paint| is the duration to first contentful paint from
+ // navigation start.
+ virtual void OnFirstContentfulPaint(
+ const base::TimeTicks& navigation_start,
+ const base::TimeDelta& first_contentful_paint) {}
+
+ // This is fired when the largest contentful paint page load metric is
+ // available. |navigation_start| is the navigation start time.
+ // |largest_contentful_paint| is the duration to largest contentful paint from
+ // navigation start.
+ virtual void OnLargestContentfulPaint(
+ const base::TimeTicks& navigation_start,
+ const base::TimeDelta& largest_contentful_paint) {}
+
// Called after each navigation to indicate that the old page is no longer
// being rendered. Note this is not ordered with respect to
// OnFirstContentfulPaint.
diff --git a/chromium/weblayer/public/tab.h b/chromium/weblayer/public/tab.h
index 6d26eb6ba21..2485fef069b 100644
--- a/chromium/weblayer/public/tab.h
+++ b/chromium/weblayer/public/tab.h
@@ -25,6 +25,7 @@ class WebView;
#endif
namespace weblayer {
+class Browser;
class ErrorPageDelegate;
class FaviconFetcher;
class FaviconFetcherDelegate;
@@ -40,6 +41,9 @@ class Tab {
public:
virtual ~Tab() = default;
+ // Returns the Browser that owns this.
+ virtual Browser* GetBrowser() = 0;
+
// Sets the ErrorPageDelegate. If none is set, a default action will be taken
// for any given interaction with an error page.
virtual void SetErrorPageDelegate(ErrorPageDelegate* delegate) = 0;
diff --git a/chromium/weblayer/renderer/DEPS b/chromium/weblayer/renderer/DEPS
index 315e8952753..4d6427eb002 100644
--- a/chromium/weblayer/renderer/DEPS
+++ b/chromium/weblayer/renderer/DEPS
@@ -6,8 +6,8 @@ include_rules = [
"+components/error_page/common",
"+components/grit",
"+components/page_load_metrics/renderer",
- "+components/prerender/common",
- "+components/prerender/renderer",
+ "+components/no_state_prefetch/common",
+ "+components/no_state_prefetch/renderer",
"+components/safe_browsing/content/common",
"+components/safe_browsing/content/renderer",
"+components/safe_browsing/core/common",
diff --git a/chromium/weblayer/renderer/content_renderer_client_impl.cc b/chromium/weblayer/renderer/content_renderer_client_impl.cc
index 76ca9ee102e..afa7ad46be4 100644
--- a/chromium/weblayer/renderer/content_renderer_client_impl.cc
+++ b/chromium/weblayer/renderer/content_renderer_client_impl.cc
@@ -12,13 +12,13 @@
#include "components/error_page/common/error.h"
#include "components/grit/components_scaled_resources.h"
#include "components/js_injection/renderer/js_communication.h"
+#include "components/no_state_prefetch/common/prerender_types.mojom.h"
+#include "components/no_state_prefetch/common/prerender_url_loader_throttle.h"
+#include "components/no_state_prefetch/renderer/prerender_helper.h"
+#include "components/no_state_prefetch/renderer/prerender_render_frame_observer.h"
+#include "components/no_state_prefetch/renderer/prerender_utils.h"
+#include "components/no_state_prefetch/renderer/prerenderer_client.h"
#include "components/page_load_metrics/renderer/metrics_render_frame_observer.h"
-#include "components/prerender/common/prerender_types.mojom.h"
-#include "components/prerender/common/prerender_url_loader_throttle.h"
-#include "components/prerender/renderer/prerender_helper.h"
-#include "components/prerender/renderer/prerender_render_frame_observer.h"
-#include "components/prerender/renderer/prerender_utils.h"
-#include "components/prerender/renderer/prerenderer_client.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/render_view.h"
@@ -38,6 +38,8 @@
#include "content/public/renderer/render_thread.h"
#include "services/service_manager/public/cpp/local_interface_provider.h"
#include "third_party/blink/public/platform/web_runtime_features.h"
+#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/web_security_policy.h"
#endif
namespace weblayer {
@@ -77,6 +79,10 @@ void ContentRendererClientImpl::RenderThreadStarted() {
local_interface_provider_ = std::make_unique<SpellcheckInterfaceProvider>();
spellcheck_ = std::make_unique<SpellCheck>(local_interface_provider_.get());
}
+ // TODO(sky): refactor. This comes from chrome/common/url_constants.cc's
+ // kAndroidAppScheme.
+ blink::WebSecurityPolicy::RegisterURLSchemeAsAllowedForReferrer(
+ blink::WebString::FromUTF8("android-app"));
#endif
content::RenderThread* thread = content::RenderThread::Get();
@@ -146,10 +152,6 @@ SkBitmap* ContentRendererClientImpl::GetSadWebViewBitmap() {
.ToSkBitmap());
}
-bool ContentRendererClientImpl::HasErrorPage(int http_status_code) {
- return http_status_code >= 400;
-}
-
void ContentRendererClientImpl::PrepareErrorPage(
content::RenderFrame* render_frame,
const blink::WebURLError& error,
diff --git a/chromium/weblayer/renderer/content_renderer_client_impl.h b/chromium/weblayer/renderer/content_renderer_client_impl.h
index 95c1672e271..db74185ea71 100644
--- a/chromium/weblayer/renderer/content_renderer_client_impl.h
+++ b/chromium/weblayer/renderer/content_renderer_client_impl.h
@@ -30,7 +30,6 @@ class ContentRendererClientImpl : public content::ContentRendererClient {
void RenderViewCreated(content::RenderView* render_view) override;
SkBitmap* GetSadPluginBitmap() override;
SkBitmap* GetSadWebViewBitmap() override;
- bool HasErrorPage(int http_status_code) override;
void PrepareErrorPage(content::RenderFrame* render_frame,
const blink::WebURLError& error,
const std::string& http_method,
diff --git a/chromium/weblayer/renderer/url_loader_throttle_provider.cc b/chromium/weblayer/renderer/url_loader_throttle_provider.cc
index 52382086f15..4f0a74fbc33 100644
--- a/chromium/weblayer/renderer/url_loader_throttle_provider.cc
+++ b/chromium/weblayer/renderer/url_loader_throttle_provider.cc
@@ -7,7 +7,7 @@
#include <memory>
#include "base/memory/ptr_util.h"
-#include "components/prerender/renderer/prerender_helper.h"
+#include "components/no_state_prefetch/renderer/prerender_helper.h"
#include "components/safe_browsing/content/renderer/renderer_url_loader_throttle.h"
#include "content/public/renderer/render_thread.h"
#include "third_party/blink/public/common/loader/resource_type_util.h"
diff --git a/chromium/weblayer/renderer/weblayer_render_frame_observer.cc b/chromium/weblayer/renderer/weblayer_render_frame_observer.cc
index 814e8a330c2..da2d6cae255 100644
--- a/chromium/weblayer/renderer/weblayer_render_frame_observer.cc
+++ b/chromium/weblayer/renderer/weblayer_render_frame_observer.cc
@@ -8,7 +8,7 @@
#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
-#include "components/prerender/renderer/prerender_helper.h"
+#include "components/no_state_prefetch/renderer/prerender_helper.h"
#include "components/translate/content/renderer/translate_agent.h"
#include "components/translate/core/common/translate_util.h"
#include "third_party/blink/public/web/web_document_loader.h"
diff --git a/chromium/weblayer/shell/BUILD.gn b/chromium/weblayer/shell/BUILD.gn
index 66984a7da54..a30f3e8407c 100644
--- a/chromium/weblayer/shell/BUILD.gn
+++ b/chromium/weblayer/shell/BUILD.gn
@@ -14,13 +14,6 @@ if (is_android) {
import("//build/config/android/config.gni")
}
-# This file depends on the legacy global sources assignment filter. It should
-# be converted to check target platform before assigning source files to the
-# sources variable. Remove this import and set_sources_assignment_filter call
-# when the file has been converted. See https://crbug.com/1018739 for details.
-import("//build/config/deprecated_default_sources_assignment_filter.gni")
-set_sources_assignment_filter(deprecated_default_sources_assignment_filter)
-
static_library("weblayer_shell_lib") {
testonly = true
sources = [
@@ -28,11 +21,14 @@ static_library("weblayer_shell_lib") {
"app/shell_main_params.h",
"browser/shell.cc",
"browser/shell.h",
- "browser/shell_android.cc",
"common/shell_switches.cc",
"common/shell_switches.h",
]
+ if (is_android) {
+ sources += [ "browser/shell_android.cc" ]
+ }
+
configs += [
"//build/config:precompiled_headers",
@@ -170,6 +166,7 @@ repack("support_pak") {
"$root_gen_dir/third_party/blink/public/resources/blink_scaled_resources_100_percent.pak",
"$root_gen_dir/third_party/blink/public/strings/blink_strings_en-US.pak",
"$root_gen_dir/ui/resources/ui_resources_100_percent.pak",
+ "$root_gen_dir/ui/resources/webui_generated_resources.pak",
"$root_gen_dir/ui/resources/webui_resources.pak",
"$root_gen_dir/ui/strings/app_locale_settings_en-US.pak",
"$root_gen_dir/ui/strings/ui_strings_en-US.pak",
diff --git a/chromium/weblayer/shell/android/BUILD.gn b/chromium/weblayer/shell/android/BUILD.gn
index 91eb911575e..c734c41455d 100644
--- a/chromium/weblayer/shell/android/BUILD.gn
+++ b/chromium/weblayer/shell/android/BUILD.gn
@@ -36,12 +36,13 @@ android_library("weblayer_shell_java") {
testonly = true
resources_package = "org.chromium.weblayer.shell"
- # The play services dependency is necessary for the
+ # The google_play_services_base_java dependency is necessary for the
# google_play_services_version definition in the manifest.
deps = [
":weblayer_shell_resources",
"$google_play_services_package:google_play_services_base_java",
"//base:base_java",
+ "//components/strictmode/android:java",
"//third_party/android_deps:android_support_v4_java",
"//third_party/android_deps:android_support_v7_appcompat_java",
"//third_party/android_deps:androidx_annotation_annotation_java",
@@ -151,6 +152,23 @@ if (enable_chrome_android_internal) {
"//clank/java:monochrome_apk",
]
}
+
+ generate_wrapper("run_weblayer_shell_webview_google") {
+ testonly = true
+ wrapper_script = "$root_out_dir/bin/run_weblayer_shell_webview_google"
+ executable = "//weblayer/tools/run_weblayer_shell.py"
+ executable_args = [
+ "--shell-apk-path",
+ "@WrappedPath(apks/WebLayerShellSystemWebView.apk)",
+ "--switch-webview-to",
+ "@WrappedPath(apks/SystemWebViewGoogle.apk)",
+ ]
+
+ deps = [
+ ":weblayer_shell_system_webview_apk",
+ "//clank/android_webview:system_webview_google_apk",
+ ]
+ }
}
generate_wrapper("run_weblayer_shell_webview") {
diff --git a/chromium/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_browsertests_apk/WebLayerBrowserTestsActivity.java b/chromium/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_browsertests_apk/WebLayerBrowserTestsActivity.java
index 7a93c55731b..56c2473bab1 100644
--- a/chromium/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_browsertests_apk/WebLayerBrowserTestsActivity.java
+++ b/chromium/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_browsertests_apk/WebLayerBrowserTestsActivity.java
@@ -119,4 +119,15 @@ public class WebLayerBrowserTestsActivity extends NativeBrowserTestActivity {
return new File(UrlUtils.getIsolatedTestRoot(),
WebLayerBrowserTestsApplication.PRIVATE_DATA_DIRECTORY_SUFFIX);
}
+
+ @Override
+ /**
+ * Ensure that the user data directory gets overridden to getPrivateDataDirectory() (which is
+ * cleared at the start of every run); the directory that ANDROID_APP_DATA_DIR is set to in the
+ * context of Java browsertests is not cleared as it also holds persistent state, which
+ * causes test failures due to state bleedthrough. See crbug.com/617734 for details.
+ */
+ protected String getUserDataDirectoryCommandLineSwitch() {
+ return "weblayer-user-data-dir";
+ }
}
diff --git a/chromium/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_private/MetricsTestHelper.java b/chromium/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_private/MetricsTestHelper.java
index c89b0e38793..a2ede31755d 100644
--- a/chromium/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_private/MetricsTestHelper.java
+++ b/chromium/weblayer/shell/android/browsertests_apk/src/org/chromium/weblayer_private/MetricsTestHelper.java
@@ -21,10 +21,13 @@ import org.chromium.weblayer.WebLayer;
@JNINamespace("weblayer")
class MetricsTestHelper {
private static class TestGmsBridge extends GmsBridge {
- private final boolean mUserConsent;
+ private final @ConsentType int mConsentType;
+ private Callback<Boolean> mConsentCallback;
+ public static TestGmsBridge sInstance;
- public TestGmsBridge(boolean userConsent) {
- mUserConsent = userConsent;
+ public TestGmsBridge(@ConsentType int consentType) {
+ sInstance = this;
+ mConsentType = consentType;
}
@Override
@@ -40,7 +43,11 @@ class MetricsTestHelper {
@Override
public void queryMetricsSetting(Callback<Boolean> callback) {
ThreadUtils.assertOnUiThread();
- callback.onResult(mUserConsent);
+ if (mConsentType == ConsentType.DELAY_CONSENT) {
+ mConsentCallback = callback;
+ } else {
+ callback.onResult(mConsentType == ConsentType.CONSENT);
+ }
}
@Override
@@ -50,8 +57,15 @@ class MetricsTestHelper {
}
@CalledByNative
- private static void installTestGmsBridge(boolean userConsent) {
- GmsBridge.injectInstance(new TestGmsBridge(userConsent));
+ private static void installTestGmsBridge(@ConsentType int consentType) {
+ GmsBridge.injectInstance(new TestGmsBridge(consentType));
+ }
+
+ @CalledByNative
+ private static void runConsentCallback(boolean hasConsent) {
+ assert TestGmsBridge.sInstance != null;
+ assert TestGmsBridge.sInstance.mConsentCallback != null;
+ TestGmsBridge.sInstance.mConsentCallback.onResult(hasConsent);
}
@CalledByNative
diff --git a/chromium/weblayer/shell/android/shell_apk/AndroidManifest.xml b/chromium/weblayer/shell/android/shell_apk/AndroidManifest.xml
index dd1feaf422f..f3028ccc4f3 100644
--- a/chromium/weblayer/shell/android/shell_apk/AndroidManifest.xml
+++ b/chromium/weblayer/shell/android/shell_apk/AndroidManifest.xml
@@ -43,15 +43,24 @@
<activity android:name="TelemetryActivity"
android:theme="@android:style/Theme.Holo.Light.NoActionBar">
</activity>
- <activity android:name="org.chromium.weblayer.test.ExternalNavigationTest$DummyActivityForSpecialScheme"
- android:exported="true" >
- <intent-filter>
- <action android:name="android.intent.action.VIEW" />
- <category android:name="android.intent.category.DEFAULT" />
- <category android:name="android.intent.category.BROWSABLE" />
- <data android:host="weblayertest" android:scheme="weblayer" />
- </intent-filter>
- </activity>
+ <activity android:name="org.chromium.weblayer.test.ExternalNavigationTest$DummyActivityForSpecialScheme"
+ android:exported="true" >
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+ <data android:host="weblayertest" android:scheme="weblayer" />
+ </intent-filter>
+ </activity>
+
+ <!-- Cast support -->
+ <meta-data
+ android:name="org.chromium.weblayer.ENABLE_REMOTE_MEDIA" android:value="true"/>
+ <meta-data
+ android:name=
+ "com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
+ android:value="org.chromium.components.media_router.caf.CastOptionsProvider"/>
+
{% if weblayer_package is defined %}
<meta-data android:name="org.chromium.weblayer.WebLayerPackage"
android:value="{{ weblayer_package }}"/>
diff --git a/chromium/weblayer/shell/android/shell_apk/DEPS b/chromium/weblayer/shell/android/shell_apk/DEPS
index 6b0969925be..0257866fa4a 100644
--- a/chromium/weblayer/shell/android/shell_apk/DEPS
+++ b/chromium/weblayer/shell/android/shell_apk/DEPS
@@ -1,5 +1,6 @@
noparent = True
include_rules = [
"+base/android/java",
+ "+components/strictmode/android/java",
"+weblayer/public/java",
]
diff --git a/chromium/weblayer/shell/android/shell_apk/res/menu/app_menu.xml b/chromium/weblayer/shell/android/shell_apk/res/menu/app_menu.xml
index 4b990c38572..375762e440f 100644
--- a/chromium/weblayer/shell/android/shell_apk/res/menu/app_menu.xml
+++ b/chromium/weblayer/shell/android/shell_apk/res/menu/app_menu.xml
@@ -26,4 +26,8 @@
android:title="Set translate target language to German" />
<item android:id="@+id/clear_translate_target_lang_menu_id"
android:title="Clear translate target language override" />
+ <item android:id="@+id/desktop_site_menu_id"
+ android:title="Request desktop site" />
+ <item android:id="@+id/no_desktop_site_menu_id"
+ android:title="Request mobile site" />
</menu>
diff --git a/chromium/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/InstrumentationActivity.java b/chromium/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/InstrumentationActivity.java
index 15507bdef11..1db38db3c21 100644
--- a/chromium/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/InstrumentationActivity.java
+++ b/chromium/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/InstrumentationActivity.java
@@ -24,6 +24,7 @@ import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import org.chromium.base.ContextUtils;
+import org.chromium.components.strictmode.ThreadStrictModeInterceptor;
import org.chromium.weblayer.Browser;
import org.chromium.weblayer.FullscreenCallback;
import org.chromium.weblayer.NewTabCallback;
@@ -42,6 +43,8 @@ import java.util.List;
/**
* Activity for running instrumentation tests.
*/
+// This isn't part of Chrome, so using explicit colors/sizes is ok.
+@SuppressWarnings("checkstyle:SetTextColorAndSetTextSizeCheck")
public class InstrumentationActivity extends FragmentActivity {
private static final String TAG = "WLInstrumentation";
private static final String KEY_MAIN_VIEW_ID = "mainViewId";
@@ -55,10 +58,17 @@ public class InstrumentationActivity extends FragmentActivity {
// True by default. If set to false, the test should call loadWebLayerSync.
public static final String EXTRA_CREATE_WEBLAYER = "EXTRA_CREATE_WEBLAYER";
+ public static final String EXTRA_TOP_VIEW_MIN_HEIGHT = "EXTRA_TOP_VIEW_MIN_HEIGHT";
+ public static final String EXTRA_ONLY_EXPAND_CONTROLS_AT_TOP =
+ "EXTRA_ONLY_EXPAND_CONTROLS_AT_TOP";
+
// Used in tests to specify whether WebLayer URL bar should set default click listeners
// that show Page Info UI on its TextView.
public static final String EXTRA_URLBAR_TEXT_CLICKABLE = "EXTRA_URLBAR_TEXT_CLICKABLE";
+ // Used in tests to specify whether WebLayer URL bar should show publisher url.
+ public static final String EXTRA_URLBAR_SHOW_PUBLISHER_URL = "EXTRA_URLBAR_SHOW_PUBLISHER_URL";
+
private static OnCreatedCallback sOnCreatedCallback;
// If true, multiple fragments may be created. Only the first is attached. This is useful for
@@ -183,8 +193,8 @@ public class InstrumentationActivity extends FragmentActivity {
protected void onCreate(final Bundle savedInstanceState) {
// JaCoCo injects code that does file access, which doesn't work well with strict mode.
if (!isJaCoCoEnabled()) {
- StrictMode.setThreadPolicy(
- new ThreadPolicy.Builder().detectAll().penaltyLog().penaltyDeath().build());
+ ThreadStrictModeInterceptor.buildWithDeathPenaltyAndKnownViolationExemptions().install(
+ new ThreadPolicy.Builder().detectAll().build());
// This doesn't use detectAll() as the untagged sockets policy is encountered in tests
// using TestServer.
StrictMode.setVmPolicy(new VmPolicy.Builder()
@@ -270,7 +280,18 @@ public class InstrumentationActivity extends FragmentActivity {
mBrowser = Browser.fromFragment(mFragment);
mProfile = mBrowser.getProfile();
- mBrowser.setTopView(mTopContentsContainer);
+ final boolean onlyExpandControlsAtTop =
+ getIntent().getBooleanExtra(EXTRA_ONLY_EXPAND_CONTROLS_AT_TOP, false);
+ final int minTopViewHeight = getIntent().getIntExtra(EXTRA_TOP_VIEW_MIN_HEIGHT, -1);
+
+ if (onlyExpandControlsAtTop || minTopViewHeight != -1) {
+ // This was added in 86.
+ mBrowser.setTopView(mTopContentsContainer, Math.max(0, minTopViewHeight),
+ onlyExpandControlsAtTop,
+ /* animate */ false);
+ } else {
+ mBrowser.setTopView(mTopContentsContainer);
+ }
mRendererCrashListener = new TabCallback() {
@Override
@@ -375,6 +396,9 @@ public class InstrumentationActivity extends FragmentActivity {
if (getIntent().getBooleanExtra(EXTRA_URLBAR_TEXT_CLICKABLE, true)) {
optionsBuilder = optionsBuilder.showPageInfoWhenTextIsClicked();
}
+ if (getIntent().getBooleanExtra(EXTRA_URLBAR_SHOW_PUBLISHER_URL, false)) {
+ optionsBuilder = optionsBuilder.showPublisherUrl();
+ }
mUrlBarView = mBrowser.getUrlBarController().createUrlBarView(optionsBuilder.build());
diff --git a/chromium/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/TelemetryActivity.java b/chromium/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/TelemetryActivity.java
index 7495340bdb4..8cef642e52b 100644
--- a/chromium/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/TelemetryActivity.java
+++ b/chromium/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/TelemetryActivity.java
@@ -6,6 +6,7 @@ package org.chromium.weblayer.shell;
import android.net.Uri;
import android.os.Bundle;
+import android.os.Trace;
import android.text.InputType;
import android.view.View;
import android.view.ViewGroup;
@@ -21,6 +22,8 @@ import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import org.chromium.weblayer.Browser;
+import org.chromium.weblayer.Navigation;
+import org.chromium.weblayer.NavigationCallback;
import org.chromium.weblayer.Profile;
import org.chromium.weblayer.Tab;
import org.chromium.weblayer.TabCallback;
@@ -37,6 +40,12 @@ import java.util.List;
public class TelemetryActivity extends FragmentActivity {
private static final String KEY_MAIN_VIEW_ID = "mainViewId";
+ // The trace tag names are the same as WebView's telemetry activity so the perf metric logic can
+ // be shared between them.
+ private static final String START_UP_TRACE_TAG = "WebViewStartupInterval";
+ private static final String LOAD_URL_TRACE_TAG = "WebViewBlankUrlLoadInterval";
+ private static final String DUMMY_TRACE_TAG = "WebViewDummyInterval";
+
private Profile mProfile;
private Fragment mFragment;
private Browser mBrowser;
@@ -77,6 +86,14 @@ public class TelemetryActivity extends FragmentActivity {
mTopContentsContainer.addView(
mUrlView, new RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0));
+ Trace.beginSection(START_UP_TRACE_TAG);
+
+ // TODO(aluo): Use async tracing to avoid having to do this
+ // dummyTraceTag is needed here to prevent code in Android intended to
+ // end activityStart from ending loadUrlTraceTag prematurely,
+ // see crbug/919221
+ Trace.beginSection(DUMMY_TRACE_TAG);
+
// If activity is re-created during process restart, FragmentManager attaches
// BrowserFragment immediately, resulting in synchronous init. By the time this line
// executes, the synchronous init has already happened, so WebLayer#createAsync will
@@ -102,6 +119,11 @@ public class TelemetryActivity extends FragmentActivity {
}
private void onWebLayerReady(WebLayer webLayer) {
+ // Ends START_UP_TRACE_TAG
+ Trace.endSection();
+ // Ends activityStart
+ Trace.endSection();
+
if (mBrowser != null || isFinishing() || isDestroyed()) return;
webLayer.setRemoteDebuggingEnabled(true);
@@ -113,6 +135,14 @@ public class TelemetryActivity extends FragmentActivity {
mBrowser.setTopView(mTopContentsContainer);
setTab(mBrowser.getActiveTab());
+ Trace.beginSection(LOAD_URL_TRACE_TAG);
+ mTab.getNavigationController().registerNavigationCallback(new NavigationCallback() {
+ @Override
+ public void onNavigationCompleted(Navigation navigation) {
+ // Ends LOAD_URL_TRACE_TAG
+ Trace.endSection();
+ }
+ });
if (getIntent() != null) {
mTab.getNavigationController().navigate(Uri.parse(getIntent().getDataString()));
}
diff --git a/chromium/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java b/chromium/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java
index ec3bcecf581..f8baa69613e 100644
--- a/chromium/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java
+++ b/chromium/weblayer/shell/android/shell_apk/src/org/chromium/weblayer/shell/WebLayerShellActivity.java
@@ -60,7 +60,6 @@ import org.chromium.weblayer.NavigationController;
import org.chromium.weblayer.NewTabCallback;
import org.chromium.weblayer.NewTabType;
import org.chromium.weblayer.Profile;
-import org.chromium.weblayer.SettingType;
import org.chromium.weblayer.SiteSettingsActivity;
import org.chromium.weblayer.Tab;
import org.chromium.weblayer.TabCallback;
@@ -72,8 +71,10 @@ import org.chromium.weblayer.WebLayer;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* Activity for managing the Demo Shell.
@@ -93,12 +94,17 @@ public class WebLayerShellActivity extends AppCompatActivity {
implements View.OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener {
private static final int MENU_ID_COPY_LINK_URI = 1;
private static final int MENU_ID_COPY_LINK_TEXT = 2;
+ private static final int MENU_ID_DOWNLOAD_IMAGE = 3;
+ private static final int MENU_ID_DOWNLOAD_VIDEO = 4;
+ private static final int MENU_ID_DOWNLOAD_LINK = 5;
private ContextMenuParams mParams;
+ private Tab mTab;
private Context mContext;
- public ContextMenuCreator(ContextMenuParams params) {
+ public ContextMenuCreator(ContextMenuParams params, Tab tab) {
mParams = params;
+ mTab = tab;
}
@Override
@@ -116,6 +122,21 @@ public class WebLayerShellActivity extends AppCompatActivity {
menu.add(Menu.NONE, MENU_ID_COPY_LINK_TEXT, Menu.NONE, "Copy link text");
copyLinkTextItem.setOnMenuItemClickListener(this);
}
+ if (mParams.canDownload) {
+ if (mParams.isImage) {
+ MenuItem downloadImageItem = menu.add(
+ Menu.NONE, MENU_ID_DOWNLOAD_IMAGE, Menu.NONE, "Download image");
+ downloadImageItem.setOnMenuItemClickListener(this);
+ } else if (mParams.isVideo) {
+ MenuItem downloadVideoItem = menu.add(
+ Menu.NONE, MENU_ID_DOWNLOAD_VIDEO, Menu.NONE, "Download video");
+ downloadVideoItem.setOnMenuItemClickListener(this);
+ } else if (mParams.linkUri != null) {
+ MenuItem downloadVideoItem =
+ menu.add(Menu.NONE, MENU_ID_DOWNLOAD_LINK, Menu.NONE, "Download link");
+ downloadVideoItem.setOnMenuItemClickListener(this);
+ }
+ }
if (!TextUtils.isEmpty(mParams.titleOrAltText)) {
TextView altTextView = new TextView(mContext);
altTextView.setText(mParams.titleOrAltText);
@@ -136,6 +157,11 @@ public class WebLayerShellActivity extends AppCompatActivity {
case MENU_ID_COPY_LINK_TEXT:
clipboard.setPrimaryClip(ClipData.newPlainText("link text", mParams.linkText));
break;
+ case MENU_ID_DOWNLOAD_IMAGE:
+ case MENU_ID_DOWNLOAD_VIDEO:
+ case MENU_ID_DOWNLOAD_LINK:
+ mTab.download(mParams);
+ break;
default:
break;
}
@@ -143,6 +169,17 @@ public class WebLayerShellActivity extends AppCompatActivity {
}
}
+ // Used for any state that is per Tab.
+ private static final class PerTabState {
+ public final FaviconFetcher mFaviconFetcher;
+ public final TabCallback mTabCallback;
+
+ PerTabState(FaviconFetcher faviconFetcher, TabCallback tabCallback) {
+ mFaviconFetcher = faviconFetcher;
+ mTabCallback = tabCallback;
+ }
+ }
+
private static final String TAG = "WebLayerShell";
private static final float DEFAULT_TEXT_SIZE = 15.0F;
private static final int EDITABLE_URL_TEXT_VIEW = 0;
@@ -157,8 +194,12 @@ public class WebLayerShellActivity extends AppCompatActivity {
private View mTopContentsContainer;
private View mAltTopContentsContainer;
private TabListCallback mTabListCallback;
+ private NewTabCallback mNewTabCallback;
+ private FullscreenCallback mFullscreenCallback;
+ private NavigationCallback mNavigationCallback;
+ private ErrorPageCallback mErrorPageCallback;
private List<Tab> mPreviousTabList = new ArrayList<>();
- private Map<Tab, FaviconFetcher> mTabToFaviconFetcher = new HashMap<>();
+ private Map<Tab, PerTabState> mTabToPerTabState = new HashMap<>();
private Runnable mExitFullscreenRunnable;
private boolean mIsTopViewVisible = true;
private View mBottomView;
@@ -225,6 +266,9 @@ public class WebLayerShellActivity extends AppCompatActivity {
.setVisible(mBrowser.getActiveTab().canTranslate());
popup.getMenu().findItem(R.id.webview_compat_menu_id).setVisible(!mEnableWebViewCompat);
popup.getMenu().findItem(R.id.no_webview_compat_menu_id).setVisible(mEnableWebViewCompat);
+ boolean isDesktopUserAgent = mBrowser.getActiveTab().isDesktopUserAgentEnabled();
+ popup.getMenu().findItem(R.id.desktop_site_menu_id).setVisible(!isDesktopUserAgent);
+ popup.getMenu().findItem(R.id.no_desktop_site_menu_id).setVisible(isDesktopUserAgent);
popup.setOnMenuItemClickListener(item -> {
if (item.getItemId() == R.id.reload_menu_id) {
mBrowser.getActiveTab().getNavigationController().reload();
@@ -280,6 +324,14 @@ public class WebLayerShellActivity extends AppCompatActivity {
restartShell(false);
}
+ if (item.getItemId() == R.id.desktop_site_menu_id) {
+ mBrowser.getActiveTab().setDesktopUserAgentEnabled(true);
+ }
+
+ if (item.getItemId() == R.id.no_desktop_site_menu_id) {
+ mBrowser.getActiveTab().setDesktopUserAgentEnabled(false);
+ }
+
if (item.getItemId() == R.id.set_translate_target_lang_menu_id) {
mBrowser.getActiveTab().setTranslateTargetLanguage("de");
}
@@ -374,13 +426,25 @@ public class WebLayerShellActivity extends AppCompatActivity {
@Override
protected void onDestroy() {
super.onDestroy();
+ // NOTE: It's important to unregister any state installed on browser/tab as during a
+ // configuration change (such as rotation) the activity is destroyed but the
+ // browser/fragment/tabs are not.
mUrlViewContainer.reset();
if (mTabListCallback != null) {
- mBrowser.unregisterTabListCallback(mTabListCallback);
- mTabListCallback = null;
+ unregisterBrowserAndTabCallbacks();
}
}
+ private void unregisterBrowserAndTabCallbacks() {
+ assert mBrowser != null;
+ mBrowser.unregisterTabListCallback(mTabListCallback);
+ mTabListCallback = null;
+
+ Set<Tab> tabs = new HashSet(mTabToPerTabState.keySet());
+ for (Tab tab : tabs) unregisterTabCallbacks(tab);
+ mTabToPerTabState.clear();
+ }
+
private void onWebLayerReady(WebLayer webLayer, Bundle savedInstanceState) {
if (isFinishing() || isDestroyed()) return;
@@ -395,7 +459,6 @@ public class WebLayerShellActivity extends AppCompatActivity {
fragment.setRetainInstance(true);
mBrowser = Browser.fromFragment(fragment);
mProfile = mBrowser.getProfile();
- mProfile.setBooleanSetting(SettingType.UKM_ENABLED, true);
mProfile.setUserIdentityCallback(new UserIdentityCallback() {
@Override
public String getEmail() {
@@ -418,9 +481,12 @@ public class WebLayerShellActivity extends AppCompatActivity {
}
});
- setTabCallbacks(mBrowser.getActiveTab(), fragment);
+ createTabCallbacks();
+
+ registerTabCallbacks(mBrowser.getActiveTab());
updateTopView();
+
mTabListCallback = new TabListCallback() {
@Override
public void onActiveTabChanged(Tab activeTab) {
@@ -435,6 +501,10 @@ public class WebLayerShellActivity extends AppCompatActivity {
public void onTabRemoved(Tab tab) {
closeTab(tab);
}
+ @Override
+ public void onWillDestroyBrowserAndAllTabs() {
+ unregisterBrowserAndTabCallbacks();
+ }
};
mBrowser.registerTabListCallback(mTabListCallback);
View nonEditUrlView = mBrowser.getUrlBarController().createUrlBarView(
@@ -442,6 +512,7 @@ public class WebLayerShellActivity extends AppCompatActivity {
.setTextSizeSP(DEFAULT_TEXT_SIZE)
.setTextColor(android.R.color.black)
.setIconColor(android.R.color.black)
+ .showPublisherUrl()
.setTextClickListener(v -> {
mEditUrlView.setText("");
mUrlViewContainer.setDisplayedChild(EDITABLE_URL_TEXT_VIEW);
@@ -489,16 +560,17 @@ public class WebLayerShellActivity extends AppCompatActivity {
.toString();
}
- private void setTabCallbacks(Tab tab, Fragment fragment) {
- tab.setNewTabCallback(new NewTabCallback() {
+ private void createTabCallbacks() {
+ mNewTabCallback = new NewTabCallback() {
@Override
public void onNewTab(Tab newTab, @NewTabType int type) {
- setTabCallbacks(newTab, fragment);
+ registerTabCallbacks(newTab);
mPreviousTabList.add(mBrowser.getActiveTab());
mBrowser.setActiveTab(newTab);
}
- });
- tab.setFullscreenCallback(new FullscreenCallback() {
+ };
+
+ mFullscreenCallback = new FullscreenCallback() {
private int mSystemVisibilityToRestore;
@Override
@@ -533,8 +605,36 @@ public class WebLayerShellActivity extends AppCompatActivity {
getWindow().setAttributes(attrs);
}
}
- });
- tab.registerTabCallback(new TabCallback() {
+ };
+
+ mNavigationCallback = new NavigationCallback() {
+ @Override
+ public void onLoadStateChanged(boolean isLoading, boolean toDifferentDocument) {
+ mLoadProgressBar.setVisibility(
+ isLoading && toDifferentDocument ? View.VISIBLE : View.INVISIBLE);
+ }
+
+ @Override
+ public void onLoadProgressChanged(double progress) {
+ mLoadProgressBar.setProgress((int) Math.round(100 * progress));
+ }
+ };
+
+ mErrorPageCallback = new ErrorPageCallback() {
+ @Override
+ public boolean onBackToSafety() {
+ WebLayerShellActivity.this.onBackPressed();
+ return true;
+ }
+ };
+ }
+
+ private void registerTabCallbacks(Tab tab) {
+ tab.setNewTabCallback(mNewTabCallback);
+ tab.setFullscreenCallback(mFullscreenCallback);
+ tab.getNavigationController().registerNavigationCallback(mNavigationCallback);
+ tab.setErrorPageCallback(mErrorPageCallback);
+ TabCallback tabCallback = new TabCallback() {
@Override
public void onVisibleUriChanged(Uri uri) {
mUrlViewContainer.setDisplayedChild(NONEDITABLE_URL_TEXT_VIEW);
@@ -548,7 +648,7 @@ public class WebLayerShellActivity extends AppCompatActivity {
@Override
public void showContextMenu(ContextMenuParams params) {
View webLayerView = getSupportFragmentManager().getFragments().get(0).getView();
- webLayerView.setOnCreateContextMenuListener(new ContextMenuCreator(params));
+ webLayerView.setOnCreateContextMenuListener(new ContextMenuCreator(params, tab));
webLayerView.showContextMenu();
}
@@ -561,32 +661,27 @@ public class WebLayerShellActivity extends AppCompatActivity {
intent.setAction(Intent.ACTION_MAIN);
activity.startActivity(intent);
}
- });
- tab.getNavigationController().registerNavigationCallback(new NavigationCallback() {
- @Override
- public void onLoadStateChanged(boolean isLoading, boolean toDifferentDocument) {
- mLoadProgressBar.setVisibility(
- isLoading && toDifferentDocument ? View.VISIBLE : View.INVISIBLE);
- }
-
- @Override
- public void onLoadProgressChanged(double progress) {
- mLoadProgressBar.setProgress((int) Math.round(100 * progress));
- }
- });
- tab.setErrorPageCallback(new ErrorPageCallback() {
- @Override
- public boolean onBackToSafety() {
- fragment.getActivity().onBackPressed();
- return true;
- }
- });
- mTabToFaviconFetcher.put(tab, tab.createFaviconFetcher(new FaviconCallback() {
+ };
+ tab.registerTabCallback(tabCallback);
+ FaviconFetcher faviconFetcher = tab.createFaviconFetcher(new FaviconCallback() {
@Override
public void onFaviconChanged(Bitmap favicon) {
updateFavicon(tab);
}
- }));
+ });
+ mTabToPerTabState.put(tab, new PerTabState(faviconFetcher, tabCallback));
+ }
+
+ private void unregisterTabCallbacks(Tab tab) {
+ tab.setNewTabCallback(null);
+ tab.setFullscreenCallback(null);
+ tab.getNavigationController().unregisterNavigationCallback(mNavigationCallback);
+ tab.setErrorPageCallback(null);
+ PerTabState perTabState = mTabToPerTabState.get(tab);
+ assert perTabState != null;
+ tab.unregisterTabCallback(perTabState.mTabCallback);
+ perTabState.mFaviconFetcher.destroy();
+ mTabToPerTabState.remove(tab);
}
private void closeTab(Tab tab) {
@@ -594,6 +689,7 @@ public class WebLayerShellActivity extends AppCompatActivity {
if (mBrowser.getActiveTab() == null && !mPreviousTabList.isEmpty()) {
mBrowser.setActiveTab(mPreviousTabList.remove(mPreviousTabList.size() - 1));
}
+ unregisterTabCallbacks(tab);
}
private Fragment getOrCreateBrowserFragment(Bundle savedInstanceState) {
@@ -709,9 +805,10 @@ public class WebLayerShellActivity extends AppCompatActivity {
private void updateFavicon(@NonNull Tab tab) {
if (tab == mBrowser.getActiveTab()) {
- assert mTabToFaviconFetcher.containsKey(tab);
- ((ImageView) findViewById(R.id.favicon_image_view))
- .setImageBitmap(mTabToFaviconFetcher.get(tab).getFaviconForCurrentNavigation());
+ assert mTabToPerTabState.containsKey(tab);
+ ((ImageView) mTopContentsContainer.findViewById(R.id.favicon_image_view))
+ .setImageBitmap(mTabToPerTabState.get(tab)
+ .mFaviconFetcher.getFaviconForCurrentNavigation());
}
}
}
diff --git a/chromium/weblayer/shell/browser/shell_views.cc b/chromium/weblayer/shell/browser/shell_views.cc
index 93759aeb946..d40ed884d1f 100644
--- a/chromium/weblayer/shell/browser/shell_views.cc
+++ b/chromium/weblayer/shell/browser/shell_views.cc
@@ -49,8 +49,7 @@ namespace {
// Maintain the UI controls and web view for web shell
class ShellWindowDelegateView : public views::WidgetDelegateView,
- public views::TextfieldController,
- public views::ButtonListener {
+ public views::TextfieldController {
public:
enum UIControl { BACK_BUTTON, FORWARD_BUTTON, STOP_BUTTON };
@@ -136,8 +135,10 @@ class ShellWindowDelegateView : public views::WidgetDelegateView,
views::ColumnSet* toolbar_column_set = toolbar_layout->AddColumnSet(0);
// Back button
- auto back_button =
- std::make_unique<views::MdTextButton>(this, base::ASCIIToUTF16("Back"));
+ auto back_button = std::make_unique<views::MdTextButton>(
+ base::BindRepeating(&Shell::GoBackOrForward,
+ base::Unretained(shell_.get()), -1),
+ base::ASCIIToUTF16("Back"));
gfx::Size back_button_size = back_button->GetPreferredSize();
toolbar_column_set->AddColumn(
views::GridLayout::CENTER, views::GridLayout::CENTER, 0,
@@ -145,7 +146,9 @@ class ShellWindowDelegateView : public views::WidgetDelegateView,
back_button_size.width() / 2);
// Forward button
auto forward_button = std::make_unique<views::MdTextButton>(
- this, base::ASCIIToUTF16("Forward"));
+ base::BindRepeating(&Shell::GoBackOrForward,
+ base::Unretained(shell_.get()), 1),
+ base::ASCIIToUTF16("Forward"));
gfx::Size forward_button_size = forward_button->GetPreferredSize();
toolbar_column_set->AddColumn(
views::GridLayout::CENTER, views::GridLayout::CENTER, 0,
@@ -153,7 +156,8 @@ class ShellWindowDelegateView : public views::WidgetDelegateView,
forward_button_size.width() / 2);
// Refresh button
auto refresh_button = std::make_unique<views::MdTextButton>(
- this, base::ASCIIToUTF16("Refresh"));
+ base::BindRepeating(&Shell::Reload, base::Unretained(shell_.get())),
+ base::ASCIIToUTF16("Refresh"));
gfx::Size refresh_button_size = refresh_button->GetPreferredSize();
toolbar_column_set->AddColumn(
views::GridLayout::CENTER, views::GridLayout::CENTER, 0,
@@ -161,7 +165,8 @@ class ShellWindowDelegateView : public views::WidgetDelegateView,
refresh_button_size.width() / 2);
// Stop button
auto stop_button = std::make_unique<views::MdTextButton>(
- this, base::ASCIIToUTF16("Stop (100%)"));
+ base::BindRepeating(&Shell::Stop, base::Unretained(shell_.get())),
+ base::ASCIIToUTF16("Stop (100%)"));
int stop_button_width = stop_button->GetPreferredSize().width();
toolbar_column_set->AddColumn(views::GridLayout::FILL,
views::GridLayout::CENTER, 0,
@@ -231,18 +236,6 @@ class ShellWindowDelegateView : public views::WidgetDelegateView,
return false;
}
- // Overridden from ButtonListener
- void ButtonPressed(views::Button* sender, const ui::Event& event) override {
- if (sender == back_button_)
- shell_->GoBackOrForward(-1);
- else if (sender == forward_button_)
- shell_->GoBackOrForward(1);
- else if (sender == refresh_button_)
- shell_->Reload();
- else if (sender == stop_button_)
- shell_->Stop();
- }
-
// Overridden from WidgetDelegateView
base::string16 GetWindowTitle() const override { return title_; }
diff --git a/chromium/weblayer/test/BUILD.gn b/chromium/weblayer/test/BUILD.gn
index 60f7b969ebc..a3aa7628878 100644
--- a/chromium/weblayer/test/BUILD.gn
+++ b/chromium/weblayer/test/BUILD.gn
@@ -42,6 +42,7 @@ if (is_android) {
"//content/public/test/android:content_java_test_support",
"//testing/android/native_test:native_test_java",
"//third_party/android_deps:android_support_v4_java",
+ "//third_party/android_deps:androidx_annotation_annotation_java",
"//third_party/android_deps:androidx_core_core_java",
"//ui/android:ui_java",
"//weblayer/browser/java",
@@ -49,6 +50,7 @@ if (is_android) {
"//weblayer/public/java",
"//weblayer/public/javatestutil:test_java",
]
+ srcjar_deps = [ ":generated_enums" ]
annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
}
@@ -70,6 +72,10 @@ if (is_android) {
deps += [ "//v8:v8_external_startup_data_assets" ]
}
}
+
+ java_cpp_enum("generated_enums") {
+ sources = [ "//weblayer/browser/android/metrics/metrics_test_helper.h" ]
+ }
}
test("weblayer_browsertests") {
@@ -96,20 +102,22 @@ test("weblayer_browsertests") {
"//components/autofill/core/browser",
"//components/autofill/core/browser:test_support",
"//components/autofill/core/common",
+ "//components/background_sync",
"//components/blocked_content",
"//components/content_settings/core/browser",
"//components/error_page/content/browser",
"//components/favicon/content",
"//components/network_session_configurator/common",
"//components/network_time",
+ "//components/no_state_prefetch/browser",
"//components/page_load_metrics/browser:browser",
"//components/prefs",
- "//components/prerender/browser",
"//components/security_interstitials/content:security_interstitial_page",
"//components/sessions:test_support",
"//components/signin/core/browser",
"//components/site_isolation",
"//components/strings",
+ "//components/subresource_filter/content/browser",
"//components/translate/content/browser",
"//components/translate/content/browser:test_support",
"//components/ukm:test_support",
@@ -124,11 +132,13 @@ test("weblayer_browsertests") {
"//testing/gtest",
"//ui/base",
"//ui/gfx:test_support",
+ "//weblayer:resources",
"//weblayer/shell:weblayer_shell_lib",
]
sources = [
"../browser/autofill_browsertest.cc",
+ "../browser/background_sync/background_sync_browsertest.cc",
"../browser/client_hints_browsertest.cc",
"../browser/content_settings_browsertest.cc",
"../browser/cookie_manager_browsertest.cc",
@@ -142,6 +152,7 @@ test("weblayer_browsertests") {
"../browser/js_communication/web_message_browsertest.cc",
"../browser/navigation_browsertest.cc",
"../browser/navigation_error_navigation_throttle_browsertest.cc",
+ "../browser/new_tab_delegate_browsertest.cc",
"../browser/no_state_prefetch/no_state_prefetch_browsertest.cc",
"../browser/page_load_metrics_browsertest.cc",
"../browser/popup_blocker_browsertest.cc",
diff --git a/chromium/weblayer/weblayer_module.gni b/chromium/weblayer/weblayer_module.gni
new file mode 100644
index 00000000000..98004e72a4f
--- /dev/null
+++ b/chromium/weblayer/weblayer_module.gni
@@ -0,0 +1,9 @@
+# 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.
+
+weblayer_module_desc = {
+ name = "weblayer"
+ android_manifest = "//weblayer/browser/java/AndroidManifest_monochrome.xml"
+ supports_isolated_split = true
+}
diff --git a/chromium/weblayer/weblayer_resources.grd b/chromium/weblayer/weblayer_resources.grd
index ded50bbd0d4..5bcd0872028 100644
--- a/chromium/weblayer/weblayer_resources.grd
+++ b/chromium/weblayer/weblayer_resources.grd
@@ -12,6 +12,8 @@
<include name="IDR_WEBLAYER_INTERNALS_HTML" file="browser/resources/weblayer_internals/weblayer_internals.html" flattenhtml="true" allowexternalscript="true" type="BINDATA" />
<include name="IDR_WEBLAYER_INTERNALS_JS" file="browser/resources/weblayer_internals/weblayer_internals.js" flattenhtml="true" type="BINDATA" />
<include name="IDR_WEBLAYER_INTERNALS_MOJO_JS" file="${root_gen_dir}/weblayer/browser/webui/weblayer_internals.mojom-lite.js" use_base_dir="false" type="BINDATA" />
+ <include name="IDR_SUBRESOURCE_FILTER_UNINDEXED_RULESET" file="../third_party/subresource-filter-ruleset/data/UnindexedRules" type="BINDATA" compress="brotli" />
+ <include name="IDR_SUBRESOURCE_FILTER_UNINDEXED_RULESET_MANIFEST_JSON" file="../third_party/subresource-filter-ruleset/manifest.json" type="BINDATA" />
</includes>
</release>
</grit>