summaryrefslogtreecommitdiff
path: root/chromium/chrome/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/chrome/renderer')
-rw-r--r--chromium/chrome/renderer/BUILD.gn50
-rw-r--r--chromium/chrome/renderer/DEPS1
-rw-r--r--chromium/chrome/renderer/autofill/autofill_renderer_browsertest.cc3
-rw-r--r--chromium/chrome/renderer/autofill/form_autocomplete_browsertest.cc7
-rw-r--r--chromium/chrome/renderer/autofill/password_autofill_agent_browsertest.cc79
-rw-r--r--chromium/chrome/renderer/browser_exposed_renderer_interfaces.cc19
-rw-r--r--chromium/chrome/renderer/chrome_content_renderer_client.cc37
-rw-r--r--chromium/chrome/renderer/chrome_content_renderer_client.h3
-rw-r--r--chromium/chrome/renderer/chrome_content_renderer_client_browsertest.cc5
-rw-r--r--chromium/chrome/renderer/chrome_content_renderer_client_unittest.cc22
-rw-r--r--chromium/chrome/renderer/chrome_content_settings_agent_delegate.cc3
-rw-r--r--chromium/chrome/renderer/chrome_content_settings_agent_delegate.h3
-rw-r--r--chromium/chrome/renderer/chrome_render_frame_observer.cc302
-rw-r--r--chromium/chrome/renderer/chrome_render_frame_observer.h15
-rw-r--r--chromium/chrome/renderer/extensions/cast_streaming_native_handler.cc844
-rw-r--r--chromium/chrome/renderer/extensions/cast_streaming_native_handler.h127
-rw-r--r--chromium/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc21
-rw-r--r--chromium/chrome/renderer/extensions/chrome_extensions_renderer_client.cc2
-rw-r--r--chromium/chrome/renderer/extensions/platform_keys_natives.cc50
-rw-r--r--chromium/chrome/renderer/instant_restricted_id_cache.h2
-rw-r--r--chromium/chrome/renderer/lite_video/DEPS3
-rw-r--r--chromium/chrome/renderer/lite_video/OWNERS3
-rw-r--r--chromium/chrome/renderer/lite_video/lite_video_hint_agent.cc99
-rw-r--r--chromium/chrome/renderer/lite_video/lite_video_hint_agent.h94
-rw-r--r--chromium/chrome/renderer/lite_video/lite_video_hint_agent_browsertest.cc236
-rw-r--r--chromium/chrome/renderer/lite_video/lite_video_url_loader_throttle.cc121
-rw-r--r--chromium/chrome/renderer/lite_video/lite_video_url_loader_throttle.h56
-rw-r--r--chromium/chrome/renderer/lite_video/lite_video_util.cc17
-rw-r--r--chromium/chrome/renderer/lite_video/lite_video_util.h15
-rw-r--r--chromium/chrome/renderer/media/OWNERS4
-rw-r--r--chromium/chrome/renderer/media/cast_ipc_dispatcher.cc147
-rw-r--r--chromium/chrome/renderer/media/cast_ipc_dispatcher.h75
-rw-r--r--chromium/chrome/renderer/media/cast_ipc_dispatcher_unittest.cc64
-rw-r--r--chromium/chrome/renderer/media/cast_receiver_audio_valve.cc50
-rw-r--r--chromium/chrome/renderer/media/cast_receiver_audio_valve.h58
-rw-r--r--chromium/chrome/renderer/media/cast_receiver_session.cc184
-rw-r--r--chromium/chrome/renderer/media/cast_receiver_session.h77
-rw-r--r--chromium/chrome/renderer/media/cast_receiver_session_delegate.cc91
-rw-r--r--chromium/chrome/renderer/media/cast_receiver_session_delegate.h59
-rw-r--r--chromium/chrome/renderer/media/cast_rtp_stream.cc578
-rw-r--r--chromium/chrome/renderer/media/cast_rtp_stream.h95
-rw-r--r--chromium/chrome/renderer/media/cast_session.cc136
-rw-r--r--chromium/chrome/renderer/media/cast_session.h116
-rw-r--r--chromium/chrome/renderer/media/cast_session_browsertest.cc30
-rw-r--r--chromium/chrome/renderer/media/cast_session_delegate.cc336
-rw-r--r--chromium/chrome/renderer/media/cast_session_delegate.h156
-rw-r--r--chromium/chrome/renderer/media/cast_threads.cc24
-rw-r--r--chromium/chrome/renderer/media/cast_threads.h37
-rw-r--r--chromium/chrome/renderer/media/cast_transport_ipc.cc186
-rw-r--r--chromium/chrome/renderer/media/cast_transport_ipc.h91
-rw-r--r--chromium/chrome/renderer/media/cast_udp_transport.cc33
-rw-r--r--chromium/chrome/renderer/media/cast_udp_transport.h46
-rw-r--r--chromium/chrome/renderer/media/chrome_speech_recognition_client.cc187
-rw-r--r--chromium/chrome/renderer/media/chrome_speech_recognition_client.h73
-rw-r--r--chromium/chrome/renderer/media/media_feeds.cc9
-rw-r--r--chromium/chrome/renderer/media/webrtc_logging_agent_impl.cc1
-rw-r--r--chromium/chrome/renderer/net/net_error_helper.cc32
-rw-r--r--chromium/chrome/renderer/net/net_error_helper.h8
-rw-r--r--chromium/chrome/renderer/net/net_error_helper_core.cc15
-rw-r--r--chromium/chrome/renderer/net/net_error_helper_core.h4
-rw-r--r--chromium/chrome/renderer/net/net_error_helper_core_unittest.cc35
-rw-r--r--chromium/chrome/renderer/performance_manager/OWNERS2
-rw-r--r--chromium/chrome/renderer/plugins/chrome_plugin_placeholder.cc6
-rw-r--r--chromium/chrome/renderer/plugins/chrome_plugin_placeholder.h4
-rw-r--r--chromium/chrome/renderer/prerender/prerender_helper.cc27
-rw-r--r--chromium/chrome/renderer/prerender/prerender_helper.h14
-rw-r--r--chromium/chrome/renderer/prerender/prerenderer_client.cc3
-rw-r--r--chromium/chrome/renderer/previews/resource_loading_hints_agent.cc43
-rw-r--r--chromium/chrome/renderer/previews/resource_loading_hints_agent.h13
-rw-r--r--chromium/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc12
-rw-r--r--chromium/chrome/renderer/resources/default_100_percent/common/sadplugin.pngbin238 -> 0 bytes
-rw-r--r--chromium/chrome/renderer/resources/default_100_percent/common/webview-crash.pngbin153 -> 0 bytes
-rw-r--r--chromium/chrome/renderer/resources/default_200_percent/common/sadplugin.pngbin321 -> 0 bytes
-rw-r--r--chromium/chrome/renderer/resources/default_200_percent/common/webview-crash.pngbin187 -> 0 bytes
-rw-r--r--chromium/chrome/renderer/resources/extensions/cast_streaming_receiver_session_custom_bindings.js15
-rw-r--r--chromium/chrome/renderer/resources/extensions/cast_streaming_rtp_stream_custom_bindings.js40
-rw-r--r--chromium/chrome/renderer/resources/extensions/cast_streaming_session_custom_bindings.js15
-rw-r--r--chromium/chrome/renderer/resources/extensions/cast_streaming_udp_transport_custom_bindings.js23
-rw-r--r--chromium/chrome/renderer/resources/extensions/chromeos_tts_stream_bindings.js19
-rw-r--r--chromium/chrome/renderer/resources/extensions/media_router_bindings.js33
-rw-r--r--chromium/chrome/renderer/resources/extensions/platform_keys/get_public_key.js36
-rw-r--r--chromium/chrome/renderer/resources/extensions/platform_keys/internal_api.js3
-rw-r--r--chromium/chrome/renderer/resources/extensions/platform_keys_custom_bindings.js18
-rw-r--r--chromium/chrome/renderer/resources/renderer_resources.grd11
-rw-r--r--chromium/chrome/renderer/safe_browsing/DEPS3
-rw-r--r--chromium/chrome/renderer/safe_browsing/feature_extractor_clock.cc15
-rw-r--r--chromium/chrome/renderer/safe_browsing/feature_extractor_clock.h30
-rw-r--r--chromium/chrome/renderer/safe_browsing/mock_feature_extractor_clock.cc14
-rw-r--r--chromium/chrome/renderer/safe_browsing/mock_feature_extractor_clock.h29
-rw-r--r--chromium/chrome/renderer/safe_browsing/phishing_classifier.cc131
-rw-r--r--chromium/chrome/renderer/safe_browsing/phishing_classifier.h27
-rw-r--r--chromium/chrome/renderer/safe_browsing/phishing_classifier_browsertest.cc33
-rw-r--r--chromium/chrome/renderer/safe_browsing/phishing_classifier_delegate.cc90
-rw-r--r--chromium/chrome/renderer/safe_browsing/phishing_classifier_delegate.h27
-rw-r--r--chromium/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc21
-rw-r--r--chromium/chrome/renderer/safe_browsing/phishing_dom_feature_extractor.cc66
-rw-r--r--chromium/chrome/renderer/safe_browsing/phishing_dom_feature_extractor.h17
-rw-r--r--chromium/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc48
-rw-r--r--chromium/chrome/renderer/safe_browsing/phishing_term_feature_extractor.cc45
-rw-r--r--chromium/chrome/renderer/safe_browsing/phishing_term_feature_extractor.h14
-rw-r--r--chromium/chrome/renderer/safe_browsing/phishing_term_feature_extractor_unittest.cc40
-rw-r--r--chromium/chrome/renderer/safe_browsing/phishing_url_feature_extractor.cc5
-rw-r--r--chromium/chrome/renderer/safe_browsing/phishing_url_feature_extractor_unittest.cc34
-rw-r--r--chromium/chrome/renderer/safe_browsing/scorer.cc34
-rw-r--r--chromium/chrome/renderer/safe_browsing/scorer.h6
-rw-r--r--chromium/chrome/renderer/safe_browsing/scorer_unittest.cc74
-rw-r--r--chromium/chrome/renderer/searchbox/searchbox.cc3
-rw-r--r--chromium/chrome/renderer/searchbox/searchbox.h3
-rw-r--r--chromium/chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.cc4
-rw-r--r--chromium/chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.h4
-rw-r--r--chromium/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.cc73
-rw-r--r--chromium/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.h13
-rw-r--r--chromium/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle_unittest.cc2
-rw-r--r--chromium/chrome/renderer/url_loader_throttle_provider_impl.cc9
114 files changed, 1961 insertions, 4566 deletions
diff --git a/chromium/chrome/renderer/BUILD.gn b/chromium/chrome/renderer/BUILD.gn
index 2ea489762ef..22e0426b61a 100644
--- a/chromium/chrome/renderer/BUILD.gn
+++ b/chromium/chrome/renderer/BUILD.gn
@@ -37,7 +37,10 @@ grit("resources") {
"//url/mojom:url_mojom_origin_js",
]
if (is_chromeos) {
- deps += [ "//chromeos/services/ime/public/mojom:mojom_js" ]
+ deps += [
+ "//chromeos/services/ime/public/mojom:mojom_js",
+ "//chromeos/services/tts/public/mojom:mojom_js",
+ ]
}
}
@@ -57,6 +60,12 @@ static_library("renderer") {
"chrome_render_thread_observer.h",
"custom_menu_commands.h",
"instant_restricted_id_cache.h",
+ "lite_video/lite_video_hint_agent.cc",
+ "lite_video/lite_video_hint_agent.h",
+ "lite_video/lite_video_url_loader_throttle.cc",
+ "lite_video/lite_video_url_loader_throttle.h",
+ "lite_video/lite_video_util.cc",
+ "lite_video/lite_video_util.h",
"loadtimes_extension_bindings.cc",
"loadtimes_extension_bindings.h",
"media/chrome_key_systems.cc",
@@ -251,8 +260,6 @@ static_library("renderer") {
]
if (safe_browsing_mode == 1) {
sources += [
- "safe_browsing/feature_extractor_clock.cc",
- "safe_browsing/feature_extractor_clock.h",
"safe_browsing/features.cc",
"safe_browsing/features.h",
"safe_browsing/murmurhash3_util.cc",
@@ -311,26 +318,6 @@ static_library("renderer") {
"extensions/sync_file_system_custom_bindings.h",
"extensions/tabs_hooks_delegate.cc",
"extensions/tabs_hooks_delegate.h",
- "media/cast_ipc_dispatcher.cc",
- "media/cast_ipc_dispatcher.h",
- "media/cast_receiver_audio_valve.cc",
- "media/cast_receiver_audio_valve.h",
- "media/cast_receiver_session.cc",
- "media/cast_receiver_session.h",
- "media/cast_receiver_session_delegate.cc",
- "media/cast_receiver_session_delegate.h",
- "media/cast_rtp_stream.cc",
- "media/cast_rtp_stream.h",
- "media/cast_session.cc",
- "media/cast_session.h",
- "media/cast_session_delegate.cc",
- "media/cast_session_delegate.h",
- "media/cast_threads.cc",
- "media/cast_threads.h",
- "media/cast_transport_ipc.cc",
- "media/cast_transport_ipc.h",
- "media/cast_udp_transport.cc",
- "media/cast_udp_transport.h",
]
deps += [
# TODO(hclam): See crbug.com/298380 for details.
@@ -346,12 +333,6 @@ static_library("renderer") {
]
public_deps += [ "//ipc" ]
}
- if (enable_extensions) {
- sources += [
- "extensions/cast_streaming_native_handler.cc",
- "extensions/cast_streaming_native_handler.h",
- ]
- }
if (enable_spellcheck) {
deps += [ "//components/spellcheck/renderer:renderer" ]
}
@@ -432,7 +413,7 @@ static_library("renderer") {
]
}
- if (is_linux) {
+ if (is_chromeos) {
sources += [
"performance_manager/mechanisms/tcmalloc_tunables_impl.cc",
"performance_manager/mechanisms/tcmalloc_tunables_impl.h",
@@ -449,8 +430,6 @@ static_library("test_support") {
sources = [
"chrome_mock_render_thread.cc",
"chrome_mock_render_thread.h",
- "safe_browsing/mock_feature_extractor_clock.cc",
- "safe_browsing/mock_feature_extractor_clock.h",
"safe_browsing/test_utils.cc",
"safe_browsing/test_utils.h",
]
@@ -463,11 +442,4 @@ static_library("test_support") {
"//testing/gmock",
"//testing/gtest",
]
-
- if (is_android) {
- sources -= [
- "safe_browsing/mock_feature_extractor_clock.cc",
- "safe_browsing/mock_feature_extractor_clock.h",
- ]
- }
}
diff --git a/chromium/chrome/renderer/DEPS b/chromium/chrome/renderer/DEPS
index b07362408fd..76e46eb27a0 100644
--- a/chromium/chrome/renderer/DEPS
+++ b/chromium/chrome/renderer/DEPS
@@ -34,6 +34,7 @@ include_rules = [
"+components/password_manager/core/common",
"+components/pdf/renderer",
"+components/plugins/renderer",
+ "+components/prerender",
"+components/printing/common",
"+components/printing/renderer",
"+components/rappor/public/mojom",
diff --git a/chromium/chrome/renderer/autofill/autofill_renderer_browsertest.cc b/chromium/chrome/renderer/autofill/autofill_renderer_browsertest.cc
index f83951ee485..41fba40e3b5 100644
--- a/chromium/chrome/renderer/autofill/autofill_renderer_browsertest.cc
+++ b/chromium/chrome/renderer/autofill/autofill_renderer_browsertest.cc
@@ -119,9 +119,6 @@ class FakeContentAutofillDriver : public mojom::AutofillDriver {
void DidEndTextFieldEditing() override {}
- void SetDataList(const std::vector<base::string16>& values,
- const std::vector<base::string16>& labels) override {}
-
void SelectFieldOptionsDidChange(const autofill::FormData& form) override {}
// Records whether TextFieldDidChange() get called.
diff --git a/chromium/chrome/renderer/autofill/form_autocomplete_browsertest.cc b/chromium/chrome/renderer/autofill/form_autocomplete_browsertest.cc
index 4e49269be5d..56033d8077d 100644
--- a/chromium/chrome/renderer/autofill/form_autocomplete_browsertest.cc
+++ b/chromium/chrome/renderer/autofill/form_autocomplete_browsertest.cc
@@ -109,9 +109,6 @@ class FakeContentAutofillDriver : public mojom::AutofillDriver {
void DidEndTextFieldEditing() override {}
- void SetDataList(const std::vector<base::string16>& values,
- const std::vector<base::string16>& labels) override {}
-
void SelectFieldOptionsDidChange(const autofill::FormData& form) override {}
// Records whether FocusNoLongerOnForm() get called.
@@ -966,8 +963,8 @@ TEST_F(FormAutocompleteTest, FormSubmittedBySameDocumentNavigation) {
ExecuteJavaScriptForTests(hide_elements.c_str());
// Simulate same document navigation.
- autofill_agent_->form_tracker_for_testing()->DidCommitProvisionalLoad(
- true /*is_same_document_navigation*/, ui::PAGE_TRANSITION_LINK);
+ autofill_agent_->form_tracker_for_testing()
+ ->DidFinishSameDocumentNavigation();
base::RunLoop().RunUntilIdle();
VerifyReceivedAddressRendererMessages(
diff --git a/chromium/chrome/renderer/autofill/password_autofill_agent_browsertest.cc b/chromium/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
index 006032ba871..92de649dd28 100644
--- a/chromium/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
+++ b/chromium/chrome/renderer/autofill/password_autofill_agent_browsertest.cc
@@ -381,7 +381,7 @@ class PasswordAutofillAgentTest : public ChromeRenderViewTest {
// We need to set the origin so it matches the frame URL and the action so
// it matches the form action, otherwise we won't autocomplete.
- UpdateOriginForHTML(kFormHTML);
+ UpdateUrlForHTML(kFormHTML);
fill_data_.action = GURL("http://www.bidule.com");
LoadHTML(kFormHTML);
@@ -441,9 +441,9 @@ class PasswordAutofillAgentTest : public ChromeRenderViewTest {
switches::kShowAutofillSignatures);
}
- void UpdateOriginForHTML(const std::string& html) {
- std::string origin = "data:text/html;charset=utf-8," + html;
- fill_data_.origin = GURL(origin);
+ void UpdateUrlForHTML(const std::string& html) {
+ std::string url = "data:text/html;charset=utf-8," + html;
+ fill_data_.url = GURL(url);
}
void UpdateRendererIDs() {
@@ -769,10 +769,10 @@ class PasswordAutofillAgentTest : public ChromeRenderViewTest {
tracker->AjaxSucceeded();
}
- void FireDidCommitProvisionalLoad() {
+ void FireDidFinishSameDocumentNavigation() {
FormTracker* tracker = autofill_agent_->form_tracker_for_testing();
static_cast<content::RenderFrameObserver*>(tracker)
- ->DidCommitProvisionalLoad(true, ui::PAGE_TRANSITION_LINK);
+ ->DidFinishSameDocumentNavigation();
}
void ClearField(FormFieldData* field) {
@@ -832,7 +832,7 @@ TEST_F(PasswordAutofillAgentTest, InitialAutocompleteForEmptyAction) {
UpdateUsernameAndPasswordElements();
// Set the expected form origin and action URLs.
- UpdateOriginForHTML(kEmptyActionFormHTML);
+ UpdateUrlForHTML(kEmptyActionFormHTML);
fill_data_.action = GURL();
// Simulate the browser sending back the login info, it triggers the
@@ -1327,7 +1327,7 @@ TEST_F(PasswordAutofillAgentTest,
CreateScriptToRegisterListeners(kPasswordName, &password_event_checkers);
std::string html = std::string(kFormHTML) + events_registration_script;
LoadHTML(html.c_str());
- UpdateOriginForHTML(html);
+ UpdateUrlForHTML(html);
UpdateUsernameAndPasswordElements();
// Simulate the browser sending back the login info, it triggers the
@@ -1364,7 +1364,7 @@ TEST_F(PasswordAutofillAgentTest,
CreateScriptToRegisterListeners(kPasswordName, &event_checkers);
std::string html = std::string(kFormHTML) + events_registration_script;
LoadHTML(html.c_str());
- UpdateOriginForHTML(html);
+ UpdateUrlForHTML(html);
UpdateUsernameAndPasswordElements();
// Simulate the browser sending back the login info, it triggers the
@@ -1834,7 +1834,7 @@ TEST_F(PasswordAutofillAgentTest, TouchToFillClosed) {
// Reload the page and simulate fill.
LoadHTML(kFormHTML);
- UpdateOriginForHTML(kFormHTML);
+ UpdateUrlForHTML(kFormHTML);
UpdateUsernameAndPasswordElements();
SimulateOnFillPasswordForm(fill_data_);
@@ -1985,16 +1985,33 @@ TEST_F(PasswordAutofillAgentTest, ClickAndSelect) {
CheckTextFieldsDOMState(kAliceUsername, true, kAlicePassword, true);
}
+TEST_F(PasswordAutofillAgentTest,
+ NoPopupOnPasswordFieldWithoutSuggestionsByDefault) {
+ ClearUsernameAndPasswordFields();
+ UpdateRendererIDs();
+
+ // A call to InformNoSavedCredentials(should_show_popup_without_passwords) is
+ // what informs the agent whether it should show the popup even without
+ // suggestions. In this test, that call hasn't happened yet, so the popup
+ // should NOT show up without suggestions.
+
+ SimulateElementClick(kPasswordName);
+
+ EXPECT_CALL(fake_driver_, ShowPasswordSuggestions).Times(0);
+ base::RunLoop().RunUntilIdle();
+}
// With butter, passwords fields should always trigger the popup so the user can
// unlock account-stored suggestions from there.
TEST_F(PasswordAutofillAgentTest, ShowPopupOnPasswordFieldWithoutSuggestions) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(
- password_manager::features::kEnablePasswordsAccountStorage);
ClearUsernameAndPasswordFields();
UpdateRendererIDs();
+ // InformNoSavedCredentials(should_show_popup_without_passwords) tells the
+ // agent to show the popup even without suggestions.
+ password_autofill_agent_->InformNoSavedCredentials(
+ /*should_show_popup_without_passwords=*/true);
+
SimulateElementClick(kPasswordName);
EXPECT_CALL(fake_driver_, ShowPasswordSuggestions);
@@ -2004,12 +2021,14 @@ TEST_F(PasswordAutofillAgentTest, ShowPopupOnPasswordFieldWithoutSuggestions) {
// Before butter, passwords fields should never trigger the popup on password
// passwords fields without suggestions since it would not be helpful.
TEST_F(PasswordAutofillAgentTest, NoPopupOnPasswordFieldWithoutSuggestions) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndDisableFeature(
- password_manager::features::kEnablePasswordsAccountStorage);
ClearUsernameAndPasswordFields();
UpdateRendererIDs();
+ // InformNoSavedCredentials(should_show_popup_without_passwords) tells the
+ // agent NOT to show the popup without suggestions.
+ password_autofill_agent_->InformNoSavedCredentials(
+ /*should_show_popup_without_passwords=*/false);
+
SimulateElementClick(kPasswordName);
EXPECT_CALL(fake_driver_, ShowPasswordSuggestions).Times(0);
@@ -2454,7 +2473,7 @@ TEST_F(PasswordAutofillAgentTest, ShowPopupOnEmptyPasswordField) {
LoadHTML(kVisibleFormWithNoUsernameHTML);
UpdateOnlyPasswordElement();
fill_data_.username_field = FormFieldData();
- UpdateOriginForHTML(kVisibleFormWithNoUsernameHTML);
+ UpdateUrlForHTML(kVisibleFormWithNoUsernameHTML);
fill_data_.additional_logins.clear();
password_element_.SetValue("");
@@ -2479,7 +2498,7 @@ TEST_F(PasswordAutofillAgentTest, ShowPopupOnAutofilledPasswordField) {
LoadHTML(kVisibleFormWithNoUsernameHTML);
UpdateOnlyPasswordElement();
fill_data_.username_field = FormFieldData();
- UpdateOriginForHTML(kVisibleFormWithNoUsernameHTML);
+ UpdateUrlForHTML(kVisibleFormWithNoUsernameHTML);
fill_data_.additional_logins.clear();
password_element_.SetValue("");
@@ -2504,7 +2523,7 @@ TEST_F(PasswordAutofillAgentTest, NotShowPopupPasswordField) {
LoadHTML(kVisibleFormWithNoUsernameHTML);
UpdateOnlyPasswordElement();
fill_data_.username_field = FormFieldData();
- UpdateOriginForHTML(kVisibleFormWithNoUsernameHTML);
+ UpdateUrlForHTML(kVisibleFormWithNoUsernameHTML);
fill_data_.additional_logins.clear();
password_element_.SetValue("");
@@ -2669,7 +2688,7 @@ TEST_F(PasswordAutofillAgentTest, PasswordGenerationSupersedesAutofill) {
fill_data_.wait_for_username = true;
fill_data_.username_field = FormFieldData();
fill_data_.password_field.name = ASCIIToUTF16("new_password");
- UpdateOriginForHTML(kSignupFormHTML);
+ UpdateUrlForHTML(kSignupFormHTML);
SimulateOnFillPasswordForm(fill_data_);
// Simulate generation triggering.
@@ -2697,7 +2716,7 @@ TEST_F(PasswordAutofillAgentTest, PasswordGenerationSupersedesAutofill) {
// password.
TEST_F(PasswordAutofillAgentTest, FillSuggestionPasswordChangeForms) {
LoadHTML(kPasswordChangeFormHTML);
- UpdateOriginForHTML(kPasswordChangeFormHTML);
+ UpdateUrlForHTML(kPasswordChangeFormHTML);
UpdateUsernameAndPasswordElements();
// Simulate the browser sending the login info, but set |wait_for_username|
// to prevent the form from being immediately filled.
@@ -2722,7 +2741,7 @@ TEST_F(PasswordAutofillAgentTest, FillSuggestionPasswordChangeForms) {
TEST_F(PasswordAutofillAgentTest,
SuggestionsOnUsernameFieldOfChangePasswordForm) {
LoadHTML(kPasswordChangeFormHTML);
- UpdateOriginForHTML(kPasswordChangeFormHTML);
+ UpdateUrlForHTML(kPasswordChangeFormHTML);
UpdateUsernameAndPasswordElements();
ClearUsernameAndPasswordFields();
@@ -2739,7 +2758,7 @@ TEST_F(PasswordAutofillAgentTest,
TEST_F(PasswordAutofillAgentTest,
SuggestionsOnPasswordFieldOfChangePasswordForm) {
LoadHTML(kPasswordChangeFormHTML);
- UpdateOriginForHTML(kPasswordChangeFormHTML);
+ UpdateUrlForHTML(kPasswordChangeFormHTML);
UpdateUsernameAndPasswordElements();
ClearUsernameAndPasswordFields();
@@ -3193,7 +3212,7 @@ TEST_F(PasswordAutofillAgentTest,
password_element_ = control_elements[0].To<WebInputElement>();
}
- UpdateOriginForHTML(test_case.html_form);
+ UpdateUrlForHTML(test_case.html_form);
if (test_case.does_trigger_autocomplete_on_fill) {
// Prepare |fill_data_| to trigger autocomplete.
fill_data_.username_field.name =
@@ -3247,7 +3266,7 @@ TEST_F(PasswordAutofillAgentTest, ShowSuggestionForNonUsernameFieldForms) {
LoadHTML(kTwoNoUsernameFormsHTML);
fill_data_.username_field.name.clear();
fill_data_.username_field.value.clear();
- UpdateOriginForHTML(kTwoNoUsernameFormsHTML);
+ UpdateUrlForHTML(kTwoNoUsernameFormsHTML);
SimulateOnFillPasswordForm(fill_data_);
SimulateElementClick("password1");
@@ -3354,7 +3373,7 @@ TEST_F(PasswordAutofillAgentTest, SuggestPasswordFieldSignInForm) {
// only on this field.
TEST_F(PasswordAutofillAgentTest, SuggestMultiplePasswordFields) {
LoadHTML(kPasswordChangeFormHTML);
- UpdateOriginForHTML(kPasswordChangeFormHTML);
+ UpdateUrlForHTML(kPasswordChangeFormHTML);
UpdateUsernameAndPasswordElements();
// Simulate the browser sending back the login info.
@@ -3455,7 +3474,7 @@ TEST_F(PasswordAutofillAgentTest,
"form.parentNode.removeChild(form);";
ExecuteJavaScriptForTests(remove_form.c_str());
- FireDidCommitProvisionalLoad();
+ FireDidFinishSameDocumentNavigation();
ExpectSameDocumentNavigationWithUsernameAndPasswords(
renderer_id, std::string(), "random", std::string(),
@@ -3501,7 +3520,7 @@ TEST_F(PasswordAutofillAgentTest,
// between discovering a form and receving credentials from the browser process.
TEST_F(PasswordAutofillAgentTest, AutocompleteWhenPageUrlIsChanged) {
// Simulate that JavaScript changes url.
- fill_data_.origin = GURL(fill_data_.origin.possibly_invalid_spec() + "/path");
+ fill_data_.url = GURL(fill_data_.url.possibly_invalid_spec() + "/path");
SimulateOnFillPasswordForm(fill_data_);
@@ -3574,7 +3593,7 @@ TEST_F(PasswordAutofillAgentTest, ManualFallbackForSaving) {
TEST_F(PasswordAutofillAgentTest, ManualFallbackForSaving_PasswordChangeForm) {
LoadHTML(kPasswordChangeFormHTML);
- UpdateOriginForHTML(kPasswordChangeFormHTML);
+ UpdateUrlForHTML(kPasswordChangeFormHTML);
UpdateUsernameAndPasswordElements();
// No password to save yet - no fallback.
@@ -3686,7 +3705,7 @@ TEST_F(PasswordAutofillAgentTest, PSLMatchedPasswordIsNotAutofill) {
UpdateUsernameAndPasswordElements();
// Set the expected form origin and action URLs.
- UpdateOriginForHTML(kFormWithPrefilledUsernameHTML);
+ UpdateUrlForHTML(kFormWithPrefilledUsernameHTML);
// Add PSL matched credentials with username equal to prefilled one.
PasswordAndMetadata psl_credentials;
diff --git a/chromium/chrome/renderer/browser_exposed_renderer_interfaces.cc b/chromium/chrome/renderer/browser_exposed_renderer_interfaces.cc
index 7e668b98964..02b8ac4e26a 100644
--- a/chromium/chrome/renderer/browser_exposed_renderer_interfaces.cc
+++ b/chromium/chrome/renderer/browser_exposed_renderer_interfaces.cc
@@ -12,27 +12,22 @@
#include "chrome/renderer/chrome_content_renderer_client.h"
#include "chrome/renderer/chrome_render_thread_observer.h"
#include "chrome/renderer/media/webrtc_logging_agent_impl.h"
-#include "components/safe_browsing/buildflags.h"
#include "components/spellcheck/spellcheck_buildflags.h"
#include "components/visitedlink/renderer/visitedlink_reader.h"
#include "components/web_cache/renderer/web_cache_impl.h"
#include "mojo/public/cpp/bindings/binder_map.h"
-#if BUILDFLAG(FULL_SAFE_BROWSING)
-#include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h"
-#endif
-
#if BUILDFLAG(ENABLE_SPELLCHECK)
#include "components/spellcheck/renderer/spellcheck.h"
#endif
-#if defined(OS_LINUX)
+#if defined(OS_CHROMEOS)
#include "base/allocator/buildflags.h"
#if BUILDFLAG(USE_TCMALLOC)
#include "chrome/common/performance_manager/mojom/tcmalloc.mojom.h"
#include "chrome/renderer/performance_manager/mechanisms/tcmalloc_tunables_impl.h"
#endif // BUILDFLAG(USE_TCMALLOC)
-#endif // defined(OS_LINUX)
+#endif // defined(OS_CHROMEOS)
namespace {
@@ -67,20 +62,14 @@ void ExposeChromeRendererInterfacesToBrowser(
binders->Add(base::BindRepeating(&BindWebRTCLoggingAgent, client),
base::SequencedTaskRunnerHandle::Get());
-#if BUILDFLAG(FULL_SAFE_BROWSING)
- binders->Add(
- base::BindRepeating(&safe_browsing::PhishingClassifierFilter::Create),
- base::SequencedTaskRunnerHandle::Get());
-#endif
-
-#if defined(OS_LINUX)
+#if defined(OS_CHROMEOS)
#if BUILDFLAG(USE_TCMALLOC)
binders->Add(
base::BindRepeating(
&performance_manager::mechanism::TcmallocTunablesImpl::Create),
base::SequencedTaskRunnerHandle::Get());
#endif // BUILDFLAG(USE_TCMALLOC)
-#endif // defined(OS_LINUX)
+#endif // defined(OS_CHROMEOS)
#if BUILDFLAG(ENABLE_SPELLCHECK)
binders->Add(base::BindRepeating(&BindSpellChecker, client),
diff --git a/chromium/chrome/renderer/chrome_content_renderer_client.cc b/chromium/chrome/renderer/chrome_content_renderer_client.cc
index c1d92ae00fe..35542225d86 100644
--- a/chromium/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chromium/chrome/renderer/chrome_content_renderer_client.cc
@@ -34,11 +34,11 @@
#include "chrome/common/crash_keys.h"
#include "chrome/common/pdf_util.h"
#include "chrome/common/pepper_permission_util.h"
-#include "chrome/common/prerender_types.h"
#include "chrome/common/prerender_url_loader_throttle.h"
+#include "chrome/common/privacy_budget/privacy_budget_settings_provider.h"
#include "chrome/common/profiler/thread_profiler.h"
#include "chrome/common/render_messages.h"
-#include "chrome/common/secure_origin_whitelist.h"
+#include "chrome/common/secure_origin_allowlist.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/chromium_strings.h"
#include "chrome/grit/generated_resources.h"
@@ -48,6 +48,8 @@
#include "chrome/renderer/chrome_content_settings_agent_delegate.h"
#include "chrome/renderer/chrome_render_frame_observer.h"
#include "chrome/renderer/chrome_render_thread_observer.h"
+#include "chrome/renderer/lite_video/lite_video_hint_agent.h"
+#include "chrome/renderer/lite_video/lite_video_util.h"
#include "chrome/renderer/loadtimes_extension_bindings.h"
#include "chrome/renderer/media/flash_embed_rewrite.h"
#include "chrome/renderer/media/webrtc_logging_agent_impl.h"
@@ -83,10 +85,12 @@
#include "components/dom_distiller/core/url_constants.h"
#include "components/error_page/common/error.h"
#include "components/error_page/common/localized_error.h"
+#include "components/grit/components_scaled_resources.h"
#include "components/network_hints/renderer/web_prescient_networking_impl.h"
#include "components/page_load_metrics/renderer/metrics_render_frame_observer.h"
#include "components/paint_preview/buildflags/buildflags.h"
#include "components/pdf/renderer/pepper_pdf_host.h"
+#include "components/prerender/common/prerender_types.mojom.h"
#include "components/safe_browsing/buildflags.h"
#include "components/safe_browsing/content/renderer/threat_dom_details.h"
#include "components/spellcheck/spellcheck_buildflags.h"
@@ -126,6 +130,7 @@
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-shared.h"
#include "third_party/blink/public/mojom/page/page_visibility_state.mojom.h"
#include "third_party/blink/public/platform/platform.h"
@@ -338,6 +343,9 @@ ChromeContentRendererClient::ChromeContentRendererClient()
for (const char* origin : kPredefinedAllowedCameraDeviceOrigins)
allowed_camera_device_origins_.insert(origin);
#endif
+
+ blink::IdentifiabilityStudySettings::SetGlobalProvider(
+ std::make_unique<PrivacyBudgetSettingsProvider>());
}
ChromeContentRendererClient::~ChromeContentRendererClient() {}
@@ -443,7 +451,7 @@ void ChromeContentRendererClient::RenderThreadStarted() {
}
for (auto& scheme :
- secure_origin_whitelist::GetSchemesBypassingSecureContextCheck()) {
+ secure_origin_allowlist::GetSchemesBypassingSecureContextCheck()) {
WebSecurityPolicy::AddSchemeToSecureContextSafelist(
WebString::FromASCII(scheme));
}
@@ -546,9 +554,9 @@ void ChromeContentRendererClient::RenderFrameCreated(
}
}
- // Set up a mojo service to test if this page is a distiller page.
+ // Set up a render frame observer to test if this page is a distiller page.
new dom_distiller::DistillerJsRenderFrameObserver(
- render_frame, ISOLATED_WORLD_ID_CHROME_INTERNAL, registry);
+ render_frame, ISOLATED_WORLD_ID_CHROME_INTERNAL);
if (dom_distiller::ShouldStartDistillabilityService()) {
// Create DistillabilityAgent to send distillability updates to
@@ -601,10 +609,13 @@ void ChromeContentRendererClient::RenderFrameCreated(
render_frame, subresource_filter_ruleset_dealer_.get(),
std::move(ad_resource_tracker));
}
- if (render_frame->IsMainFrame()) {
- new previews::ResourceLoadingHintsAgent(
- render_frame_observer->associated_interfaces(), render_frame);
- }
+
+ if (lite_video::IsLiteVideoEnabled())
+ new lite_video::LiteVideoHintAgent(render_frame);
+
+ new previews::ResourceLoadingHintsAgent(
+ render_frame_observer->associated_interfaces(), render_frame);
+
if (translate::IsSubFrameTranslationEnabled()) {
new translate::PerFrameTranslateAgent(
render_frame, ISOLATED_WORLD_ID_TRANSLATE, associated_interfaces);
@@ -1332,7 +1343,7 @@ bool ChromeContentRendererClient::IsPrefetchOnly(
content::RenderFrame* render_frame,
const blink::WebURLRequest& request) {
return prerender::PrerenderHelper::GetPrerenderMode(render_frame) ==
- prerender::PREFETCH_ONLY;
+ prerender::mojom::PrerenderMode::kPrefetchOnly;
}
uint64_t ChromeContentRendererClient::VisitedLinkHash(const char* canonical_url,
@@ -1438,8 +1449,10 @@ ChromeContentRendererClient::CreateWorkerContentSettingsClient(
#if !defined(OS_ANDROID)
std::unique_ptr<media::SpeechRecognitionClient>
ChromeContentRendererClient::CreateSpeechRecognitionClient(
- content::RenderFrame* render_frame) {
- return std::make_unique<ChromeSpeechRecognitionClient>(render_frame);
+ content::RenderFrame* render_frame,
+ media::SpeechRecognitionClient::OnReadyCallback callback) {
+ return std::make_unique<ChromeSpeechRecognitionClient>(render_frame,
+ std::move(callback));
}
#endif
diff --git a/chromium/chrome/renderer/chrome_content_renderer_client.h b/chromium/chrome/renderer/chrome_content_renderer_client.h
index 416b7a8f3ba..ea214daadf1 100644
--- a/chromium/chrome/renderer/chrome_content_renderer_client.h
+++ b/chromium/chrome/renderer/chrome_content_renderer_client.h
@@ -151,7 +151,8 @@ class ChromeContentRendererClient
content::RenderFrame* render_frame) override;
#if !defined(OS_ANDROID)
std::unique_ptr<media::SpeechRecognitionClient> CreateSpeechRecognitionClient(
- content::RenderFrame* render_frame) override;
+ content::RenderFrame* render_frame,
+ media::SpeechRecognitionClient::OnReadyCallback callback) override;
#endif
void AddSupportedKeySystems(
std::vector<std::unique_ptr<::media::KeySystemProperties>>* key_systems)
diff --git a/chromium/chrome/renderer/chrome_content_renderer_client_browsertest.cc b/chromium/chrome/renderer/chrome_content_renderer_client_browsertest.cc
index ae1c0079376..8df56778bfb 100644
--- a/chromium/chrome/renderer/chrome_content_renderer_client_browsertest.cc
+++ b/chromium/chrome/renderer/chrome_content_renderer_client_browsertest.cc
@@ -11,7 +11,6 @@
#include "base/command_line.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
@@ -136,8 +135,8 @@ class ChromeContentRendererClientBrowserTest :
EXPECT_EQ(request.relative_url, GetParam().expected_url)
<< "URL is wrong for test " << GetParam().name;
- base::PostTask(FROM_HERE, {content::BrowserThread::UI},
- message_runner_->QuitClosure());
+ content::GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, message_runner_->QuitClosure());
}
void WaitForYouTubeRequest() {
diff --git a/chromium/chrome/renderer/chrome_content_renderer_client_unittest.cc b/chromium/chrome/renderer/chrome_content_renderer_client_unittest.cc
index 3025593fd2a..7974a07b096 100644
--- a/chromium/chrome/renderer/chrome_content_renderer_client_unittest.cc
+++ b/chromium/chrome/renderer/chrome_content_renderer_client_unittest.cc
@@ -16,12 +16,14 @@
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "build/build_config.h"
+#include "chrome/common/privacy_budget/scoped_privacy_budget_config.h"
#include "chrome/renderer/searchbox/search_bouncer.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/webplugininfo.h"
#include "extensions/buildflags/buildflags.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h"
#include "third_party/blink/public/platform/web_string.h"
#include "third_party/blink/public/platform/web_url_response.h"
#include "url/gurl.h"
@@ -232,6 +234,8 @@ TEST_F(ChromeContentRendererClientTest, NaClRestriction) {
// SearchBouncer doesn't exist on Android.
#if !defined(OS_ANDROID)
TEST_F(ChromeContentRendererClientTest, ShouldSuppressErrorPage) {
+ test::ScopedPrivacyBudgetConfig config(
+ test::ScopedPrivacyBudgetConfig::kDisable);
ChromeContentRendererClient client;
SearchBouncer::GetInstance()->SetNewTabPageURL(GURL("http://example.com/n"));
EXPECT_FALSE(client.ShouldSuppressErrorPage(
@@ -242,6 +246,8 @@ TEST_F(ChromeContentRendererClientTest, ShouldSuppressErrorPage) {
}
TEST_F(ChromeContentRendererClientTest, ShouldTrackUseCounter) {
+ test::ScopedPrivacyBudgetConfig config(
+ test::ScopedPrivacyBudgetConfig::kDisable);
ChromeContentRendererClient client;
SearchBouncer::GetInstance()->SetNewTabPageURL(GURL("http://example.com/n"));
EXPECT_TRUE(client.ShouldTrackUseCounter(GURL("http://example.com")));
@@ -249,3 +255,19 @@ TEST_F(ChromeContentRendererClientTest, ShouldTrackUseCounter) {
SearchBouncer::GetInstance()->SetNewTabPageURL(GURL::EmptyGURL());
}
#endif
+
+TEST_F(ChromeContentRendererClientTest, IdentifiabilityStudySettingsDisabled) {
+ test::ScopedPrivacyBudgetConfig::Parameters parameters;
+ parameters.enabled = false;
+ test::ScopedPrivacyBudgetConfig config(parameters);
+ ChromeContentRendererClient client;
+ EXPECT_FALSE(blink::IdentifiabilityStudySettings::Get()->IsActive());
+}
+
+TEST_F(ChromeContentRendererClientTest, IdentifiabilityStudySettingsEnabled) {
+ test::ScopedPrivacyBudgetConfig::Parameters parameters;
+ parameters.enabled = true;
+ test::ScopedPrivacyBudgetConfig config(parameters);
+ ChromeContentRendererClient client;
+ EXPECT_TRUE(blink::IdentifiabilityStudySettings::Get()->IsActive());
+}
diff --git a/chromium/chrome/renderer/chrome_content_settings_agent_delegate.cc b/chromium/chrome/renderer/chrome_content_settings_agent_delegate.cc
index 77187dca7f9..0c4dcfb794b 100644
--- a/chromium/chrome/renderer/chrome_content_settings_agent_delegate.cc
+++ b/chromium/chrome/renderer/chrome_content_settings_agent_delegate.cc
@@ -152,9 +152,8 @@ bool ChromeContentSettingsAgentDelegate::OnMessageReceived(
}
void ChromeContentSettingsAgentDelegate::DidCommitProvisionalLoad(
- bool is_same_document_navigation,
ui::PageTransition transition) {
- if (render_frame()->GetWebFrame()->Parent() || is_same_document_navigation)
+ if (render_frame()->GetWebFrame()->Parent())
return;
temporarily_allowed_plugins_.clear();
diff --git a/chromium/chrome/renderer/chrome_content_settings_agent_delegate.h b/chromium/chrome/renderer/chrome_content_settings_agent_delegate.h
index cfc027255b3..b56cc2cd8ef 100644
--- a/chromium/chrome/renderer/chrome_content_settings_agent_delegate.h
+++ b/chromium/chrome/renderer/chrome_content_settings_agent_delegate.h
@@ -49,8 +49,7 @@ class ChromeContentSettingsAgentDelegate
// RenderFrameObserver:
bool OnMessageReceived(const IPC::Message& message) override;
- void DidCommitProvisionalLoad(bool is_same_document_navigation,
- ui::PageTransition transition) override;
+ void DidCommitProvisionalLoad(ui::PageTransition transition) override;
void OnDestruct() override;
void OnLoadBlockedPlugins(const std::string& identifier);
diff --git a/chromium/chrome/renderer/chrome_render_frame_observer.cc b/chromium/chrome/renderer/chrome_render_frame_observer.cc
index ac6ba14b9a1..a545474a8a0 100644
--- a/chromium/chrome/renderer/chrome_render_frame_observer.cc
+++ b/chromium/chrome/renderer/chrome_render_frame_observer.cc
@@ -22,13 +22,13 @@
#include "chrome/common/chrome_isolated_world_ids.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/open_search_description_document_handler.mojom.h"
-#include "chrome/common/prerender_messages.h"
#include "chrome/common/render_messages.h"
#include "chrome/renderer/media/media_feeds.h"
#include "chrome/renderer/prerender/prerender_helper.h"
#include "chrome/renderer/web_apps.h"
#include "components/crash/core/common/crash_key.h"
#include "components/offline_pages/buildflags/buildflags.h"
+#include "components/prerender/common/prerender_messages.h"
#include "components/translate/content/renderer/translate_agent.h"
#include "components/translate/core/common/translate_util.h"
#include "components/web_cache/renderer/web_cache_impl.h"
@@ -130,11 +130,11 @@ ChromeRenderFrameObserver::ChromeRenderFrameObserver(
if (!render_frame->IsMainFrame())
return;
-#if BUILDFLAG(SAFE_BROWSING_CSD)
+#if BUILDFLAG(FULL_SAFE_BROWSING)
const base::CommandLine& command_line =
*base::CommandLine::ForCurrentProcess();
if (!command_line.HasSwitch(switches::kDisableClientSidePhishingDetection))
- SetClientSidePhishingDetection(true);
+ SetClientSidePhishingDetection();
#endif
if (!translate::IsSubFrameTranslationEnabled()) {
translate_agent_ =
@@ -193,10 +193,123 @@ bool ChromeRenderFrameObserver::OnMessageReceived(const IPC::Message& message) {
return handled;
}
+void ChromeRenderFrameObserver::ReadyToCommitNavigation(
+ WebDocumentLoader* document_loader) {
+ // Execute cache clear operations that were postponed until a navigation
+ // event (including tab reload).
+ if (render_frame()->IsMainFrame() && web_cache_impl_)
+ web_cache_impl_->ExecutePendingClearCache();
+
+ // Let translate_agent do any preparatory work for loading a URL.
+ if (!translate_agent_)
+ return;
+
+ translate_agent_->PrepareForUrl(
+ render_frame()->GetWebFrame()->GetDocument().Url());
+}
+
+void ChromeRenderFrameObserver::DidFinishLoad() {
+ WebLocalFrame* frame = render_frame()->GetWebFrame();
+ // Don't do anything for subframes.
+ if (frame->Parent())
+ return;
+
+ GURL osdd_url = frame->GetDocument().OpenSearchDescriptionURL();
+ if (!osdd_url.is_empty()) {
+ mojo::AssociatedRemote<chrome::mojom::OpenSearchDescriptionDocumentHandler>
+ osdd_handler;
+ render_frame()->GetRemoteAssociatedInterfaces()->GetInterface(
+ &osdd_handler);
+ osdd_handler->PageHasOpenSearchDescriptionDocument(
+ frame->GetDocument().Url(), osdd_url);
+ }
+}
+
+void ChromeRenderFrameObserver::DidCreateNewDocument() {
+#if BUILDFLAG(ENABLE_OFFLINE_PAGES)
+ DCHECK(render_frame());
+ if (!render_frame()->IsMainFrame())
+ return;
+
+ DCHECK(render_frame()->GetWebFrame());
+ blink::WebDocumentLoader* doc_loader =
+ render_frame()->GetWebFrame()->GetDocumentLoader();
+ DCHECK(doc_loader);
+
+ if (!doc_loader->HasBeenLoadedAsWebArchive())
+ return;
+
+ // Connect to Mojo service on browser to notify it of the page's archive
+ // properties.
+ mojo::AssociatedRemote<offline_pages::mojom::MhtmlPageNotifier>
+ mhtml_notifier;
+ render_frame()->GetRemoteAssociatedInterfaces()->GetInterface(
+ &mhtml_notifier);
+ DCHECK(mhtml_notifier);
+ blink::WebArchiveInfo info = doc_loader->GetArchiveInfo();
+
+ mhtml_notifier->NotifyMhtmlPageLoadAttempted(info.load_result, info.url,
+ info.date);
+#endif
+}
+
+void ChromeRenderFrameObserver::DidCommitProvisionalLoad(
+ ui::PageTransition transition) {
+ WebLocalFrame* frame = render_frame()->GetWebFrame();
+
+ // Don't do anything for subframes.
+ if (frame->Parent())
+ return;
+
+ static crash_reporter::CrashKeyString<8> view_count_key("view-count");
+ view_count_key.Set(
+ base::NumberToString(content::RenderView::GetRenderViewCount()));
+
+#if !defined(OS_ANDROID)
+ if (render_frame()->GetEnabledBindings() &
+ content::kWebUIBindingsPolicyMask) {
+ for (const auto& script : webui_javascript_)
+ render_frame()->ExecuteJavaScript(script);
+ webui_javascript_.clear();
+ }
+#endif
+}
+
+void ChromeRenderFrameObserver::DidClearWindowObject() {
+#if !defined(OS_ANDROID)
+ const base::CommandLine& command_line =
+ *base::CommandLine::ForCurrentProcess();
+ if (command_line.HasSwitch(switches::kInstantProcess))
+ SearchBoxExtension::Install(render_frame()->GetWebFrame());
+#endif // !defined(OS_ANDROID)
+}
+
+void ChromeRenderFrameObserver::DidMeaningfulLayout(
+ blink::WebMeaningfulLayout layout_type) {
+ // Don't do any work for subframes.
+ if (!render_frame()->IsMainFrame())
+ return;
+
+ switch (layout_type) {
+ case blink::WebMeaningfulLayout::kFinishedParsing:
+ CapturePageText(PRELIMINARY_CAPTURE);
+ break;
+ case blink::WebMeaningfulLayout::kFinishedLoading:
+ CapturePageText(FINAL_CAPTURE);
+ break;
+ default:
+ break;
+ }
+}
+
+void ChromeRenderFrameObserver::OnDestruct() {
+ delete this;
+}
+
void ChromeRenderFrameObserver::OnSetIsPrerendering(
- prerender::PrerenderMode mode,
+ prerender::mojom::PrerenderMode mode,
const std::string& histogram_prefix) {
- if (mode != prerender::NO_PRERENDER) {
+ if (mode != prerender::mojom::PrerenderMode::kNoPrerender) {
// If the PrerenderHelper for this frame already exists, don't create it. It
// can already be created for subframes during handling of
// RenderFrameCreated, if the parent frame was prerendering at time of
@@ -210,14 +323,17 @@ void ChromeRenderFrameObserver::OnSetIsPrerendering(
}
}
-void ChromeRenderFrameObserver::RequestReloadImageForContextNode() {
- WebLocalFrame* frame = render_frame()->GetWebFrame();
- // TODO(dglazkov): This code is clearly in the wrong place. Need
- // to investigate what it is doing and fix (http://crbug.com/606164).
- WebNode context_node = frame->ContextMenuNode();
- if (!context_node.IsNull()) {
- frame->ReloadImage(context_node);
- }
+void ChromeRenderFrameObserver::SetWindowFeatures(
+ blink::mojom::WindowFeaturesPtr window_features) {
+ render_frame()->GetRenderView()->GetWebView()->SetWindowFeatures(
+ content::ConvertMojoWindowFeaturesToWebWindowFeatures(*window_features));
+}
+
+void ChromeRenderFrameObserver::ExecuteWebUIJavaScript(
+ const base::string16& javascript) {
+#if !defined(OS_ANDROID)
+ webui_javascript_.push_back(javascript);
+#endif
}
void ChromeRenderFrameObserver::RequestImageForContextNode(
@@ -294,6 +410,16 @@ void ChromeRenderFrameObserver::RequestImageForContextNode(
std::move(callback).Run(image_data, original_size, image_extension);
}
+void ChromeRenderFrameObserver::RequestReloadImageForContextNode() {
+ WebLocalFrame* frame = render_frame()->GetWebFrame();
+ // TODO(dglazkov): This code is clearly in the wrong place. Need
+ // to investigate what it is doing and fix (http://crbug.com/606164).
+ WebNode context_node = frame->ContextMenuNode();
+ if (!context_node.IsNull()) {
+ frame->ReloadImage(context_node);
+ }
+}
+
void ChromeRenderFrameObserver::GetWebApplicationInfo(
GetWebApplicationInfoCallback callback) {
WebLocalFrame* frame = render_frame()->GetWebFrame();
@@ -345,114 +471,17 @@ void ChromeRenderFrameObserver::GetMediaFeedURL(
std::move(callback).Run(MediaFeeds::GetMediaFeedURL(render_frame()));
}
-void ChromeRenderFrameObserver::SetClientSidePhishingDetection(
- bool enable_phishing_detection) {
-#if BUILDFLAG(SAFE_BROWSING_CSD)
- phishing_classifier_ =
- enable_phishing_detection
- ? safe_browsing::PhishingClassifierDelegate::Create(render_frame(),
- nullptr)
- : nullptr;
-#endif
-}
-
-void ChromeRenderFrameObserver::ExecuteWebUIJavaScript(
- const base::string16& javascript) {
-#if !defined(OS_ANDROID)
- webui_javascript_.push_back(javascript);
-#endif
-}
-
-void ChromeRenderFrameObserver::DidFinishLoad() {
- WebLocalFrame* frame = render_frame()->GetWebFrame();
- // Don't do anything for subframes.
- if (frame->Parent())
- return;
-
- GURL osdd_url = frame->GetDocument().OpenSearchDescriptionURL();
- if (!osdd_url.is_empty()) {
- mojo::AssociatedRemote<chrome::mojom::OpenSearchDescriptionDocumentHandler>
- osdd_handler;
- render_frame()->GetRemoteAssociatedInterfaces()->GetInterface(
- &osdd_handler);
- osdd_handler->PageHasOpenSearchDescriptionDocument(
- frame->GetDocument().Url(), osdd_url);
- }
-}
-
-void ChromeRenderFrameObserver::DidCreateNewDocument() {
-#if BUILDFLAG(ENABLE_OFFLINE_PAGES)
- DCHECK(render_frame());
- if (!render_frame()->IsMainFrame())
- return;
-
- DCHECK(render_frame()->GetWebFrame());
- blink::WebDocumentLoader* doc_loader =
- render_frame()->GetWebFrame()->GetDocumentLoader();
- DCHECK(doc_loader);
-
- if (!doc_loader->HasBeenLoadedAsWebArchive())
- return;
-
- // Connect to Mojo service on browser to notify it of the page's archive
- // properties.
- mojo::AssociatedRemote<offline_pages::mojom::MhtmlPageNotifier>
- mhtml_notifier;
- render_frame()->GetRemoteAssociatedInterfaces()->GetInterface(
- &mhtml_notifier);
- DCHECK(mhtml_notifier);
- blink::WebArchiveInfo info = doc_loader->GetArchiveInfo();
-
- mhtml_notifier->NotifyMhtmlPageLoadAttempted(info.load_result, info.url,
- info.date);
-#endif
-}
-
-void ChromeRenderFrameObserver::ReadyToCommitNavigation(
- WebDocumentLoader* document_loader) {
- // Execute cache clear operations that were postponed until a navigation
- // event (including tab reload).
- if (render_frame()->IsMainFrame() && web_cache_impl_)
- web_cache_impl_->ExecutePendingClearCache();
-
- // Let translate_agent do any preparatory work for loading a URL.
- if (!translate_agent_)
- return;
-
- translate_agent_->PrepareForUrl(
- render_frame()->GetWebFrame()->GetDocument().Url());
-}
-
-void ChromeRenderFrameObserver::DidCommitProvisionalLoad(
- bool is_same_document_navigation,
- ui::PageTransition transition) {
- WebLocalFrame* frame = render_frame()->GetWebFrame();
-
- // Don't do anything for subframes.
- if (frame->Parent())
- return;
-
- static crash_reporter::CrashKeyString<8> view_count_key("view-count");
- view_count_key.Set(
- base::NumberToString(content::RenderView::GetRenderViewCount()));
-
-#if !defined(OS_ANDROID)
- if (render_frame()->GetEnabledBindings() &
- content::kWebUIBindingsPolicyMask) {
- for (const auto& script : webui_javascript_)
- render_frame()->ExecuteJavaScript(script);
- webui_javascript_.clear();
- }
+void ChromeRenderFrameObserver::SetClientSidePhishingDetection() {
+#if BUILDFLAG(FULL_SAFE_BROWSING)
+ phishing_classifier_ = safe_browsing::PhishingClassifierDelegate::Create(
+ render_frame(), nullptr);
#endif
}
-void ChromeRenderFrameObserver::DidClearWindowObject() {
-#if !defined(OS_ANDROID)
- const base::CommandLine& command_line =
- *base::CommandLine::ForCurrentProcess();
- if (command_line.HasSwitch(switches::kInstantProcess))
- SearchBoxExtension::Install(render_frame()->GetWebFrame());
-#endif // !defined(OS_ANDROID)
+void ChromeRenderFrameObserver::OnRenderFrameObserverRequest(
+ mojo::PendingAssociatedReceiver<chrome::mojom::ChromeRenderFrame>
+ receiver) {
+ receivers_.Add(this, std::move(receiver));
}
void ChromeRenderFrameObserver::CapturePageText(TextCaptureType capture_type) {
@@ -479,7 +508,7 @@ void ChromeRenderFrameObserver::CapturePageText(TextCaptureType capture_type) {
// Don't capture contents unless there is either a translate agent or a
// phishing classifier to consume them.
-#if BUILDFLAG(SAFE_BROWSING_CSD)
+#if BUILDFLAG(FULL_SAFE_BROWSING)
if (!translate_agent_ && !phishing_classifier_)
return;
#else
@@ -509,7 +538,7 @@ void ChromeRenderFrameObserver::CapturePageText(TextCaptureType capture_type) {
TRACE_EVENT0("renderer", "ChromeRenderFrameObserver::CapturePageText");
-#if BUILDFLAG(SAFE_BROWSING_CSD)
+#if BUILDFLAG(FULL_SAFE_BROWSING)
// Will swap out the string.
if (phishing_classifier_)
phishing_classifier_->PageCaptured(&contents,
@@ -517,39 +546,6 @@ void ChromeRenderFrameObserver::CapturePageText(TextCaptureType capture_type) {
#endif
}
-void ChromeRenderFrameObserver::DidMeaningfulLayout(
- blink::WebMeaningfulLayout layout_type) {
- // Don't do any work for subframes.
- if (!render_frame()->IsMainFrame())
- return;
-
- switch (layout_type) {
- case blink::WebMeaningfulLayout::kFinishedParsing:
- CapturePageText(PRELIMINARY_CAPTURE);
- break;
- case blink::WebMeaningfulLayout::kFinishedLoading:
- CapturePageText(FINAL_CAPTURE);
- break;
- default:
- break;
- }
-}
-
-void ChromeRenderFrameObserver::OnDestruct() {
- delete this;
-}
-
-void ChromeRenderFrameObserver::OnRenderFrameObserverRequest(
- mojo::PendingAssociatedReceiver<chrome::mojom::ChromeRenderFrame>
- receiver) {
- receivers_.Add(this, std::move(receiver));
-}
-
-void ChromeRenderFrameObserver::SetWindowFeatures(
- blink::mojom::WindowFeaturesPtr window_features) {
- render_frame()->GetRenderView()->GetWebView()->SetWindowFeatures(
- content::ConvertMojoWindowFeaturesToWebWindowFeatures(*window_features));
-}
// static
bool ChromeRenderFrameObserver::NeedsDownscale(
diff --git a/chromium/chrome/renderer/chrome_render_frame_observer.h b/chromium/chrome/renderer/chrome_render_frame_observer.h
index a7257c75d0f..2680019005e 100644
--- a/chromium/chrome/renderer/chrome_render_frame_observer.h
+++ b/chromium/chrome/renderer/chrome_render_frame_observer.h
@@ -12,7 +12,7 @@
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "chrome/common/chrome_render_frame.mojom.h"
-#include "chrome/common/prerender_types.h"
+#include "components/prerender/common/prerender_types.mojom.h"
#include "components/safe_browsing/buildflags.h"
#include "content/public/renderer/render_frame_observer.h"
#include "mojo/public/cpp/bindings/associated_receiver_set.h"
@@ -73,14 +73,13 @@ class ChromeRenderFrameObserver : public content::RenderFrameObserver,
blink::WebDocumentLoader* document_loader) override;
void DidFinishLoad() override;
void DidCreateNewDocument() override;
- void DidCommitProvisionalLoad(bool is_same_document_navigation,
- ui::PageTransition transition) override;
+ void DidCommitProvisionalLoad(ui::PageTransition transition) override;
void DidClearWindowObject() override;
void DidMeaningfulLayout(blink::WebMeaningfulLayout layout_type) override;
void OnDestruct() override;
// IPC handlers
- void OnSetIsPrerendering(prerender::PrerenderMode mode,
+ void OnSetIsPrerendering(prerender::mojom::PrerenderMode mode,
const std::string& histogram_prefix);
// chrome::mojom::ChromeRenderFrame:
@@ -93,13 +92,15 @@ class ChromeRenderFrameObserver : public content::RenderFrameObserver,
chrome::mojom::ImageFormat image_format,
RequestImageForContextNodeCallback callback) override;
void RequestReloadImageForContextNode() override;
- void SetClientSidePhishingDetection(bool enable_phishing_detection) override;
void GetWebApplicationInfo(GetWebApplicationInfoCallback callback) override;
#if defined(OS_ANDROID)
void SetCCTClientHeader(const std::string& header) override;
#endif
void GetMediaFeedURL(GetMediaFeedURLCallback callback) override;
+ // Initialize a |phishing_classifier_delegate_|.
+ void SetClientSidePhishingDetection();
+
void OnRenderFrameObserverRequest(
mojo::PendingAssociatedReceiver<chrome::mojom::ChromeRenderFrame>
receiver);
@@ -130,7 +131,7 @@ class ChromeRenderFrameObserver : public content::RenderFrameObserver,
// Have the same lifetime as us.
translate::TranslateAgent* translate_agent_;
-#if BUILDFLAG(SAFE_BROWSING_CSD)
+#if BUILDFLAG(FULL_SAFE_BROWSING)
safe_browsing::PhishingClassifierDelegate* phishing_classifier_ = nullptr;
#endif
@@ -150,4 +151,4 @@ class ChromeRenderFrameObserver : public content::RenderFrameObserver,
DISALLOW_COPY_AND_ASSIGN(ChromeRenderFrameObserver);
};
-#endif // CHROME_RENDERER_CHROME_RENDER_FRAME_OBSERVER_H_ \ No newline at end of file
+#endif // CHROME_RENDERER_CHROME_RENDER_FRAME_OBSERVER_H_
diff --git a/chromium/chrome/renderer/extensions/cast_streaming_native_handler.cc b/chromium/chrome/renderer/extensions/cast_streaming_native_handler.cc
deleted file mode 100644
index 1fb0aa4b760..00000000000
--- a/chromium/chrome/renderer/extensions/cast_streaming_native_handler.cc
+++ /dev/null
@@ -1,844 +0,0 @@
-// Copyright 2013 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 "chrome/renderer/extensions/cast_streaming_native_handler.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <algorithm>
-#include <functional>
-#include <iterator>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/memory/scoped_refptr.h"
-#include "base/single_thread_task_runner.h"
-#include "base/stl_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/system/sys_info.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/values.h"
-#include "chrome/common/extensions/api/cast_streaming_receiver_session.h"
-#include "chrome/common/extensions/api/cast_streaming_rtp_stream.h"
-#include "chrome/common/extensions/api/cast_streaming_udp_transport.h"
-#include "chrome/renderer/media/cast_receiver_session.h"
-#include "chrome/renderer/media/cast_rtp_stream.h"
-#include "chrome/renderer/media/cast_session.h"
-#include "chrome/renderer/media/cast_udp_transport.h"
-#include "content/public/renderer/v8_value_converter.h"
-#include "extensions/common/extension.h"
-#include "extensions/renderer/native_extension_bindings_system.h"
-#include "extensions/renderer/script_context.h"
-#include "media/base/audio_parameters.h"
-#include "media/base/limits.h"
-#include "net/base/host_port_pair.h"
-#include "net/base/ip_address.h"
-#include "third_party/blink/public/platform/web_media_stream.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
-#include "third_party/blink/public/platform/web_url.h"
-#include "third_party/blink/public/web/web_dom_media_stream_track.h"
-#include "third_party/blink/public/web/web_local_frame.h"
-#include "url/gurl.h"
-
-using content::V8ValueConverter;
-using media::cast::FrameSenderConfig;
-
-// Extension types.
-using extensions::api::cast_streaming_receiver_session::RtpReceiverParams;
-using extensions::api::cast_streaming_rtp_stream::RtpParams;
-using extensions::api::cast_streaming_rtp_stream::RtpPayloadParams;
-using extensions::api::cast_streaming_udp_transport::IPEndPoint;
-
-namespace extensions {
-
-namespace {
-
-constexpr char kInvalidAesIvMask[] = "Invalid value for AES IV mask";
-constexpr char kInvalidAesKey[] = "Invalid value for AES key";
-constexpr char kInvalidDestination[] = "Invalid destination";
-constexpr char kInvalidRtpParams[] = "Invalid value for RTP params";
-constexpr char kInvalidStreamArgs[] = "Invalid stream arguments";
-constexpr char kRtpStreamNotFound[] = "The RTP stream cannot be found";
-constexpr char kUdpTransportNotFound[] = "The UDP transport cannot be found";
-constexpr char kUnableToConvertArgs[] = "Unable to convert arguments";
-constexpr char kUnableToConvertParams[] = "Unable to convert params";
-constexpr char kCodecNameOpus[] = "OPUS";
-constexpr char kCodecNameVp8[] = "VP8";
-constexpr char kCodecNameH264[] = "H264";
-constexpr char kCodecNameRemoteAudio[] = "REMOTE_AUDIO";
-constexpr char kCodecNameRemoteVideo[] = "REMOTE_VIDEO";
-
-// To convert from kilobits per second to bits per second.
-constexpr int kBitsPerKilobit = 1000;
-
-bool HexDecode(const std::string& input, std::string* output) {
- DCHECK(output->empty());
- if (!base::HexStringToString(input, output)) {
- output->clear();
- return false;
- }
- return true;
-}
-
-int NumberOfEncodeThreads() {
- // Do not saturate CPU utilization just for encoding. On a lower-end system
- // with only 1 or 2 cores, use only one thread for encoding. On systems with
- // more cores, allow half of the cores to be used for encoding.
- return std::min(8, (base::SysInfo::NumberOfProcessors() + 1) / 2);
-}
-
-bool ToFrameSenderConfigOrThrow(v8::Isolate* isolate,
- const RtpPayloadParams& ext_params,
- FrameSenderConfig* config) {
- config->sender_ssrc = ext_params.ssrc;
- config->receiver_ssrc = ext_params.feedback_ssrc;
- if (config->sender_ssrc == config->receiver_ssrc) {
- DVLOG(1) << "sender_ssrc " << config->sender_ssrc
- << " cannot be equal to receiver_ssrc";
- isolate->ThrowException(
- v8::Exception::Error(v8::String::NewFromUtf8(isolate, kInvalidRtpParams,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- return false;
- }
- config->min_playout_delay = base::TimeDelta::FromMilliseconds(
- ext_params.min_latency ? *ext_params.min_latency
- : ext_params.max_latency);
- config->max_playout_delay =
- base::TimeDelta::FromMilliseconds(ext_params.max_latency);
- config->animated_playout_delay = base::TimeDelta::FromMilliseconds(
- ext_params.animated_latency ? *ext_params.animated_latency
- : ext_params.max_latency);
- if (config->min_playout_delay <= base::TimeDelta()) {
- DVLOG(1) << "min_playout_delay " << config->min_playout_delay
- << " must be greater than zero";
- isolate->ThrowException(
- v8::Exception::Error(v8::String::NewFromUtf8(isolate, kInvalidRtpParams,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- return false;
- }
- if (config->min_playout_delay > config->max_playout_delay) {
- DVLOG(1) << "min_playout_delay " << config->min_playout_delay
- << " must be less than or equal to max_palyout_delay";
- isolate->ThrowException(
- v8::Exception::Error(v8::String::NewFromUtf8(isolate, kInvalidRtpParams,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- return false;
- }
- if (config->animated_playout_delay < config->min_playout_delay ||
- config->animated_playout_delay > config->max_playout_delay) {
- DVLOG(1) << "animated_playout_delay " << config->animated_playout_delay
- << " must be between (inclusive) the min and max playout delay";
- isolate->ThrowException(
- v8::Exception::Error(v8::String::NewFromUtf8(isolate, kInvalidRtpParams,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- return false;
- }
- if (ext_params.codec_name == kCodecNameOpus) {
- config->rtp_payload_type = media::cast::RtpPayloadType::AUDIO_OPUS;
- config->use_external_encoder = false;
- config->rtp_timebase = ext_params.clock_rate
- ? *ext_params.clock_rate
- : media::cast::kDefaultAudioSamplingRate;
- // Sampling rate must be one of the Opus-supported values.
- switch (config->rtp_timebase) {
- case 48000:
- case 24000:
- case 16000:
- case 12000:
- case 8000:
- break;
- default:
- DVLOG(1) << "rtp_timebase " << config->rtp_timebase << " is invalid";
- isolate->ThrowException(v8::Exception::Error(
- v8::String::NewFromUtf8(isolate, kInvalidRtpParams,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- return false;
- }
- config->channels = ext_params.channels ? *ext_params.channels : 2;
- if (config->channels != 1 && config->channels != 2) {
- isolate->ThrowException(v8::Exception::Error(
- v8::String::NewFromUtf8(isolate, kInvalidRtpParams,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- DVLOG(1) << "channels " << config->channels << " is invalid";
- return false;
- }
- config->min_bitrate = config->start_bitrate = config->max_bitrate =
- ext_params.max_bitrate ? (*ext_params.max_bitrate) * kBitsPerKilobit
- : media::cast::kDefaultAudioEncoderBitrate;
- config->max_frame_rate = 100; // 10ms audio frames.
- config->codec = media::cast::CODEC_AUDIO_OPUS;
- } else if (ext_params.codec_name == kCodecNameVp8 ||
- ext_params.codec_name == kCodecNameH264) {
- config->rtp_timebase = media::cast::kVideoFrequency;
- config->channels = ext_params.channels ? *ext_params.channels : 1;
- if (config->channels != 1) {
- isolate->ThrowException(v8::Exception::Error(
- v8::String::NewFromUtf8(isolate, kInvalidRtpParams,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- DVLOG(1) << "channels " << config->channels << " is invalid";
- return false;
- }
- config->min_bitrate = ext_params.min_bitrate
- ? (*ext_params.min_bitrate) * kBitsPerKilobit
- : media::cast::kDefaultMinVideoBitrate;
- config->max_bitrate = ext_params.max_bitrate
- ? (*ext_params.max_bitrate) * kBitsPerKilobit
- : media::cast::kDefaultMaxVideoBitrate;
- if (config->min_bitrate > config->max_bitrate) {
- DVLOG(1) << "min_bitrate " << config->min_bitrate << " is larger than "
- << "max_bitrate " << config->max_bitrate;
- isolate->ThrowException(v8::Exception::Error(
- v8::String::NewFromUtf8(isolate, kInvalidRtpParams,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- return false;
- }
- config->start_bitrate = config->min_bitrate;
- config->max_frame_rate = std::max(
- 1.0, ext_params.max_frame_rate ? *ext_params.max_frame_rate : 0.0);
- if (config->max_frame_rate > media::limits::kMaxFramesPerSecond) {
- DVLOG(1) << "max_frame_rate " << config->max_frame_rate << " is invalid";
- isolate->ThrowException(v8::Exception::Error(
- v8::String::NewFromUtf8(isolate, kInvalidRtpParams,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- return false;
- }
- if (ext_params.codec_name == kCodecNameVp8) {
- config->rtp_payload_type = media::cast::RtpPayloadType::VIDEO_VP8;
- config->codec = media::cast::CODEC_VIDEO_VP8;
- config->use_external_encoder =
- CastRtpStream::IsHardwareVP8EncodingSupported();
- } else {
- config->rtp_payload_type = media::cast::RtpPayloadType::VIDEO_H264;
- config->codec = media::cast::CODEC_VIDEO_H264;
- config->use_external_encoder =
- CastRtpStream::IsHardwareH264EncodingSupported();
- }
- if (!config->use_external_encoder)
- config->video_codec_params.number_of_encode_threads =
- NumberOfEncodeThreads();
- } else if (ext_params.codec_name == kCodecNameRemoteAudio) {
- config->rtp_payload_type = media::cast::RtpPayloadType::REMOTE_AUDIO;
- config->codec = media::cast::CODEC_AUDIO_REMOTE;
- } else if (ext_params.codec_name == kCodecNameRemoteVideo) {
- config->rtp_payload_type = media::cast::RtpPayloadType::REMOTE_VIDEO;
- config->codec = media::cast::CODEC_VIDEO_REMOTE;
- } else {
- DVLOG(1) << "codec_name " << ext_params.codec_name << " is invalid";
- isolate->ThrowException(
- v8::Exception::Error(v8::String::NewFromUtf8(isolate, kInvalidRtpParams,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- return false;
- }
- if (ext_params.aes_key && !HexDecode(*ext_params.aes_key, &config->aes_key)) {
- isolate->ThrowException(
- v8::Exception::Error(v8::String::NewFromUtf8(isolate, kInvalidAesKey,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- return false;
- }
- if (ext_params.aes_iv_mask &&
- !HexDecode(*ext_params.aes_iv_mask, &config->aes_iv_mask)) {
- isolate->ThrowException(
- v8::Exception::Error(v8::String::NewFromUtf8(isolate, kInvalidAesIvMask,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- return false;
- }
- return true;
-}
-
-void FromFrameSenderConfig(const FrameSenderConfig& config,
- RtpPayloadParams* ext_params) {
- ext_params->payload_type = static_cast<int>(config.rtp_payload_type);
- ext_params->max_latency = config.max_playout_delay.InMilliseconds();
- ext_params->min_latency.reset(
- new int(config.min_playout_delay.InMilliseconds()));
- ext_params->animated_latency.reset(
- new int(config.animated_playout_delay.InMilliseconds()));
- switch (config.codec) {
- case media::cast::CODEC_AUDIO_OPUS:
- ext_params->codec_name = kCodecNameOpus;
- break;
- case media::cast::CODEC_VIDEO_VP8:
- ext_params->codec_name = kCodecNameVp8;
- break;
- case media::cast::CODEC_VIDEO_H264:
- ext_params->codec_name = kCodecNameH264;
- break;
- case media::cast::CODEC_AUDIO_REMOTE:
- ext_params->codec_name = kCodecNameRemoteAudio;
- break;
- case media::cast::CODEC_VIDEO_REMOTE:
- ext_params->codec_name = kCodecNameRemoteVideo;
- break;
- default:
- NOTREACHED();
- }
- ext_params->ssrc = config.sender_ssrc;
- ext_params->feedback_ssrc = config.receiver_ssrc;
- if (config.rtp_timebase)
- ext_params->clock_rate.reset(new int(config.rtp_timebase));
- if (config.min_bitrate)
- ext_params->min_bitrate.reset(
- new int(config.min_bitrate / kBitsPerKilobit));
- if (config.max_bitrate)
- ext_params->max_bitrate.reset(
- new int(config.max_bitrate / kBitsPerKilobit));
- if (config.channels)
- ext_params->channels.reset(new int(config.channels));
- if (config.max_frame_rate > 0.0)
- ext_params->max_frame_rate.reset(new double(config.max_frame_rate));
-}
-
-} // namespace
-
-// |last_transport_id_| is the identifier for the next created RTP stream. To
-// create globally unique IDs used for referring to RTP stream objects in
-// browser process, we set its higher 16 bits as HASH(extension_id)&0x7fff, and
-// lower 16 bits as the sequence number of the RTP stream created in the same
-// extension. Collision will happen when the first RTP stream keeps alive after
-// creating another 64k-1 RTP streams in the same extension, which is very
-// unlikely to happen in normal use cases.
-CastStreamingNativeHandler::CastStreamingNativeHandler(
- ScriptContext* context,
- NativeExtensionBindingsSystem* bindings_system)
- : ObjectBackedNativeHandler(context),
- last_transport_id_(
- context->extension()
- ? (((base::Hash(context->extension()->id()) & 0x7fff) << 16) + 1)
- : 1),
- bindings_system_(bindings_system) {}
-
-CastStreamingNativeHandler::~CastStreamingNativeHandler() {
- // Note: A superclass's destructor will call Invalidate(), but Invalidate()
- // may also be called at any time before destruction.
-}
-
-void CastStreamingNativeHandler::AddRoutes() {
- RouteHandlerFunction(
- "CreateSession", "cast.streaming.session",
- base::BindRepeating(&CastStreamingNativeHandler::CreateCastSession,
- weak_factory_.GetWeakPtr()));
- RouteHandlerFunction(
- "DestroyCastRtpStream", "cast.streaming.rtpStream",
- base::BindRepeating(&CastStreamingNativeHandler::DestroyCastRtpStream,
- weak_factory_.GetWeakPtr()));
- RouteHandlerFunction(
- "GetSupportedParamsCastRtpStream", "cast.streaming.rtpStream",
- base::BindRepeating(
- &CastStreamingNativeHandler::GetSupportedParamsCastRtpStream,
- weak_factory_.GetWeakPtr()));
- RouteHandlerFunction(
- "StartCastRtpStream", "cast.streaming.rtpStream",
- base::BindRepeating(&CastStreamingNativeHandler::StartCastRtpStream,
- weak_factory_.GetWeakPtr()));
- RouteHandlerFunction(
- "StopCastRtpStream", "cast.streaming.rtpStream",
- base::BindRepeating(&CastStreamingNativeHandler::StopCastRtpStream,
- weak_factory_.GetWeakPtr()));
- RouteHandlerFunction(
- "DestroyCastUdpTransport", "cast.streaming.udpTransport",
- base::BindRepeating(&CastStreamingNativeHandler::DestroyCastUdpTransport,
- weak_factory_.GetWeakPtr()));
- RouteHandlerFunction(
- "SetDestinationCastUdpTransport", "cast.streaming.udpTransport",
- base::BindRepeating(
- &CastStreamingNativeHandler::SetDestinationCastUdpTransport,
- weak_factory_.GetWeakPtr()));
- RouteHandlerFunction(
- "SetOptionsCastUdpTransport", "cast.streaming.udpTransport",
- base::BindRepeating(
- &CastStreamingNativeHandler::SetOptionsCastUdpTransport,
- weak_factory_.GetWeakPtr()));
- RouteHandlerFunction(
- "ToggleLogging", "cast.streaming.rtpStream",
- base::BindRepeating(&CastStreamingNativeHandler::ToggleLogging,
- weak_factory_.GetWeakPtr()));
- RouteHandlerFunction(
- "GetRawEvents", "cast.streaming.rtpStream",
- base::BindRepeating(&CastStreamingNativeHandler::GetRawEvents,
- weak_factory_.GetWeakPtr()));
- RouteHandlerFunction(
- "GetStats", "cast.streaming.rtpStream",
- base::BindRepeating(&CastStreamingNativeHandler::GetStats,
- weak_factory_.GetWeakPtr()));
-}
-
-void CastStreamingNativeHandler::Invalidate() {
- // Cancel all function call routing and callbacks.
- weak_factory_.InvalidateWeakPtrs();
-
- // Clear all references to V8 and Cast objects, which will trigger
- // auto-destructions (effectively stopping all sessions).
- get_stats_callbacks_.clear();
- get_raw_events_callbacks_.clear();
- create_callback_.Reset();
- udp_transport_map_.clear();
- rtp_stream_map_.clear();
-
- ObjectBackedNativeHandler::Invalidate();
-}
-
-void CastStreamingNativeHandler::CreateCastSession(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
- CHECK_EQ(3, args.Length());
- CHECK(args[2]->IsFunction());
-
- v8::Isolate* isolate = context()->v8_context()->GetIsolate();
-
- auto session = base::MakeRefCounted<CastSession>(
- context()->web_frame()->GetTaskRunner(blink::TaskType::kInternalMedia));
- std::unique_ptr<CastRtpStream> stream1, stream2;
- if ((args[0]->IsNull() || args[0]->IsUndefined()) &&
- (args[1]->IsNull() || args[1]->IsUndefined())) {
- DVLOG(3) << "CreateCastSession for remoting.";
- // Creates audio/video RTP streams for media remoting.
- stream1.reset(new CastRtpStream(true, session));
- stream2.reset(new CastRtpStream(false, session));
- } else {
- // Creates RTP streams that consume from an audio and/or a video
- // MediaStreamTrack.
- if (!args[0]->IsNull() && !args[0]->IsUndefined()) {
- CHECK(args[0]->IsObject());
- blink::WebDOMMediaStreamTrack track =
- blink::WebDOMMediaStreamTrack::FromV8Value(args[0]);
- if (track.IsNull()) {
- isolate->ThrowException(v8::Exception::Error(
- v8::String::NewFromUtf8(isolate, kInvalidStreamArgs,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- return;
- }
- stream1.reset(new CastRtpStream(track.Component(), session));
- }
- if (!args[1]->IsNull() && !args[1]->IsUndefined()) {
- CHECK(args[1]->IsObject());
- blink::WebDOMMediaStreamTrack track =
- blink::WebDOMMediaStreamTrack::FromV8Value(args[1]);
- if (track.IsNull()) {
- isolate->ThrowException(v8::Exception::Error(
- v8::String::NewFromUtf8(isolate, kInvalidStreamArgs,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- return;
- }
- stream2.reset(new CastRtpStream(track.Component(), session));
- }
- }
- std::unique_ptr<CastUdpTransport> udp_transport(
- new CastUdpTransport(session));
-
- create_callback_.Reset(isolate, args[2].As<v8::Function>());
-
- context()
- ->web_frame()
- ->GetTaskRunner(blink::TaskType::kInternalMedia)
- ->PostTask(FROM_HERE,
- base::BindOnce(&CastStreamingNativeHandler::CallCreateCallback,
- weak_factory_.GetWeakPtr(), std::move(stream1),
- std::move(stream2), std::move(udp_transport)));
-}
-
-void CastStreamingNativeHandler::CallCreateCallback(
- std::unique_ptr<CastRtpStream> stream1,
- std::unique_ptr<CastRtpStream> stream2,
- std::unique_ptr<CastUdpTransport> udp_transport) {
- v8::Isolate* isolate = context()->isolate();
- v8::HandleScope handle_scope(isolate);
- v8::Context::Scope context_scope(context()->v8_context());
-
- v8::Local<v8::Value> callback_args[3];
- callback_args[0] = v8::Null(isolate);
- callback_args[1] = v8::Null(isolate);
-
- if (stream1) {
- const int stream1_id = last_transport_id_++;
- callback_args[0] = v8::Integer::New(isolate, stream1_id);
- rtp_stream_map_[stream1_id] = std::move(stream1);
- }
- if (stream2) {
- const int stream2_id = last_transport_id_++;
- callback_args[1] = v8::Integer::New(isolate, stream2_id);
- rtp_stream_map_[stream2_id] = std::move(stream2);
- }
- const int udp_id = last_transport_id_++;
- udp_transport_map_[udp_id] = std::move(udp_transport);
- callback_args[2] = v8::Integer::New(isolate, udp_id);
- context()->SafeCallFunction(
- v8::Local<v8::Function>::New(isolate, create_callback_), 3,
- callback_args);
- create_callback_.Reset();
-}
-
-void CastStreamingNativeHandler::CallStartCallback(int stream_id) const {
- base::ListValue event_args;
- event_args.AppendInteger(stream_id);
- bindings_system_->DispatchEventInContext("cast.streaming.rtpStream.onStarted",
- &event_args, nullptr, context());
-}
-
-void CastStreamingNativeHandler::CallStopCallback(int stream_id) const {
- base::ListValue event_args;
- event_args.AppendInteger(stream_id);
- bindings_system_->DispatchEventInContext("cast.streaming.rtpStream.onStopped",
- &event_args, nullptr, context());
-}
-
-void CastStreamingNativeHandler::CallErrorCallback(
- int stream_id,
- const std::string& message) const {
- base::ListValue event_args;
- event_args.AppendInteger(stream_id);
- event_args.AppendString(message);
- bindings_system_->DispatchEventInContext("cast.streaming.rtpStream.onError",
- &event_args, nullptr, context());
-}
-
-void CastStreamingNativeHandler::DestroyCastRtpStream(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
- CHECK_EQ(1, args.Length());
- CHECK(args[0]->IsInt32());
-
- const int transport_id = args[0].As<v8::Int32>()->Value();
- if (!GetRtpStreamOrThrow(transport_id))
- return;
- rtp_stream_map_.erase(transport_id);
-}
-
-void CastStreamingNativeHandler::GetSupportedParamsCastRtpStream(
- const v8::FunctionCallbackInfo<v8::Value>& args) const {
- CHECK_EQ(1, args.Length());
- CHECK(args[0]->IsInt32());
-
- const int transport_id = args[0].As<v8::Int32>()->Value();
- CastRtpStream* transport = GetRtpStreamOrThrow(transport_id);
- if (!transport)
- return;
-
- std::unique_ptr<V8ValueConverter> converter = V8ValueConverter::Create();
- std::vector<FrameSenderConfig> configs = transport->GetSupportedConfigs();
- v8::Local<v8::Array> result =
- v8::Array::New(args.GetIsolate(), static_cast<int>(configs.size()));
- for (size_t i = 0; i < configs.size(); ++i) {
- RtpParams params;
- FromFrameSenderConfig(configs[i], &params.payload);
- std::unique_ptr<base::DictionaryValue> params_value = params.ToValue();
- result
- ->CreateDataProperty(
- context()->v8_context(), static_cast<int>(i),
- converter->ToV8Value(params_value.get(), context()->v8_context()))
- .Check();
- }
- args.GetReturnValue().Set(result);
-}
-
-void CastStreamingNativeHandler::StartCastRtpStream(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
- CHECK_EQ(2, args.Length());
- CHECK(args[0]->IsInt32());
- CHECK(args[1]->IsObject());
-
- const int transport_id = args[0].As<v8::Int32>()->Value();
- CastRtpStream* transport = GetRtpStreamOrThrow(transport_id);
- if (!transport)
- return;
-
- std::unique_ptr<base::Value> params_value =
- V8ValueConverter::Create()->FromV8Value(args[1], context()->v8_context());
- if (!params_value) {
- args.GetIsolate()->ThrowException(v8::Exception::TypeError(
- v8::String::NewFromUtf8(args.GetIsolate(), kUnableToConvertParams,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- return;
- }
- std::unique_ptr<RtpParams> params = RtpParams::FromValue(*params_value);
- if (!params) {
- args.GetIsolate()->ThrowException(v8::Exception::TypeError(
- v8::String::NewFromUtf8(args.GetIsolate(), kInvalidRtpParams,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- return;
- }
-
- FrameSenderConfig config;
- v8::Isolate* isolate = context()->v8_context()->GetIsolate();
- if (!ToFrameSenderConfigOrThrow(isolate, params->payload, &config))
- return;
-
- base::OnceClosure start_callback =
- base::BindOnce(&CastStreamingNativeHandler::CallStartCallback,
- weak_factory_.GetWeakPtr(), transport_id);
- base::OnceClosure stop_callback =
- base::BindOnce(&CastStreamingNativeHandler::CallStopCallback,
- weak_factory_.GetWeakPtr(), transport_id);
- CastRtpStream::ErrorCallback error_callback =
- base::BindRepeating(&CastStreamingNativeHandler::CallErrorCallback,
- weak_factory_.GetWeakPtr(), transport_id);
-
- // |transport_id| is a globally unique identifier for the RTP stream.
- transport->Start(transport_id, config, std::move(start_callback),
- std::move(stop_callback), error_callback);
-}
-
-void CastStreamingNativeHandler::StopCastRtpStream(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
- CHECK_EQ(1, args.Length());
- CHECK(args[0]->IsInt32());
-
- const int transport_id = args[0].As<v8::Int32>()->Value();
- CastRtpStream* transport = GetRtpStreamOrThrow(transport_id);
- if (!transport)
- return;
- transport->Stop();
-}
-
-void CastStreamingNativeHandler::DestroyCastUdpTransport(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
- CHECK_EQ(1, args.Length());
- CHECK(args[0]->IsInt32());
-
- const int transport_id = args[0].As<v8::Int32>()->Value();
- if (!GetUdpTransportOrThrow(transport_id))
- return;
- udp_transport_map_.erase(transport_id);
-}
-
-void CastStreamingNativeHandler::SetDestinationCastUdpTransport(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
- CHECK_EQ(2, args.Length());
- CHECK(args[0]->IsInt32());
- CHECK(args[1]->IsObject());
-
- const int transport_id = args[0].As<v8::Int32>()->Value();
- CastUdpTransport* transport = GetUdpTransportOrThrow(transport_id);
- if (!transport)
- return;
-
- net::IPEndPoint dest;
- if (!IPEndPointFromArg(args.GetIsolate(),
- args[1],
- &dest)) {
- return;
- }
- transport->SetDestination(
- dest,
- base::Bind(&CastStreamingNativeHandler::CallErrorCallback,
- weak_factory_.GetWeakPtr(),
- transport_id));
-}
-
-void CastStreamingNativeHandler::SetOptionsCastUdpTransport(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
- CHECK_EQ(2, args.Length());
- CHECK(args[0]->IsInt32());
- CHECK(args[1]->IsObject());
-
- const int transport_id = args[0].As<v8::Int32>()->Value();
- CastUdpTransport* transport = GetUdpTransportOrThrow(transport_id);
- if (!transport)
- return;
-
- std::unique_ptr<base::DictionaryValue> options =
- base::DictionaryValue::From(V8ValueConverter::Create()->FromV8Value(
- args[1], context()->v8_context()));
- if (!options) {
- args.GetIsolate()->ThrowException(v8::Exception::TypeError(
- v8::String::NewFromUtf8(args.GetIsolate(), kUnableToConvertArgs,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- return;
- }
- transport->SetOptions(std::move(options));
-}
-
-void CastStreamingNativeHandler::ToggleLogging(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
- CHECK_EQ(2, args.Length());
- CHECK(args[0]->IsInt32());
- CHECK(args[1]->IsBoolean());
-
- const int stream_id = args[0].As<v8::Int32>()->Value();
- CastRtpStream* stream = GetRtpStreamOrThrow(stream_id);
- if (!stream)
- return;
-
- const bool enable = args[1]->ToBoolean(args.GetIsolate())->Value();
- stream->ToggleLogging(enable);
-}
-
-void CastStreamingNativeHandler::GetRawEvents(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
- CHECK_EQ(3, args.Length());
- CHECK(args[0]->IsInt32());
- CHECK(args[1]->IsNull() || args[1]->IsString());
- CHECK(args[2]->IsFunction());
-
- const int transport_id = args[0].As<v8::Int32>()->Value();
- v8::Isolate* isolate = args.GetIsolate();
- v8::Global<v8::Function> callback(isolate, args[2].As<v8::Function>());
- std::string extra_data;
- if (!args[1]->IsNull()) {
- extra_data = *v8::String::Utf8Value(isolate, args[1]);
- }
-
- CastRtpStream* transport = GetRtpStreamOrThrow(transport_id);
- if (!transport)
- return;
-
- get_raw_events_callbacks_.insert(
- std::make_pair(transport_id, std::move(callback)));
-
- transport->GetRawEvents(
- base::Bind(&CastStreamingNativeHandler::CallGetRawEventsCallback,
- weak_factory_.GetWeakPtr(),
- transport_id),
- extra_data);
-}
-
-void CastStreamingNativeHandler::GetStats(
- const v8::FunctionCallbackInfo<v8::Value>& args) {
- CHECK_EQ(2, args.Length());
- CHECK(args[0]->IsInt32());
- CHECK(args[1]->IsFunction());
- const int transport_id = args[0].As<v8::Int32>()->Value();
- CastRtpStream* transport = GetRtpStreamOrThrow(transport_id);
- if (!transport)
- return;
-
- v8::Global<v8::Function> callback(args.GetIsolate(),
- args[1].As<v8::Function>());
- get_stats_callbacks_.insert(
- std::make_pair(transport_id, std::move(callback)));
-
- transport->GetStats(
- base::Bind(&CastStreamingNativeHandler::CallGetStatsCallback,
- weak_factory_.GetWeakPtr(),
- transport_id));
-}
-
-void CastStreamingNativeHandler::CallGetRawEventsCallback(
- int transport_id,
- std::unique_ptr<base::Value> raw_events) {
- v8::Isolate* isolate = context()->isolate();
- v8::HandleScope handle_scope(isolate);
- v8::Context::Scope context_scope(context()->v8_context());
-
- auto it = get_raw_events_callbacks_.find(transport_id);
- if (it == get_raw_events_callbacks_.end())
- return;
- v8::Local<v8::Value> callback_args[] = {V8ValueConverter::Create()->ToV8Value(
- raw_events.get(), context()->v8_context())};
- context()->SafeCallFunction(v8::Local<v8::Function>::New(isolate, it->second),
- base::size(callback_args), callback_args);
- get_raw_events_callbacks_.erase(it);
-}
-
-void CastStreamingNativeHandler::CallGetStatsCallback(
- int transport_id,
- std::unique_ptr<base::DictionaryValue> stats) {
- v8::Isolate* isolate = context()->isolate();
- v8::HandleScope handle_scope(isolate);
- v8::Context::Scope context_scope(context()->v8_context());
-
- auto it = get_stats_callbacks_.find(transport_id);
- if (it == get_stats_callbacks_.end())
- return;
-
- v8::Local<v8::Value> callback_args[] = {V8ValueConverter::Create()->ToV8Value(
- stats.get(), context()->v8_context())};
- context()->SafeCallFunction(v8::Local<v8::Function>::New(isolate, it->second),
- base::size(callback_args), callback_args);
- get_stats_callbacks_.erase(it);
-}
-
-CastRtpStream* CastStreamingNativeHandler::GetRtpStreamOrThrow(
- int transport_id) const {
- auto iter = rtp_stream_map_.find(transport_id);
- if (iter != rtp_stream_map_.end())
- return iter->second.get();
- v8::Isolate* isolate = context()->v8_context()->GetIsolate();
- isolate->ThrowException(v8::Exception::RangeError(
- v8::String::NewFromUtf8(isolate, kRtpStreamNotFound,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- return NULL;
-}
-
-CastUdpTransport* CastStreamingNativeHandler::GetUdpTransportOrThrow(
- int transport_id) const {
- auto iter = udp_transport_map_.find(transport_id);
- if (iter != udp_transport_map_.end())
- return iter->second.get();
- v8::Isolate* isolate = context()->v8_context()->GetIsolate();
- isolate->ThrowException(v8::Exception::RangeError(
- v8::String::NewFromUtf8(isolate, kUdpTransportNotFound,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- return NULL;
-}
-
-bool CastStreamingNativeHandler::IPEndPointFromArg(
- v8::Isolate* isolate,
- const v8::Local<v8::Value>& arg,
- net::IPEndPoint* ip_endpoint) const {
- std::unique_ptr<base::Value> destination_value =
- V8ValueConverter::Create()->FromV8Value(arg, context()->v8_context());
- if (!destination_value) {
- isolate->ThrowException(v8::Exception::TypeError(
- v8::String::NewFromUtf8(isolate, kInvalidAesIvMask,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- return false;
- }
- std::unique_ptr<IPEndPoint> destination =
- IPEndPoint::FromValue(*destination_value);
- if (!destination) {
- isolate->ThrowException(v8::Exception::TypeError(
- v8::String::NewFromUtf8(isolate, kInvalidDestination,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- return false;
- }
- net::IPAddress ip;
- if (!ip.AssignFromIPLiteral(destination->address)) {
- isolate->ThrowException(v8::Exception::TypeError(
- v8::String::NewFromUtf8(isolate, kInvalidDestination,
- v8::NewStringType::kNormal)
- .ToLocalChecked()));
- return false;
- }
- *ip_endpoint = net::IPEndPoint(ip, destination->port);
- return true;
-}
-
-void CastStreamingNativeHandler::CallReceiverErrorCallback(
- v8::CopyablePersistentTraits<v8::Function>::CopyablePersistent function,
- const std::string& error_message) {
- v8::Isolate* isolate = context()->v8_context()->GetIsolate();
- v8::Local<v8::Value> arg =
- v8::String::NewFromUtf8(isolate, error_message.data(),
- v8::NewStringType::kNormal, error_message.size())
- .ToLocalChecked();
- context()->SafeCallFunction(v8::Local<v8::Function>::New(isolate, function),
- 1, &arg);
-}
-
-} // namespace extensions
diff --git a/chromium/chrome/renderer/extensions/cast_streaming_native_handler.h b/chromium/chrome/renderer/extensions/cast_streaming_native_handler.h
deleted file mode 100644
index 9f135b35be2..00000000000
--- a/chromium/chrome/renderer/extensions/cast_streaming_native_handler.h
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright 2013 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 CHROME_RENDERER_EXTENSIONS_CAST_STREAMING_NATIVE_HANDLER_H_
-#define CHROME_RENDERER_EXTENSIONS_CAST_STREAMING_NATIVE_HANDLER_H_
-
-#include <map>
-#include <memory>
-
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "extensions/renderer/object_backed_native_handler.h"
-#include "v8/include/v8.h"
-
-class CastRtpStream;
-class CastUdpTransport;
-
-namespace base {
-class DictionaryValue;
-class Value;
-}
-
-namespace net {
-class IPEndPoint;
-}
-
-namespace extensions {
-class NativeExtensionBindingsSystem;
-
-// Native code that handle chrome.webrtc custom bindings.
-class CastStreamingNativeHandler : public ObjectBackedNativeHandler {
- public:
- CastStreamingNativeHandler(ScriptContext* context,
- NativeExtensionBindingsSystem* bindings_system);
- ~CastStreamingNativeHandler() override;
-
- // ObjectBackedNativeHandler:
- void AddRoutes() override;
-
- protected:
- // Shut down all sessions and cancel any in-progress operations because the
- // ScriptContext is about to become invalid.
- void Invalidate() override;
-
- private:
- void CreateCastSession(
- const v8::FunctionCallbackInfo<v8::Value>& args);
-
- void DestroyCastRtpStream(
- const v8::FunctionCallbackInfo<v8::Value>& args);
- void CreateParamsCastRtpStream(
- const v8::FunctionCallbackInfo<v8::Value>& args);
- void GetSupportedParamsCastRtpStream(
- const v8::FunctionCallbackInfo<v8::Value>& args) const;
- void StartCastRtpStream(
- const v8::FunctionCallbackInfo<v8::Value>& args);
- void StopCastRtpStream(
- const v8::FunctionCallbackInfo<v8::Value>& args);
-
- void DestroyCastUdpTransport(
- const v8::FunctionCallbackInfo<v8::Value>& args);
- void SetDestinationCastUdpTransport(
- const v8::FunctionCallbackInfo<v8::Value>& args);
- void SetOptionsCastUdpTransport(
- const v8::FunctionCallbackInfo<v8::Value>& args);
- void StopCastUdpTransport(
- const v8::FunctionCallbackInfo<v8::Value>& args);
-
- void ToggleLogging(const v8::FunctionCallbackInfo<v8::Value>& args);
- void GetRawEvents(const v8::FunctionCallbackInfo<v8::Value>& args);
- void GetStats(const v8::FunctionCallbackInfo<v8::Value>& args);
-
- // Helper method to call the v8 callback function after a session is
- // created.
- void CallCreateCallback(std::unique_ptr<CastRtpStream> stream1,
- std::unique_ptr<CastRtpStream> stream2,
- std::unique_ptr<CastUdpTransport> udp_transport);
-
- void CallStartCallback(int stream_id) const;
- void CallStopCallback(int stream_id) const;
- void CallErrorCallback(int stream_id, const std::string& message) const;
-
- // |function| is a javascript function that will take |error_message| as
- // an argument. Called when something goes wrong in a cast receiver.
- void CallReceiverErrorCallback(
- v8::CopyablePersistentTraits<v8::Function>::CopyablePersistent function,
- const std::string& error_message);
-
- void CallGetRawEventsCallback(int transport_id,
- std::unique_ptr<base::Value> raw_events);
- void CallGetStatsCallback(int transport_id,
- std::unique_ptr<base::DictionaryValue> stats);
-
- // Gets the RTP stream or UDP transport indexed by an ID.
- // If not found, returns NULL and throws a V8 exception.
- CastRtpStream* GetRtpStreamOrThrow(int stream_id) const;
- CastUdpTransport* GetUdpTransportOrThrow(int transport_id) const;
-
- bool IPEndPointFromArg(v8::Isolate* isolate,
- const v8::Local<v8::Value>& arg,
- net::IPEndPoint* ip_endpoint) const;
-
- int last_transport_id_;
-
- using RtpStreamMap = std::map<int, std::unique_ptr<CastRtpStream>>;
- RtpStreamMap rtp_stream_map_;
-
- using UdpTransportMap = std::map<int, std::unique_ptr<CastUdpTransport>>;
- UdpTransportMap udp_transport_map_;
-
- v8::Global<v8::Function> create_callback_;
-
- using RtpStreamCallbackMap = std::map<int, v8::Global<v8::Function>>;
- RtpStreamCallbackMap get_raw_events_callbacks_;
- RtpStreamCallbackMap get_stats_callbacks_;
-
- NativeExtensionBindingsSystem* bindings_system_;
-
- base::WeakPtrFactory<CastStreamingNativeHandler> weak_factory_{this};
-
- DISALLOW_COPY_AND_ASSIGN(CastStreamingNativeHandler);
-};
-
-} // namespace extensions
-
-#endif // CHROME_RENDERER_EXTENSIONS_CAST_STREAMING_NATIVE_HANDLER_H_
diff --git a/chromium/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc b/chromium/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc
index 6621279f9f5..07605bbb35d 100644
--- a/chromium/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc
+++ b/chromium/chrome/renderer/extensions/chrome_extensions_dispatcher_delegate.cc
@@ -14,7 +14,6 @@
#include "chrome/grit/renderer_resources.h"
#include "chrome/renderer/extensions/accessibility_private_hooks_delegate.h"
#include "chrome/renderer/extensions/app_hooks_delegate.h"
-#include "chrome/renderer/extensions/cast_streaming_native_handler.h"
#include "chrome/renderer/extensions/extension_hooks_delegate.h"
#include "chrome/renderer/extensions/media_galleries_custom_bindings.h"
#include "chrome/renderer/extensions/notifications_native_handler.h"
@@ -92,10 +91,6 @@ void ChromeExtensionsDispatcherDelegate::RegisterNativeHandlers(
module_system->RegisterNativeHandler(
"page_capture", std::unique_ptr<NativeHandler>(
new extensions::PageCaptureCustomBindings(context)));
- module_system->RegisterNativeHandler(
- "cast_streaming_natives",
- std::make_unique<extensions::CastStreamingNativeHandler>(
- context, bindings_system));
// The following are native handlers that are defined in //extensions, but
// are only used for APIs defined in Chrome.
@@ -163,7 +158,7 @@ void ChromeExtensionsDispatcherDelegate::PopulateSourceMap(
IDR_FILE_SYSTEM_PROVIDER_CUSTOM_BINDINGS_JS);
source_map->RegisterSource("platformKeys",
IDR_PLATFORM_KEYS_CUSTOM_BINDINGS_JS);
- source_map->RegisterSource("platformKeys.getPublicKey",
+ source_map->RegisterSource("platformKeys.getPublicKeyUtil",
IDR_PLATFORM_KEYS_GET_PUBLIC_KEY_JS);
source_map->RegisterSource("platformKeys.internalAPI",
IDR_PLATFORM_KEYS_INTERNAL_API_JS);
@@ -179,18 +174,12 @@ void ChromeExtensionsDispatcherDelegate::PopulateSourceMap(
IDR_IME_SERVICE_MOJOM_JS);
source_map->RegisterSource("chromeos.ime.service",
IDR_IME_SERVICE_BINDINGS_JS);
+
+ source_map->RegisterSource("chromeos.tts.mojom.tts_stream.mojom",
+ IDR_TTS_STREAM_MOJOM_JS);
+ source_map->RegisterSource("chromeos.tts.stream", IDR_TTS_STREAM_BINDINGS_JS);
#endif // defined(OS_CHROMEOS)
- source_map->RegisterSource("cast.streaming.rtpStream",
- IDR_CAST_STREAMING_RTP_STREAM_CUSTOM_BINDINGS_JS);
- source_map->RegisterSource("cast.streaming.session",
- IDR_CAST_STREAMING_SESSION_CUSTOM_BINDINGS_JS);
- source_map->RegisterSource(
- "cast.streaming.udpTransport",
- IDR_CAST_STREAMING_UDP_TRANSPORT_CUSTOM_BINDINGS_JS);
- source_map->RegisterSource(
- "cast.streaming.receiverSession",
- IDR_CAST_STREAMING_RECEIVER_SESSION_CUSTOM_BINDINGS_JS);
source_map->RegisterSource(
"webrtcDesktopCapturePrivate",
IDR_WEBRTC_DESKTOP_CAPTURE_PRIVATE_CUSTOM_BINDINGS_JS);
diff --git a/chromium/chrome/renderer/extensions/chrome_extensions_renderer_client.cc b/chromium/chrome/renderer/extensions/chrome_extensions_renderer_client.cc
index c29b1f5a41f..6804fa38d51 100644
--- a/chromium/chrome/renderer/extensions/chrome_extensions_renderer_client.cc
+++ b/chromium/chrome/renderer/extensions/chrome_extensions_renderer_client.cc
@@ -21,7 +21,6 @@
#include "chrome/renderer/extensions/extension_process_policy.h"
#include "chrome/renderer/extensions/renderer_permissions_policy_delegate.h"
#include "chrome/renderer/extensions/resource_request_policy.h"
-#include "chrome/renderer/media/cast_ipc_dispatcher.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/content_switches.h"
#include "content/public/renderer/render_frame.h"
@@ -166,7 +165,6 @@ void ChromeExtensionsRendererClient::RenderThreadStarted() {
thread->AddObserver(extension_dispatcher_.get());
thread->AddObserver(guest_view_container_dispatcher_.get());
- thread->AddFilter(new CastIPCDispatcher(thread->GetIOTaskRunner()));
}
void ChromeExtensionsRendererClient::RenderFrameCreated(
diff --git a/chromium/chrome/renderer/extensions/platform_keys_natives.cc b/chromium/chrome/renderer/extensions/platform_keys_natives.cc
index 831e007ccbe..22551ad0bca 100644
--- a/chromium/chrome/renderer/extensions/platform_keys_natives.cc
+++ b/chromium/chrome/renderer/extensions/platform_keys_natives.cc
@@ -10,8 +10,8 @@
#include "base/bind.h"
#include "base/values.h"
-#include "content/public/renderer/v8_value_converter.h"
#include "extensions/renderer/script_context.h"
+#include "gin/data_object_builder.h"
#include "third_party/blink/public/platform/web_crypto_algorithm.h"
#include "third_party/blink/public/platform/web_crypto_algorithm_params.h"
#include "third_party/blink/public/platform/web_string.h"
@@ -43,14 +43,17 @@ bool StringToWebCryptoOperation(const std::string& str,
return false;
}
-std::unique_ptr<base::DictionaryValue> WebCryptoAlgorithmToBaseValue(
- const blink::WebCryptoAlgorithm& algorithm) {
+v8::Local<v8::Object> WebCryptoAlgorithmToV8Value(
+ const blink::WebCryptoAlgorithm& algorithm,
+ v8::Local<v8::Context> context) {
DCHECK(!algorithm.IsNull());
+ v8::Context::Scope scope(context);
+ v8::Isolate* isolate = context->GetIsolate();
- std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
const blink::WebCryptoAlgorithmInfo* info =
blink::WebCryptoAlgorithm::LookupAlgorithmInfo(algorithm.Id());
- dict->SetKey("name", base::Value(info->name));
+ gin::DataObjectBuilder builder(isolate);
+ builder.Set("name", base::StringPiece(info->name));
const blink::WebCryptoAlgorithm* hash = nullptr;
@@ -59,16 +62,15 @@ std::unique_ptr<base::DictionaryValue> WebCryptoAlgorithmToBaseValue(
const blink::WebCryptoRsaHashedKeyGenParams* rsa_hashed_key_gen =
algorithm.RsaHashedKeyGenParams();
if (rsa_hashed_key_gen) {
- dict->SetKey("modulusLength",
- base::Value(static_cast<int>(
- rsa_hashed_key_gen->ModulusLengthBits())));
+ builder.Set("modulusLength", rsa_hashed_key_gen->ModulusLengthBits());
+
const blink::WebVector<unsigned char>& public_exponent =
rsa_hashed_key_gen->PublicExponent();
- dict->SetWithoutPathExpansion(
- "publicExponent",
- base::Value::CreateWithCopiedBuffer(
- reinterpret_cast<const char*>(public_exponent.Data()),
- public_exponent.size()));
+ v8::Local<v8::ArrayBuffer> buffer =
+ v8::ArrayBuffer::New(isolate, public_exponent.size());
+ memcpy(buffer->GetContents().Data(), public_exponent.Data(),
+ public_exponent.size());
+ builder.Set("publicExponent", buffer);
hash = &rsa_hashed_key_gen->GetHash();
DCHECK(!hash->IsNull());
@@ -85,7 +87,7 @@ std::unique_ptr<base::DictionaryValue> WebCryptoAlgorithmToBaseValue(
const blink::WebCryptoEcKeyGenParams* ec_key_gen =
algorithm.EcKeyGenParams();
if (ec_key_gen) {
- std::string named_curve;
+ base::StringPiece named_curve;
switch (ec_key_gen->NamedCurve()) {
case blink::kWebCryptoNamedCurveP256:
named_curve = "P-256";
@@ -98,7 +100,7 @@ std::unique_ptr<base::DictionaryValue> WebCryptoAlgorithmToBaseValue(
break;
}
DCHECK(!named_curve.empty());
- dict->SetKey("namedCurve", base::Value(std::move(named_curve)));
+ builder.Set("namedCurve", named_curve);
}
const blink::WebCryptoEcdsaParams* ecdsa = algorithm.EcdsaParams();
@@ -117,13 +119,13 @@ std::unique_ptr<base::DictionaryValue> WebCryptoAlgorithmToBaseValue(
const blink::WebCryptoAlgorithmInfo* hash_info =
blink::WebCryptoAlgorithm::LookupAlgorithmInfo(hash->Id());
- std::unique_ptr<base::DictionaryValue> hash_dict(new base::DictionaryValue);
- hash_dict->SetKey("name", base::Value(hash_info->name));
- dict->SetWithoutPathExpansion("hash", std::move(hash_dict));
+ builder.Set("hash", gin::DataObjectBuilder(isolate)
+ .Set("name", base::StringPiece(hash_info->name))
+ .Build());
}
// Otherwise, |algorithm| is missing support here or no parameters were
// required.
- return dict;
+ return builder.Build();
}
} // namespace
@@ -158,15 +160,11 @@ void PlatformKeysNatives::NormalizeAlgorithm(
v8::Local<v8::Object>::Cast(call_info[0]), operation, &exception_code,
&error_details, call_info.GetIsolate());
- std::unique_ptr<base::DictionaryValue> algorithm_dict;
- if (!algorithm.IsNull())
- algorithm_dict = WebCryptoAlgorithmToBaseValue(algorithm);
-
- if (!algorithm_dict)
+ if (algorithm.IsNull())
return;
- call_info.GetReturnValue().Set(content::V8ValueConverter::Create()->ToV8Value(
- algorithm_dict.get(), context()->v8_context()));
+ call_info.GetReturnValue().Set(
+ WebCryptoAlgorithmToV8Value(algorithm, context()->v8_context()));
}
} // namespace extensions
diff --git a/chromium/chrome/renderer/instant_restricted_id_cache.h b/chromium/chrome/renderer/instant_restricted_id_cache.h
index 3062768bc22..6e3f820cf96 100644
--- a/chromium/chrome/renderer/instant_restricted_id_cache.h
+++ b/chromium/chrome/renderer/instant_restricted_id_cache.h
@@ -11,9 +11,9 @@
#include <utility>
#include <vector>
+#include "base/check_op.h"
#include "base/containers/mru_cache.h"
#include "base/gtest_prod_util.h"
-#include "base/logging.h"
#include "base/macros.h"
#include "chrome/common/search/instant_types.h"
diff --git a/chromium/chrome/renderer/lite_video/DEPS b/chromium/chrome/renderer/lite_video/DEPS
new file mode 100644
index 00000000000..6511c3d7aac
--- /dev/null
+++ b/chromium/chrome/renderer/lite_video/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+"+services/network/test",
+]
diff --git a/chromium/chrome/renderer/lite_video/OWNERS b/chromium/chrome/renderer/lite_video/OWNERS
new file mode 100644
index 00000000000..d5e2286a680
--- /dev/null
+++ b/chromium/chrome/renderer/lite_video/OWNERS
@@ -0,0 +1,3 @@
+file://components/data_reduction_proxy/OWNERS
+
+# COMPONENT: Internal>Network>DataUse
diff --git a/chromium/chrome/renderer/lite_video/lite_video_hint_agent.cc b/chromium/chrome/renderer/lite_video/lite_video_hint_agent.cc
new file mode 100644
index 00000000000..4f4840c349e
--- /dev/null
+++ b/chromium/chrome/renderer/lite_video/lite_video_hint_agent.cc
@@ -0,0 +1,99 @@
+// 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 "chrome/renderer/lite_video/lite_video_hint_agent.h"
+
+#include "base/metrics/histogram_macros.h"
+#include "chrome/renderer/lite_video/lite_video_util.h"
+#include "services/network/public/mojom/url_response_head.mojom.h"
+
+namespace lite_video {
+
+LiteVideoHintAgent::LiteVideoHintAgent(content::RenderFrame* render_frame)
+ : content::RenderFrameObserver(render_frame),
+ content::RenderFrameObserverTracker<LiteVideoHintAgent>(render_frame) {
+ DCHECK(render_frame);
+}
+
+LiteVideoHintAgent::~LiteVideoHintAgent() = default;
+
+void LiteVideoHintAgent::OnDestruct() {
+ delete this;
+}
+
+void LiteVideoHintAgent::AddThrottle(LiteVideoURLLoaderThrottle* throttle) {
+ DCHECK(HasLiteVideoHint());
+ active_throttles_.insert(throttle);
+ UMA_HISTOGRAM_COUNTS("LiteVideo.HintAgent.ActiveThrottleSize",
+ active_throttles_.size());
+}
+
+void LiteVideoHintAgent::RemoveThrottle(LiteVideoURLLoaderThrottle* throttle) {
+ active_throttles_.erase(throttle);
+}
+
+base::TimeDelta LiteVideoHintAgent::CalculateLatencyForResourceResponse(
+ const network::mojom::URLResponseHead& response_head) {
+ if (!HasLiteVideoHint())
+ return base::TimeDelta();
+
+ int64_t recv_bytes = response_head.content_length;
+ if (recv_bytes == -1)
+ recv_bytes = response_head.encoded_body_length;
+ if (recv_bytes == -1)
+ return base::TimeDelta();
+
+ if (kilobytes_buffered_before_throttle_ <
+ *kilobytes_to_buffer_before_throttle_) {
+ kilobytes_buffered_before_throttle_ += recv_bytes / 1024;
+ return base::TimeDelta();
+ }
+
+ // The total RTT for this media response should be based on how much time it
+ // took to transfer the packet in the target bandwidth, and the per RTT
+ // latency. For example, assuming 100KBPS target bandwidth and target RTT of 1
+ // second, an 400KB response should have total delay of 5 seconds
+ // (400/100 + 1).
+ auto delay_for_throttled_response =
+ base::TimeDelta::FromSecondsD(
+ recv_bytes / (*target_downlink_bandwidth_kbps_ * 1024.0)) +
+ *target_downlink_rtt_latency_;
+ auto response_delay =
+ response_head.response_time - response_head.request_time;
+ if (delay_for_throttled_response <= response_delay)
+ return base::TimeDelta();
+
+ return std::min(delay_for_throttled_response - response_delay,
+ *max_throttling_delay_);
+}
+
+bool LiteVideoHintAgent::HasLiteVideoHint() const {
+ return target_downlink_bandwidth_kbps_ && target_downlink_rtt_latency_ &&
+ kilobytes_to_buffer_before_throttle_ && max_throttling_delay_;
+}
+
+void LiteVideoHintAgent::SetLiteVideoHint(
+ blink::mojom::LiteVideoHintPtr lite_video_hint) {
+ if (!lite_video_hint)
+ return;
+ target_downlink_bandwidth_kbps_ =
+ lite_video_hint->target_downlink_bandwidth_kbps;
+ kilobytes_to_buffer_before_throttle_ =
+ lite_video_hint->kilobytes_to_buffer_before_throttle;
+ target_downlink_rtt_latency_ = lite_video_hint->target_downlink_rtt_latency;
+ max_throttling_delay_ = lite_video_hint->max_throttling_delay;
+ LOCAL_HISTOGRAM_BOOLEAN("LiteVideo.HintAgent.HasHint", true);
+}
+
+void LiteVideoHintAgent::StopThrottling() {
+ // TODO(rajendrant): Send the stop throttling signal to browser process, after
+ // some K rebuffer events had occurred.
+ DCHECK(HasLiteVideoHint());
+ for (auto* throttle : active_throttles_) {
+ throttle->ResumeIfThrottled();
+ }
+ kilobytes_buffered_before_throttle_ = 0;
+}
+
+} // namespace lite_video
diff --git a/chromium/chrome/renderer/lite_video/lite_video_hint_agent.h b/chromium/chrome/renderer/lite_video/lite_video_hint_agent.h
new file mode 100644
index 00000000000..023150bb979
--- /dev/null
+++ b/chromium/chrome/renderer/lite_video/lite_video_hint_agent.h
@@ -0,0 +1,94 @@
+// 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 CHROME_RENDERER_LITE_VIDEO_LITE_VIDEO_HINT_AGENT_H_
+#define CHROME_RENDERER_LITE_VIDEO_LITE_VIDEO_HINT_AGENT_H_
+
+#include "base/macros.h"
+#include "base/time/time.h"
+#include "chrome/renderer/lite_video/lite_video_url_loader_throttle.h"
+#include "content/public/renderer/render_frame_observer.h"
+#include "content/public/renderer/render_frame_observer_tracker.h"
+#include "third_party/blink/public/mojom/loader/previews_resource_loading_hints.mojom.h"
+#include "url/gurl.h"
+
+namespace lite_video {
+
+// The renderer-side agent for LiteVideos. There is one instance per frame (main
+// frame and subframes), to receive LiteVideo throttling parameters from
+// browser.
+class LiteVideoHintAgent
+ : public content::RenderFrameObserver,
+ public content::RenderFrameObserverTracker<LiteVideoHintAgent> {
+ public:
+ explicit LiteVideoHintAgent(content::RenderFrame* render_frame);
+ ~LiteVideoHintAgent() override;
+
+ LiteVideoHintAgent(const LiteVideoHintAgent&) = delete;
+ LiteVideoHintAgent& operator=(const LiteVideoHintAgent&) = delete;
+
+ // Returns how much time the media response should get throttled. This is the
+ // difference between the target latency based on target bandwidth, RTT, and
+ // the latency the response has already spent. Empty duration is returned when
+ // the response should not be throttled. The first
+ // |kilobytes_buffered_before_throttle_| for this render frame should not be
+ // throttled. This function also updates
+ // |kilobytes_buffered_before_throttle_|.
+ base::TimeDelta CalculateLatencyForResourceResponse(
+ const network::mojom::URLResponseHead& response_head);
+
+ // Updates the LiteVideo throttling parameters for calculating
+ // the latency to add to media requests.
+ void SetLiteVideoHint(blink::mojom::LiteVideoHintPtr lite_video_hint);
+
+ // Returns whether |this| has been provided a LiteVideoHint and
+ // has the parameters needed for calculating the throttling latency.
+ bool HasLiteVideoHint() const;
+
+ void AddThrottle(LiteVideoURLLoaderThrottle* throttle);
+ void RemoveThrottle(LiteVideoURLLoaderThrottle* throttle);
+
+ const std::set<LiteVideoURLLoaderThrottle*>& GetActiveThrottlesForTesting()
+ const {
+ return active_throttles_;
+ }
+
+ // Stop throttling and resume the current throttled media requests
+ // immediately. Throttling could start again for new requests
+ void StopThrottling();
+
+ private:
+ friend class LiteVideoHintAgentTest;
+
+ // content::RenderFrameObserver overrides
+ void OnDestruct() override;
+
+ // The network downlink bandwidth target in kilobytes per second used to
+ // calculate the throttling delay on media requests
+ base::Optional<int> target_downlink_bandwidth_kbps_;
+
+ // The network downlink rtt target latency used to calculate the
+ // throttling delay on media requests
+ base::Optional<base::TimeDelta> target_downlink_rtt_latency_;
+
+ // The number of kilobytes for media to be observed before starting to
+ // throttle requests.
+ base::Optional<int> kilobytes_to_buffer_before_throttle_;
+
+ // The maximum delay a throttle can introduce for a media request in
+ // milliseconds.
+ base::Optional<base::TimeDelta> max_throttling_delay_;
+
+ // The number of media KB that have been left unthrottled before starting
+ // to introduce a throttling delay.
+ int kilobytes_buffered_before_throttle_ = 0;
+
+ // Set of media requests that are throttled currently. These are maintained
+ // here to resume them immediately upon StopThrottling()
+ std::set<LiteVideoURLLoaderThrottle*> active_throttles_;
+};
+
+} // namespace lite_video
+
+#endif // CHROME_RENDERER_LITE_VIDEO_LITE_VIDEO_HINT_AGENT_H_
diff --git a/chromium/chrome/renderer/lite_video/lite_video_hint_agent_browsertest.cc b/chromium/chrome/renderer/lite_video/lite_video_hint_agent_browsertest.cc
new file mode 100644
index 00000000000..b22f60d9b5d
--- /dev/null
+++ b/chromium/chrome/renderer/lite_video/lite_video_hint_agent_browsertest.cc
@@ -0,0 +1,236 @@
+// 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 "chrome/renderer/lite_video/lite_video_hint_agent.h"
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
+#include "chrome/common/chrome_features.h"
+#include "chrome/renderer/lite_video/lite_video_url_loader_throttle.h"
+#include "chrome/test/base/chrome_render_view_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "content/public/renderer/render_frame.h"
+#include "content/public/renderer/render_view.h"
+#include "services/network/test/test_utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/platform/web_network_state_notifier.h"
+
+namespace lite_video {
+
+namespace {
+constexpr char kTestURL[] = "https://litevideo.test.com";
+
+}
+
+// Encapsulates the media URLLoader throttle, its delegate, and maintains the
+// current throttling state.
+class MediaLoaderThrottleInfo : public blink::URLLoaderThrottle::Delegate {
+ public:
+ explicit MediaLoaderThrottleInfo(
+ std::unique_ptr<LiteVideoURLLoaderThrottle> throttle)
+ : throttle_(std::move(throttle)) {
+ throttle_->set_delegate(this);
+ }
+
+ void SendResponse(network::mojom::URLResponseHead* response_head) {
+ throttle_->WillProcessResponse(GURL(kTestURL), response_head,
+ &is_throttled_);
+ }
+
+ // Implements blink::URLLoaderThrottle::Delegate.
+ void CancelWithError(int error_code,
+ base::StringPiece custom_reason) override {
+ NOTIMPLEMENTED();
+ }
+ void Resume() override {
+ ASSERT_TRUE(is_throttled_);
+ is_throttled_ = false;
+ }
+
+ bool is_throttled() { return is_throttled_; }
+
+ private:
+ // Current throttling state.
+ bool is_throttled_ = false;
+
+ std::unique_ptr<LiteVideoURLLoaderThrottle> throttle_;
+};
+
+class LiteVideoHintAgentTest : public ChromeRenderViewTest {
+ public:
+ void DisableLiteVideoFeature() {
+ scoped_feature_list_.Reset();
+ scoped_feature_list_.InitAndDisableFeature(features::kLiteVideo);
+ }
+
+ std::unique_ptr<LiteVideoURLLoaderThrottle> CreateLiteVideoURLLoaderThrottle(
+ blink::mojom::RequestContextType request_context_type) {
+ blink::WebURLRequest request;
+ request.SetUrl(GURL(kTestURL));
+ request.SetRequestContext(request_context_type);
+ return LiteVideoURLLoaderThrottle::MaybeCreateThrottle(
+ request, view_->GetMainRenderFrame()->GetRoutingID());
+ }
+
+ std::unique_ptr<MediaLoaderThrottleInfo> CreateThrottleAndSendResponse(
+ net::HttpStatusCode response_code,
+ const std::string& mime_type,
+ int content_length) {
+ auto throttle_info = std::make_unique<MediaLoaderThrottleInfo>(
+ CreateLiteVideoURLLoaderThrottle(
+ blink::mojom::RequestContextType::FETCH));
+ network::mojom::URLResponseHeadPtr response_head =
+ network::CreateURLResponseHead(response_code);
+ response_head->mime_type = mime_type;
+ response_head->mime_type = mime_type;
+ response_head->content_length = content_length;
+ response_head->network_accessed = true;
+ response_head->was_fetched_via_cache = false;
+
+ throttle_info->SendResponse(response_head.get());
+ return throttle_info;
+ }
+
+ const std::set<LiteVideoURLLoaderThrottle*>& GetActiveThrottledResponses()
+ const {
+ return lite_video_hint_agent_->GetActiveThrottlesForTesting();
+ }
+
+ const base::HistogramTester& histogram_tester() { return histogram_tester_; }
+
+ void StopThrottling() { lite_video_hint_agent_->StopThrottling(); }
+
+ protected:
+ void SetUp() override {
+ ChromeRenderViewTest::SetUp();
+ scoped_feature_list_.InitAndEnableFeature(features::kLiteVideo);
+ blink::WebNetworkStateNotifier::SetSaveDataEnabled(true);
+ lite_video_hint_agent_ =
+ new LiteVideoHintAgent(view_->GetMainRenderFrame());
+
+ // Set some default hints.
+ blink::mojom::LiteVideoHintPtr hint = blink::mojom::LiteVideoHint::New();
+ hint->kilobytes_to_buffer_before_throttle = 10;
+ hint->target_downlink_bandwidth_kbps = 60;
+ hint->target_downlink_rtt_latency = base::TimeDelta::FromMilliseconds(500);
+ hint->max_throttling_delay = base::TimeDelta::FromSeconds(5);
+ lite_video_hint_agent_->SetLiteVideoHint(std::move(hint));
+ }
+
+ private:
+ base::test::ScopedFeatureList scoped_feature_list_;
+
+ base::HistogramTester histogram_tester_;
+
+ // Owned by the RenderFrame.
+ LiteVideoHintAgent* lite_video_hint_agent_;
+};
+
+TEST_F(LiteVideoHintAgentTest, LiteVideoDisabled) {
+ DisableLiteVideoFeature();
+ EXPECT_FALSE(CreateLiteVideoURLLoaderThrottle(
+ blink::mojom::RequestContextType::FETCH));
+}
+
+TEST_F(LiteVideoHintAgentTest, SaveDataDisabled) {
+ blink::WebNetworkStateNotifier::SetSaveDataEnabled(false);
+ EXPECT_FALSE(CreateLiteVideoURLLoaderThrottle(
+ blink::mojom::RequestContextType::FETCH));
+}
+
+TEST_F(LiteVideoHintAgentTest, OnlyFetchAPIResponseThrottled) {
+ EXPECT_FALSE(CreateLiteVideoURLLoaderThrottle(
+ blink::mojom::RequestContextType::IMAGE));
+}
+
+TEST_F(LiteVideoHintAgentTest, OnlyMediaMimeTypeThrottled) {
+ histogram_tester().ExpectUniqueSample("LiteVideo.HintAgent.HasHint", true, 1);
+
+ auto throttle_info =
+ CreateThrottleAndSendResponse(net::HTTP_OK, "image/jpeg", 11000);
+ EXPECT_FALSE(throttle_info->is_throttled());
+
+ throttle_info =
+ CreateThrottleAndSendResponse(net::HTTP_OK, "image/jpeg", 11000);
+ EXPECT_FALSE(throttle_info->is_throttled());
+ histogram_tester().ExpectTotalCount("LiteVideo.URLLoader.ThrottleLatency", 0);
+}
+
+TEST_F(LiteVideoHintAgentTest, FailedMediaResponseNotThrottled) {
+ histogram_tester().ExpectUniqueSample("LiteVideo.HintAgent.HasHint", true, 1);
+
+ auto throttle_info = CreateThrottleAndSendResponse(
+ net::HTTP_INTERNAL_SERVER_ERROR, "video/mp4", 11000);
+ EXPECT_FALSE(throttle_info->is_throttled());
+
+ throttle_info = CreateThrottleAndSendResponse(net::HTTP_INTERNAL_SERVER_ERROR,
+ "video/mp4", 11000);
+ EXPECT_FALSE(throttle_info->is_throttled());
+ histogram_tester().ExpectTotalCount("LiteVideo.URLLoader.ThrottleLatency", 0);
+}
+
+TEST_F(LiteVideoHintAgentTest, MediaResponseThrottled) {
+ histogram_tester().ExpectUniqueSample("LiteVideo.HintAgent.HasHint", true, 1);
+
+ // Initial k media bytes will not be throttled.
+ auto throttle_info =
+ CreateThrottleAndSendResponse(net::HTTP_OK, "video/mp4", 11000);
+ EXPECT_FALSE(throttle_info->is_throttled());
+ histogram_tester().ExpectTotalCount("LiteVideo.URLLoader.ThrottleLatency", 0);
+ EXPECT_TRUE(GetActiveThrottledResponses().empty());
+
+ // Verify if a response gets throttled and eventually resumed.
+ throttle_info =
+ CreateThrottleAndSendResponse(net::HTTP_OK, "video/mp4", 440000);
+ histogram_tester().ExpectTotalCount("LiteVideo.URLLoader.ThrottleLatency", 1);
+ EXPECT_TRUE(throttle_info->is_throttled());
+ // This is to wait until the throttle resumes, cannot fast-forward in
+ // RenderViewTest.
+ while (throttle_info->is_throttled())
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(throttle_info->is_throttled());
+
+ // Verify a response that wasn't yet resumed, gets cleared from hint agent
+ // when its destroyed.
+ throttle_info =
+ CreateThrottleAndSendResponse(net::HTTP_OK, "video/mp4", 440000);
+ EXPECT_TRUE(throttle_info->is_throttled());
+ histogram_tester().ExpectTotalCount("LiteVideo.URLLoader.ThrottleLatency", 2);
+
+ EXPECT_FALSE(GetActiveThrottledResponses().empty());
+ throttle_info.reset();
+ EXPECT_TRUE(GetActiveThrottledResponses().empty());
+}
+
+TEST_F(LiteVideoHintAgentTest, StopThrottlingResumesResponsesImmediately) {
+ histogram_tester().ExpectUniqueSample("LiteVideo.HintAgent.HasHint", true, 1);
+
+ // Initial response is not throttled, and the next two are throttled.
+ auto throttle_info1 =
+ CreateThrottleAndSendResponse(net::HTTP_OK, "video/mp4", 11000);
+ auto throttle_info2 =
+ CreateThrottleAndSendResponse(net::HTTP_OK, "video/mp4", 11000);
+ auto throttle_info3 =
+ CreateThrottleAndSendResponse(net::HTTP_OK, "video/mp4", 11000);
+ EXPECT_FALSE(throttle_info1->is_throttled());
+ EXPECT_TRUE(throttle_info2->is_throttled());
+ EXPECT_TRUE(throttle_info3->is_throttled());
+ histogram_tester().ExpectTotalCount("LiteVideo.URLLoader.ThrottleLatency", 2);
+ EXPECT_EQ(2U, GetActiveThrottledResponses().size());
+
+ // Stop throttling will immediately resume.
+ StopThrottling();
+ EXPECT_FALSE(throttle_info2->is_throttled());
+ EXPECT_FALSE(throttle_info3->is_throttled());
+
+ // When the throttle destroys it should get removed from active throttles.
+ throttle_info2.reset();
+ throttle_info3.reset();
+ EXPECT_TRUE(GetActiveThrottledResponses().empty());
+}
+
+} // namespace lite_video
diff --git a/chromium/chrome/renderer/lite_video/lite_video_url_loader_throttle.cc b/chromium/chrome/renderer/lite_video/lite_video_url_loader_throttle.cc
new file mode 100644
index 00000000000..acde3638f64
--- /dev/null
+++ b/chromium/chrome/renderer/lite_video/lite_video_url_loader_throttle.cc
@@ -0,0 +1,121 @@
+// 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 "chrome/renderer/lite_video/lite_video_url_loader_throttle.h"
+
+#include "base/metrics/histogram_macros.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "chrome/renderer/lite_video/lite_video_hint_agent.h"
+#include "chrome/renderer/lite_video/lite_video_util.h"
+#include "content/public/renderer/render_frame.h"
+#include "content/public/renderer/render_thread.h"
+#include "services/network/public/mojom/url_response_head.mojom.h"
+
+namespace lite_video {
+
+LiteVideoHintAgent* GetLiteVideoHintAgent(int render_frame_id) {
+ DCHECK_NE(MSG_ROUTING_NONE, render_frame_id);
+ if (auto* render_frame =
+ content::RenderFrame::FromRoutingID(render_frame_id)) {
+ return LiteVideoHintAgent::Get(render_frame);
+ }
+ return nullptr;
+}
+
+// static
+std::unique_ptr<LiteVideoURLLoaderThrottle>
+LiteVideoURLLoaderThrottle::MaybeCreateThrottle(
+ const blink::WebURLRequest& request,
+ int render_frame_id) {
+ auto request_context = request.GetRequestContext();
+ if (request_context != blink::mojom::RequestContextType::FETCH &&
+ request_context != blink::mojom::RequestContextType::XML_HTTP_REQUEST) {
+ return nullptr;
+ }
+ // TODO(rajendrant): Also allow the throttle to be stopped when LiteMode gets
+ // disabled or ECT worsens. This logic should probably be in the browser
+ // process.
+ if (!IsLiteVideoEnabled())
+ return nullptr;
+
+ auto* lite_video_hint_agent = GetLiteVideoHintAgent(render_frame_id);
+ if (lite_video_hint_agent && lite_video_hint_agent->HasLiteVideoHint())
+ return std::make_unique<LiteVideoURLLoaderThrottle>(render_frame_id);
+
+ return nullptr;
+}
+
+LiteVideoURLLoaderThrottle::LiteVideoURLLoaderThrottle(int render_frame_id)
+ : render_frame_id_(render_frame_id) {
+ DCHECK(IsLiteVideoEnabled());
+}
+
+LiteVideoURLLoaderThrottle::~LiteVideoURLLoaderThrottle() {
+ // Existence of |response_delay_timer_| indicates throttling has been
+ // attempted on this media response. Remove the throttle on this case.
+ if (response_delay_timer_) {
+ DCHECK(render_frame_id_);
+ auto* lite_video_hint_agent = GetLiteVideoHintAgent(render_frame_id_);
+ if (lite_video_hint_agent)
+ lite_video_hint_agent->RemoveThrottle(this);
+ }
+}
+
+void LiteVideoURLLoaderThrottle::WillProcessResponse(
+ const GURL& response_url,
+ network::mojom::URLResponseHead* response_head,
+ bool* defer) {
+ if (!response_head || !response_head->headers)
+ return;
+ // Do not throttle on 4xx, 5xx failures.
+ if (response_head->headers->response_code() != 200)
+ return;
+ if (!response_head->network_accessed ||
+ response_head->was_fetched_via_cache) {
+ return;
+ }
+ if (!base::StartsWith(response_head->mime_type, "video/",
+ base::CompareCase::SENSITIVE)) {
+ return;
+ }
+
+ auto* lite_video_hint_agent = GetLiteVideoHintAgent(render_frame_id_);
+ if (!lite_video_hint_agent)
+ return;
+
+ auto latency = lite_video_hint_agent->CalculateLatencyForResourceResponse(
+ *response_head);
+ if (latency.is_zero())
+ return;
+
+ UMA_HISTOGRAM_TIMES("LiteVideo.URLLoader.ThrottleLatency", latency);
+
+ *defer = true;
+ // The timer may have already started and running, and the below restart will
+ // lose that elapsed time. However the elapsed time will be small since this
+ // case happens if some other url loader throttle is restarting the request.
+ response_delay_timer_ = std::make_unique<base::OneShotTimer>();
+ response_delay_timer_->Start(
+ FROM_HERE, latency,
+ base::BindOnce(&LiteVideoURLLoaderThrottle::ResumeThrottledMediaResponse,
+ base::Unretained(this)));
+
+ lite_video_hint_agent->AddThrottle(this);
+}
+
+void LiteVideoURLLoaderThrottle::ResumeIfThrottled() {
+ if (response_delay_timer_ && response_delay_timer_->IsRunning()) {
+ response_delay_timer_->Stop();
+ ResumeThrottledMediaResponse();
+ }
+}
+
+void LiteVideoURLLoaderThrottle::ResumeThrottledMediaResponse() {
+ DCHECK(!response_delay_timer_->IsRunning());
+ delegate_->Resume();
+}
+
+void LiteVideoURLLoaderThrottle::DetachFromCurrentSequence() {}
+
+} // namespace lite_video
diff --git a/chromium/chrome/renderer/lite_video/lite_video_url_loader_throttle.h b/chromium/chrome/renderer/lite_video/lite_video_url_loader_throttle.h
new file mode 100644
index 00000000000..ec353aa16c4
--- /dev/null
+++ b/chromium/chrome/renderer/lite_video/lite_video_url_loader_throttle.h
@@ -0,0 +1,56 @@
+// 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 CHROME_RENDERER_LITE_VIDEO_LITE_VIDEO_URL_LOADER_THROTTLE_H_
+#define CHROME_RENDERER_LITE_VIDEO_LITE_VIDEO_URL_LOADER_THROTTLE_H_
+
+#include "base/callback.h"
+#include "base/timer/timer.h"
+#include "third_party/blink/public/common/loader/url_loader_throttle.h"
+
+namespace blink {
+class WebURLRequest;
+} // namespace blink
+
+namespace lite_video {
+
+// This class throttles media url requests that have audio/video mime-type in
+// response headers, to simulate low bandwidth conditions. This allows MSE video
+// players to adapt and play the lower resolution videos.
+class LiteVideoURLLoaderThrottle : public blink::URLLoaderThrottle {
+ public:
+ explicit LiteVideoURLLoaderThrottle(int render_frame_id);
+ ~LiteVideoURLLoaderThrottle() override;
+
+ // Creates throttle for |request| if LiteVideo is enabled for LiteMode users,
+ // and LiteVideoHintAgent has received hints for the navigation. Throttle will
+ // be created only for Fetch/XHR requests.
+ static std::unique_ptr<LiteVideoURLLoaderThrottle> MaybeCreateThrottle(
+ const blink::WebURLRequest& request,
+ int render_frame_id);
+
+ // Resumes the media response if it was currently throttled. Otherwise its a
+ // no-op.
+ void ResumeIfThrottled();
+
+ // blink::URLLoaderThrottle:
+ void WillProcessResponse(const GURL& response_url,
+ network::mojom::URLResponseHead* response_head,
+ bool* defer) override;
+ void DetachFromCurrentSequence() override;
+
+ private:
+ // Resumes the media response immediately.
+ void ResumeThrottledMediaResponse();
+
+ // Render frame id to get the media throttle observer of the render frame.
+ const int render_frame_id_;
+
+ // Timer to introduce latency for the response.
+ std::unique_ptr<base::OneShotTimer> response_delay_timer_;
+};
+
+} // namespace lite_video
+
+#endif // CHROME_RENDERER_LITE_VIDEO_LITE_VIDEO_URL_LOADER_THROTTLE_H_
diff --git a/chromium/chrome/renderer/lite_video/lite_video_util.cc b/chromium/chrome/renderer/lite_video/lite_video_util.cc
new file mode 100644
index 00000000000..69c483cb1a1
--- /dev/null
+++ b/chromium/chrome/renderer/lite_video/lite_video_util.cc
@@ -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.
+
+#include "chrome/renderer/lite_video/lite_video_util.h"
+
+#include "chrome/common/chrome_features.h"
+#include "third_party/blink/public/platform/web_network_state_notifier.h"
+
+namespace lite_video {
+
+bool IsLiteVideoEnabled() {
+ return base::FeatureList::IsEnabled(features::kLiteVideo) &&
+ blink::WebNetworkStateNotifier::SaveDataEnabled();
+}
+
+} // namespace lite_video
diff --git a/chromium/chrome/renderer/lite_video/lite_video_util.h b/chromium/chrome/renderer/lite_video/lite_video_util.h
new file mode 100644
index 00000000000..35c4603be9d
--- /dev/null
+++ b/chromium/chrome/renderer/lite_video/lite_video_util.h
@@ -0,0 +1,15 @@
+// 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 CHROME_RENDERER_LITE_VIDEO_LITE_VIDEO_UTIL_H_
+#define CHROME_RENDERER_LITE_VIDEO_LITE_VIDEO_UTIL_H_
+
+namespace lite_video {
+
+// Returns whether LiteVideo is enabled.
+bool IsLiteVideoEnabled();
+
+} // namespace lite_video
+
+#endif // CHROME_RENDERER_LITE_VIDEO_LITE_VIDEO_UTIL_H_
diff --git a/chromium/chrome/renderer/media/OWNERS b/chromium/chrome/renderer/media/OWNERS
index e5a3f968d1c..3de875bc8e3 100644
--- a/chromium/chrome/renderer/media/OWNERS
+++ b/chromium/chrome/renderer/media/OWNERS
@@ -2,10 +2,6 @@ file://media/OWNERS
sergeyu@chromium.org
tommi@chromium.org
-# For Cast-related changes.
-per-file cast_*=miu@chromium.org
-per-file cast_*=mfoltz@chromium.org
-
# FlashEmbedRewrite
per-file flash_embed_rewrite*=mlamouri@chromium.org
diff --git a/chromium/chrome/renderer/media/cast_ipc_dispatcher.cc b/chromium/chrome/renderer/media/cast_ipc_dispatcher.cc
deleted file mode 100644
index 3025cc4fbc7..00000000000
--- a/chromium/chrome/renderer/media/cast_ipc_dispatcher.cc
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2014 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 "chrome/renderer/media/cast_ipc_dispatcher.h"
-
-#include "base/single_thread_task_runner.h"
-#include "chrome/common/cast_messages.h"
-#include "chrome/renderer/media/cast_transport_ipc.h"
-#include "ipc/ipc_message_macros.h"
-
-CastIPCDispatcher* CastIPCDispatcher::global_instance_ = NULL;
-
-CastIPCDispatcher::CastIPCDispatcher(
- const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner)
- : sender_(NULL),
- io_task_runner_(io_task_runner) {
- DCHECK(io_task_runner_.get());
- DCHECK(!global_instance_);
-}
-
-CastIPCDispatcher::~CastIPCDispatcher() {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
- DCHECK(!global_instance_);
-}
-
-CastIPCDispatcher* CastIPCDispatcher::Get() {
- return global_instance_;
-}
-
-void CastIPCDispatcher::Send(IPC::Message* message) {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
- if (sender_) {
- sender_->Send(message);
- } else {
- delete message;
- }
-}
-
-int32_t CastIPCDispatcher::AddSender(CastTransportIPC* sender) {
- return id_map_.Add(sender);
-}
-
-void CastIPCDispatcher::RemoveSender(int32_t channel_id) {
- return id_map_.Remove(channel_id);
-}
-
-bool CastIPCDispatcher::OnMessageReceived(const IPC::Message& message) {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(CastIPCDispatcher, message)
- IPC_MESSAGE_HANDLER(CastMsg_NotifyStatusChange, OnNotifyStatusChange)
- IPC_MESSAGE_HANDLER(CastMsg_RawEvents, OnRawEvents)
- IPC_MESSAGE_HANDLER(CastMsg_Rtt, OnRtt)
- IPC_MESSAGE_HANDLER(CastMsg_RtcpCastMessage, OnRtcpCastMessage)
- IPC_MESSAGE_HANDLER(CastMsg_Pli, OnReceivedPli);
- IPC_MESSAGE_HANDLER(CastMsg_ReceivedPacket, OnReceivedPacket)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-void CastIPCDispatcher::OnFilterAdded(IPC::Channel* channel) {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
- DCHECK(!global_instance_);
- global_instance_ = this;
- sender_ = channel;
-}
-
-void CastIPCDispatcher::OnFilterRemoved() {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
- DCHECK_EQ(this, global_instance_);
- global_instance_ = NULL;
- sender_ = NULL;
-}
-
-void CastIPCDispatcher::OnChannelClosing() {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
- DCHECK_EQ(this, global_instance_);
-}
-
-void CastIPCDispatcher::OnNotifyStatusChange(
- int32_t channel_id,
- media::cast::CastTransportStatus status) {
- CastTransportIPC* sender = id_map_.Lookup(channel_id);
- if (sender) {
- sender->OnNotifyStatusChange(status);
- } else {
- DVLOG(1)
- << "CastIPCDispatcher::OnNotifystatusChange on non-existing channel.";
- }
-}
-
-void CastIPCDispatcher::OnRawEvents(
- int32_t channel_id,
- const std::vector<media::cast::PacketEvent>& packet_events,
- const std::vector<media::cast::FrameEvent>& frame_events) {
- CastTransportIPC* sender = id_map_.Lookup(channel_id);
- if (sender) {
- sender->OnRawEvents(packet_events, frame_events);
- } else {
- DVLOG(1) << "CastIPCDispatcher::OnRawEvents on non-existing channel.";
- }
-}
-
-void CastIPCDispatcher::OnRtt(int32_t channel_id,
- uint32_t ssrc,
- base::TimeDelta rtt) {
- CastTransportIPC* sender = id_map_.Lookup(channel_id);
- if (sender) {
- sender->OnRtt(ssrc, rtt);
- } else {
- DVLOG(1) << "CastIPCDispatcher::OnRtt on non-existing channel.";
- }
-}
-
-void CastIPCDispatcher::OnRtcpCastMessage(
- int32_t channel_id,
- uint32_t ssrc,
- const media::cast::RtcpCastMessage& cast_message) {
- CastTransportIPC* sender = id_map_.Lookup(channel_id);
- if (sender) {
- sender->OnRtcpCastMessage(ssrc, cast_message);
- } else {
- DVLOG(1) << "CastIPCDispatcher::OnRtt on non-existing channel.";
- }
-}
-
-void CastIPCDispatcher::OnReceivedPli(int32_t channel_id, int32_t ssrc) {
- CastTransportIPC* sender = id_map_.Lookup(channel_id);
- if (sender) {
- sender->OnReceivedPli(ssrc);
- } else {
- DVLOG(1) << "CastIPCDispatcher::OnReceivedPli on non-existing "
- "channel.";
- }
-}
-
-void CastIPCDispatcher::OnReceivedPacket(int32_t channel_id,
- const media::cast::Packet& packet) {
- CastTransportIPC* sender = id_map_.Lookup(channel_id);
- if (sender) {
- sender->OnReceivedPacket(packet);
- } else {
- DVLOG(1) << "CastIPCDispatcher::OnReceievdPacket on non-existing channel.";
- }
-}
diff --git a/chromium/chrome/renderer/media/cast_ipc_dispatcher.h b/chromium/chrome/renderer/media/cast_ipc_dispatcher.h
deleted file mode 100644
index 32f898fddb2..00000000000
--- a/chromium/chrome/renderer/media/cast_ipc_dispatcher.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2014 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 CHROME_RENDERER_MEDIA_CAST_IPC_DISPATCHER_H_
-#define CHROME_RENDERER_MEDIA_CAST_IPC_DISPATCHER_H_
-
-#include <stdint.h>
-
-#include "base/callback.h"
-#include "base/containers/id_map.h"
-#include "base/macros.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "ipc/ipc_channel_proxy.h"
-#include "ipc/message_filter.h"
-#include "media/cast/cast_sender.h"
-#include "media/cast/logging/logging_defines.h"
-#include "media/cast/net/cast_transport.h"
-
-class CastTransportIPC;
-
-// This dispatcher listens to incoming IPC messages and sends
-// the call to the correct CastTransportIPC instance.
-class CastIPCDispatcher : public IPC::MessageFilter {
- public:
- explicit CastIPCDispatcher(
- const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner);
-
- static CastIPCDispatcher* Get();
- void Send(IPC::Message* message);
- int32_t AddSender(CastTransportIPC* sender);
- void RemoveSender(int32_t channel_id);
-
- // IPC::MessageFilter implementation
- bool OnMessageReceived(const IPC::Message& message) override;
- void OnFilterAdded(IPC::Channel* channel) override;
- void OnFilterRemoved() override;
- void OnChannelClosing() override;
-
- protected:
- ~CastIPCDispatcher() override;
-
- private:
- void OnNotifyStatusChange(int32_t channel_id,
- media::cast::CastTransportStatus status);
- void OnRtpStatistics(int32_t channel_id,
- bool audio,
- const media::cast::RtcpSenderInfo& sender_info,
- base::TimeTicks time_sent,
- uint32_t rtp_timestamp);
- void OnRawEvents(int32_t channel_id,
- const std::vector<media::cast::PacketEvent>& packet_events,
- const std::vector<media::cast::FrameEvent>& frame_events);
- void OnRtt(int32_t channel_id, uint32_t ssrc, base::TimeDelta rtt);
- void OnRtcpCastMessage(int32_t channel_id,
- uint32_t ssrc,
- const media::cast::RtcpCastMessage& cast_message);
- void OnReceivedPli(int32_t channel_id, int32_t ssrc);
- void OnReceivedPacket(int32_t channel_id, const media::cast::Packet& packet);
-
- static CastIPCDispatcher* global_instance_;
-
- // For IPC Send(); must only be accesed on |io_message_loop_|.
- IPC::Sender* sender_;
-
- // Task runner on which IPC calls are driven.
- const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
-
- // A map of stream ids to delegates; must only be accessed on
- // |io_message_loop_|.
- base::IDMap<CastTransportIPC*> id_map_;
- DISALLOW_COPY_AND_ASSIGN(CastIPCDispatcher);
-};
-
-#endif // CHROME_RENDERER_MEDIA_CAST_IPC_DISPATCHER_H_
diff --git a/chromium/chrome/renderer/media/cast_ipc_dispatcher_unittest.cc b/chromium/chrome/renderer/media/cast_ipc_dispatcher_unittest.cc
deleted file mode 100644
index 7dd002ae427..00000000000
--- a/chromium/chrome/renderer/media/cast_ipc_dispatcher_unittest.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2014 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 "chrome/renderer/media/cast_ipc_dispatcher.h"
-
-#include "base/test/simple_test_tick_clock.h"
-#include "base/test/task_environment.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "chrome/common/cast_messages.h"
-#include "ipc/ipc_message_macros.h"
-#include "media/cast/logging/logging_defines.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-class CastIPCDispatcherTest : public testing::Test {
- public:
- CastIPCDispatcherTest() {
- dispatcher_ = new CastIPCDispatcher(base::ThreadTaskRunnerHandle::Get());
- }
-
- protected:
- void FakeSend(const IPC::Message& message) {
- EXPECT_TRUE(dispatcher_->OnMessageReceived(message));
- }
-
- scoped_refptr<CastIPCDispatcher> dispatcher_;
- base::test::SingleThreadTaskEnvironment task_environment_{
- base::test::SingleThreadTaskEnvironment::MainThreadType::IO};
-};
-
-TEST_F(CastIPCDispatcherTest, RawEvents) {
- const int kChannelId = 17;
-
- media::cast::PacketEvent packet_event;
- packet_event.rtp_timestamp =
- media::cast::RtpTimeTicks().Expand(UINT32_C(100));
- packet_event.max_packet_id = 10;
- packet_event.packet_id = 5;
- packet_event.size = 512;
- packet_event.timestamp = base::SimpleTestTickClock().NowTicks();
- packet_event.type = media::cast::PACKET_SENT_TO_NETWORK;
- packet_event.media_type = media::cast::VIDEO_EVENT;
- std::vector<media::cast::PacketEvent> packet_events;
- packet_events.push_back(packet_event);
-
- media::cast::FrameEvent frame_event;
- frame_event.rtp_timestamp = media::cast::RtpTimeTicks().Expand(UINT32_C(100));
- frame_event.frame_id = media::cast::FrameId::first() + 5;
- frame_event.size = 512;
- frame_event.timestamp = base::SimpleTestTickClock().NowTicks();
- frame_event.media_type = media::cast::VIDEO_EVENT;
- std::vector<media::cast::FrameEvent> frame_events;
- frame_events.push_back(frame_event);
-
- packet_events.push_back(packet_event);
- CastMsg_RawEvents raw_events_msg(kChannelId, packet_events,
- frame_events);
-
- FakeSend(raw_events_msg);
-}
-
-} // namespace
diff --git a/chromium/chrome/renderer/media/cast_receiver_audio_valve.cc b/chromium/chrome/renderer/media/cast_receiver_audio_valve.cc
deleted file mode 100644
index c2d5b856727..00000000000
--- a/chromium/chrome/renderer/media/cast_receiver_audio_valve.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2015 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 "chrome/renderer/media/cast_receiver_audio_valve.h"
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "media/base/audio_parameters.h"
-
-CastReceiverAudioValve::CastReceiverAudioValve(
- const media::AudioParameters& params,
- media::AudioCapturerSource::CaptureCallback* cb)
- : cb_(cb),
- fifo_(base::Bind(&CastReceiverAudioValve::DeliverRebufferedAudio,
- base::Unretained(this))),
- sample_rate_(params.sample_rate()) {
- fifo_.Reset(params.frames_per_buffer());
-}
-
-CastReceiverAudioValve::~CastReceiverAudioValve() {}
-
-void CastReceiverAudioValve::DeliverDecodedAudio(
- const media::AudioBus* audio_bus,
- base::TimeTicks playout_time) {
- current_playout_time_ = playout_time;
- // The following will result in zero, one, or multiple synchronous calls to
- // DeliverRebufferedAudio().
- fifo_.Push(*audio_bus);
-}
-
-void CastReceiverAudioValve::DeliverRebufferedAudio(
- const media::AudioBus& audio_bus,
- int frame_delay) {
- const base::TimeTicks playout_time =
- current_playout_time_ +
- base::TimeDelta::FromMicroseconds(
- frame_delay * base::Time::kMicrosecondsPerSecond / sample_rate_);
-
- base::AutoLock lock(lock_);
- if (cb_) {
- cb_->Capture(&audio_bus, playout_time, 1.0 /* volume */,
- false /* key_pressed */);
- }
-}
-
-void CastReceiverAudioValve::Stop() {
- base::AutoLock lock(lock_);
- cb_ = nullptr;
-}
diff --git a/chromium/chrome/renderer/media/cast_receiver_audio_valve.h b/chromium/chrome/renderer/media/cast_receiver_audio_valve.h
deleted file mode 100644
index f6c09a74a26..00000000000
--- a/chromium/chrome/renderer/media/cast_receiver_audio_valve.h
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2015 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 CHROME_RENDERER_MEDIA_CAST_RECEIVER_AUDIO_VALVE_H_
-#define CHROME_RENDERER_MEDIA_CAST_RECEIVER_AUDIO_VALVE_H_
-
-#include "base/synchronization/lock.h"
-#include "base/time/time.h"
-#include "media/base/audio_capturer_source.h"
-#include "media/base/audio_push_fifo.h"
-
-namespace media {
-class AudioBus;
-}
-
-// Forwards calls to |cb| until Stop is called. If the client requested a
-// different buffer size than that provided by the Cast Receiver, AudioPushFifo
-// is used to rectify that.
-//
-// Thread-safe.
-// All functions may block depending on contention.
-class CastReceiverAudioValve :
- public base::RefCountedThreadSafe<CastReceiverAudioValve> {
- public:
- CastReceiverAudioValve(const media::AudioParameters& params,
- media::AudioCapturerSource::CaptureCallback* cb);
-
- // Called on an unknown thread to provide more decoded audio data from the
- // Cast Receiver.
- void DeliverDecodedAudio(const media::AudioBus* audio_bus,
- base::TimeTicks playout_time);
-
- // When this returns, no more calls will be forwarded to |cb|.
- void Stop();
-
- private:
- friend class base::RefCountedThreadSafe<CastReceiverAudioValve>;
-
- ~CastReceiverAudioValve();
-
- // Called by AudioPushFifo zero or more times during the call to Capture().
- // Delivers audio data in the required buffer size to |cb_|.
- void DeliverRebufferedAudio(const media::AudioBus& audio_bus,
- int frame_delay);
-
- media::AudioCapturerSource::CaptureCallback* cb_;
- base::Lock lock_;
-
- media::AudioPushFifo fifo_;
- const int sample_rate_;
-
- // Used to pass the current playout time between DeliverDecodedAudio() and
- // DeviliverRebufferedAudio().
- base::TimeTicks current_playout_time_;
-};
-
-#endif // CHROME_RENDERER_MEDIA_CAST_RECEIVER_AUDIO_VALVE_H_
diff --git a/chromium/chrome/renderer/media/cast_receiver_session.cc b/chromium/chrome/renderer/media/cast_receiver_session.cc
deleted file mode 100644
index 659bf04ca4d..00000000000
--- a/chromium/chrome/renderer/media/cast_receiver_session.cc
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright 2015 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 "chrome/renderer/media/cast_receiver_session.h"
-
-#include <memory>
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "chrome/renderer/media/cast_receiver_audio_valve.h"
-#include "content/public/renderer/render_thread.h"
-#include "media/base/audio_capturer_source.h"
-#include "media/base/bind_to_current_loop.h"
-#include "media/capture/video_capturer_source.h"
-#include "third_party/blink/public/platform/web_media_stream.h"
-#include "third_party/blink/public/platform/web_media_stream_source.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
-
-// This is a render thread object.
-class CastReceiverSession::AudioCapturerSource :
- public media::AudioCapturerSource {
- public:
- AudioCapturerSource(
- const scoped_refptr<CastReceiverSession> cast_receiver_session);
- void Initialize(const media::AudioParameters& params,
- CaptureCallback* callback) override;
- void Start() override;
- void Stop() override;
- void SetVolume(double volume) override;
- void SetAutomaticGainControl(bool enable) override;
- void SetOutputDeviceForAec(const std::string& output_device_id) override;
-
- private:
- ~AudioCapturerSource() override;
- const scoped_refptr<CastReceiverSession> cast_receiver_session_;
- scoped_refptr<CastReceiverAudioValve> audio_valve_;
-};
-
-// This is a render thread object.
-class CastReceiverSession::VideoCapturerSource
- : public media::VideoCapturerSource {
- public:
- explicit VideoCapturerSource(
- const scoped_refptr<CastReceiverSession> cast_receiver_session);
- protected:
- media::VideoCaptureFormats GetPreferredFormats() override;
- void StartCapture(const media::VideoCaptureParams& params,
- const VideoCaptureDeliverFrameCB& frame_callback,
- const RunningCallback& running_callback) override;
- void StopCapture() override;
- private:
- const scoped_refptr<CastReceiverSession> cast_receiver_session_;
-};
-
-CastReceiverSession::CastReceiverSession()
- : delegate_(new CastReceiverSessionDelegate()),
- io_task_runner_(content::RenderThread::Get()->GetIOTaskRunner()) {}
-
-CastReceiverSession::~CastReceiverSession() {
- // We should always be able to delete the object on the IO thread.
- CHECK(io_task_runner_->DeleteSoon(FROM_HERE, delegate_.release()));
-}
-
-void CastReceiverSession::Start(
- const media::cast::FrameReceiverConfig& audio_config,
- const media::cast::FrameReceiverConfig& video_config,
- const net::IPEndPoint& local_endpoint,
- const net::IPEndPoint& remote_endpoint,
- std::unique_ptr<base::DictionaryValue> options,
- const media::VideoCaptureFormat& capture_format,
- const StartCB& start_callback,
- const CastReceiverSessionDelegate::ErrorCallback& error_callback) {
- audio_config_ = audio_config;
- video_config_ = video_config;
- format_ = capture_format;
- io_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&CastReceiverSessionDelegate::Start,
- base::Unretained(delegate_.get()), audio_config,
- video_config, local_endpoint, remote_endpoint,
- std::move(options), format_,
- media::BindToCurrentLoop(error_callback)));
- scoped_refptr<media::AudioCapturerSource> audio(
- new CastReceiverSession::AudioCapturerSource(this));
- std::unique_ptr<media::VideoCapturerSource> video(
- new CastReceiverSession::VideoCapturerSource(this));
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(start_callback, audio, std::move(video)));
-}
-
-void CastReceiverSession::StartAudio(
- scoped_refptr<CastReceiverAudioValve> audio_valve) {
- io_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&CastReceiverSessionDelegate::StartAudio,
- base::Unretained(delegate_.get()), audio_valve));
-}
-
-void CastReceiverSession::StartVideo(
- blink::VideoCaptureDeliverFrameCB frame_callback) {
- io_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&CastReceiverSessionDelegate::StartVideo,
- base::Unretained(delegate_.get()), frame_callback));
-}
-
-void CastReceiverSession::StopVideo() {
- io_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&CastReceiverSessionDelegate::StopVideo,
- base::Unretained(delegate_.get())));
-}
-
-CastReceiverSession::VideoCapturerSource::VideoCapturerSource(
- const scoped_refptr<CastReceiverSession> cast_receiver_session)
- : cast_receiver_session_(cast_receiver_session) {
-}
-
-media::VideoCaptureFormats
-CastReceiverSession::VideoCapturerSource::GetPreferredFormats() {
- media::VideoCaptureFormats formats;
- if (cast_receiver_session_->format_.IsValid())
- formats.push_back(cast_receiver_session_->format_);
- return formats;
-}
-
-void CastReceiverSession::VideoCapturerSource::StartCapture(
- const media::VideoCaptureParams& params,
- const VideoCaptureDeliverFrameCB& frame_callback,
- const RunningCallback& running_callback) {
- cast_receiver_session_->StartVideo(frame_callback);
- running_callback.Run(true);
-}
-
-void CastReceiverSession::VideoCapturerSource::StopCapture() {
- cast_receiver_session_->StopVideo();
-}
-
-CastReceiverSession::AudioCapturerSource::AudioCapturerSource(
- const scoped_refptr<CastReceiverSession> cast_receiver_session)
- : cast_receiver_session_(cast_receiver_session) {
-}
-
-CastReceiverSession::AudioCapturerSource::~AudioCapturerSource() {
- DCHECK(!audio_valve_);
-}
-
-void CastReceiverSession::AudioCapturerSource::Initialize(
- const media::AudioParameters& params,
- CaptureCallback* callback) {
- // TODO(hubbe): Consider converting the audio to whatever the caller wants.
- if (params.sample_rate() !=
- cast_receiver_session_->audio_config_.rtp_timebase ||
- params.channels() != cast_receiver_session_->audio_config_.channels) {
- callback->OnCaptureError(std::string());
- return;
- }
- audio_valve_ = new CastReceiverAudioValve(params, callback);
-}
-
-void CastReceiverSession::AudioCapturerSource::Start() {
- DCHECK(audio_valve_);
- cast_receiver_session_->StartAudio(audio_valve_);
-}
-
-void CastReceiverSession::AudioCapturerSource::Stop() {
- audio_valve_->Stop();
- audio_valve_ = nullptr;
-}
-
-void CastReceiverSession::AudioCapturerSource::SetVolume(double volume) {
- // not supported
-}
-
-void CastReceiverSession::AudioCapturerSource::SetAutomaticGainControl(
- bool enable) {
- // not supported
-}
-
-void CastReceiverSession::AudioCapturerSource::SetOutputDeviceForAec(
- const std::string& output_device_id) {
- // not supported
-}
diff --git a/chromium/chrome/renderer/media/cast_receiver_session.h b/chromium/chrome/renderer/media/cast_receiver_session.h
deleted file mode 100644
index c9bfa5a1181..00000000000
--- a/chromium/chrome/renderer/media/cast_receiver_session.h
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2015 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 CHROME_RENDERER_MEDIA_CAST_RECEIVER_SESSION_H_
-#define CHROME_RENDERER_MEDIA_CAST_RECEIVER_SESSION_H_
-
-#include <memory>
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/single_thread_task_runner.h"
-#include "chrome/renderer/media/cast_receiver_session_delegate.h"
-
-namespace media {
-class AudioCapturerSource;
-struct VideoCaptureFormat;
-class VideoCapturerSource;
-}
-
-namespace net {
-class IPEndPoint;
-}
-
-namespace base {
-class DictionaryValue;
-}
-
-// This a render thread object, all methods, construction and
-// destruction must happen on the render thread.
-class CastReceiverSession : public base::RefCounted<CastReceiverSession> {
- public:
- CastReceiverSession();
-
- typedef base::Callback<void(scoped_refptr<media::AudioCapturerSource>,
- std::unique_ptr<media::VideoCapturerSource>)>
- StartCB;
-
- // Note that the cast receiver will start responding to
- // incoming network streams immediately, buffering input until
- // StartAudio/StartVideo is called.
- // Five first parameters are passed to cast receiver.
- // |start_callback| is called when initialization is done.
- // TODO(hubbe): Currently the audio component of the returned media
- // stream only the exact format that the sender is sending us.
- void Start(const media::cast::FrameReceiverConfig& audio_config,
- const media::cast::FrameReceiverConfig& video_config,
- const net::IPEndPoint& local_endpoint,
- const net::IPEndPoint& remote_endpoint,
- std::unique_ptr<base::DictionaryValue> options,
- const media::VideoCaptureFormat& capture_format,
- const StartCB& start_callback,
- const CastReceiverSessionDelegate::ErrorCallback& error_callback);
-
- private:
- class VideoCapturerSource;
- class AudioCapturerSource;
- friend class base::RefCounted<CastReceiverSession>;
- virtual ~CastReceiverSession();
- void StartAudio(scoped_refptr<CastReceiverAudioValve> audio_valve);
-
- void StartVideo(blink::VideoCaptureDeliverFrameCB frame_callback);
- // Stop Video callbacks.
- // Note that this returns immediately, but callbacks do not stop immediately.
- void StopVideo();
-
- media::cast::FrameReceiverConfig audio_config_;
- media::cast::FrameReceiverConfig video_config_;
- std::unique_ptr<CastReceiverSessionDelegate> delegate_;
- const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
- media::VideoCaptureFormat format_;
-
- DISALLOW_COPY_AND_ASSIGN(CastReceiverSession);
-};
-
-#endif // CHROME_RENDERER_MEDIA_CAST_RECEIVER_SESSION_H_
diff --git a/chromium/chrome/renderer/media/cast_receiver_session_delegate.cc b/chromium/chrome/renderer/media/cast_receiver_session_delegate.cc
deleted file mode 100644
index c6b6a1053b9..00000000000
--- a/chromium/chrome/renderer/media/cast_receiver_session_delegate.cc
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2015 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 "chrome/renderer/media/cast_receiver_session_delegate.h"
-
-#include <memory>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/values.h"
-
-CastReceiverSessionDelegate::CastReceiverSessionDelegate() {}
-CastReceiverSessionDelegate::~CastReceiverSessionDelegate() {}
-
-void CastReceiverSessionDelegate::Start(
- const media::cast::FrameReceiverConfig& audio_config,
- const media::cast::FrameReceiverConfig& video_config,
- const net::IPEndPoint& local_endpoint,
- const net::IPEndPoint& remote_endpoint,
- std::unique_ptr<base::DictionaryValue> options,
- const media::VideoCaptureFormat& format,
- const ErrorCallback& error_callback) {
- format_ = format;
- DCHECK(io_task_runner_->BelongsToCurrentThread());
- CastSessionDelegateBase::StartUDP(local_endpoint, remote_endpoint,
- std::move(options), error_callback);
- cast_receiver_ = media::cast::CastReceiver::Create(cast_environment_,
- audio_config,
- video_config,
- cast_transport_.get());
- on_audio_decoded_cb_ =
- base::BindRepeating(&CastReceiverSessionDelegate::OnDecodedAudioFrame,
- weak_factory_.GetWeakPtr());
- on_video_decoded_cb_ =
- base::BindRepeating(&CastReceiverSessionDelegate::OnDecodedVideoFrame,
- weak_factory_.GetWeakPtr());
-}
-
-void CastReceiverSessionDelegate::ReceivePacket(
- std::unique_ptr<media::cast::Packet> packet) {
- cast_receiver_->ReceivePacket(std::move(packet));
-}
-
-void CastReceiverSessionDelegate::StartAudio(
- scoped_refptr<CastReceiverAudioValve> audio_valve) {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
- audio_valve_ = audio_valve;
- cast_receiver_->RequestDecodedAudioFrame(on_audio_decoded_cb_);
-}
-
-void CastReceiverSessionDelegate::OnDecodedAudioFrame(
- std::unique_ptr<media::AudioBus> audio_bus,
- base::TimeTicks playout_time,
- bool is_continuous) {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
- if (!audio_valve_)
- return;
-
- // We're on the IO thread, which doesn't allow blocking
- // operations. Since we don't know what the Capture callback
- // will do exactly, we need to jump to a different thread.
- // Let's re-use the audio decoder thread.
- cast_environment_->PostTask(
- media::cast::CastEnvironment::AUDIO, FROM_HERE,
- base::BindOnce(&CastReceiverAudioValve::DeliverDecodedAudio, audio_valve_,
- base::Owned(audio_bus.release()), playout_time));
- cast_receiver_->RequestDecodedAudioFrame(on_audio_decoded_cb_);
-}
-
-void CastReceiverSessionDelegate::StartVideo(
- blink::VideoCaptureDeliverFrameCB video_callback) {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
- frame_callback_ = video_callback;
- cast_receiver_->RequestDecodedVideoFrame(on_video_decoded_cb_);
-}
-
-void CastReceiverSessionDelegate::StopVideo() {
- frame_callback_ = blink::VideoCaptureDeliverFrameCB();
-}
-
-void CastReceiverSessionDelegate::OnDecodedVideoFrame(
- scoped_refptr<media::VideoFrame> video_frame,
- base::TimeTicks playout_time,
- bool is_continuous) {
- if (frame_callback_.is_null())
- return;
- frame_callback_.Run(std::move(video_frame), playout_time);
- cast_receiver_->RequestDecodedVideoFrame(on_video_decoded_cb_);
-}
diff --git a/chromium/chrome/renderer/media/cast_receiver_session_delegate.h b/chromium/chrome/renderer/media/cast_receiver_session_delegate.h
deleted file mode 100644
index e7708cb3e2f..00000000000
--- a/chromium/chrome/renderer/media/cast_receiver_session_delegate.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2015 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 CHROME_RENDERER_MEDIA_CAST_RECEIVER_SESSION_DELEGATE_H_
-#define CHROME_RENDERER_MEDIA_CAST_RECEIVER_SESSION_DELEGATE_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "chrome/renderer/media/cast_receiver_audio_valve.h"
-#include "chrome/renderer/media/cast_session_delegate.h"
-#include "media/capture/video_capture_types.h"
-#include "media/cast/cast_receiver.h"
-#include "third_party/blink/public/common/media/video_capture.h"
-
-class CastReceiverSessionDelegate : public CastSessionDelegateBase {
- public:
- typedef base::Callback<void(const std::string&)> ErrorCallback;
-
- CastReceiverSessionDelegate();
- ~CastReceiverSessionDelegate() override;
-
- void ReceivePacket(std::unique_ptr<media::cast::Packet> packet) override;
-
- void Start(const media::cast::FrameReceiverConfig& audio_config,
- const media::cast::FrameReceiverConfig& video_config,
- const net::IPEndPoint& local_endpoint,
- const net::IPEndPoint& remote_endpoint,
- std::unique_ptr<base::DictionaryValue> options,
- const media::VideoCaptureFormat& format,
- const ErrorCallback& error_callback);
-
- void StartAudio(scoped_refptr<CastReceiverAudioValve> audio_valve);
-
- void StartVideo(blink::VideoCaptureDeliverFrameCB frame_callback);
- // Stop Video callbacks (eventually).
- void StopVideo();
-
- private:
- void OnDecodedAudioFrame(std::unique_ptr<media::AudioBus> audio_bus,
- base::TimeTicks playout_time,
- bool is_continuous);
-
- void OnDecodedVideoFrame(scoped_refptr<media::VideoFrame> video_frame,
- base::TimeTicks playout_time,
- bool is_continuous);
-
- scoped_refptr<CastReceiverAudioValve> audio_valve_;
- blink::VideoCaptureDeliverFrameCB frame_callback_;
- media::cast::AudioFrameDecodedCallback on_audio_decoded_cb_;
- media::cast::VideoFrameDecodedCallback on_video_decoded_cb_;
- std::unique_ptr<media::cast::CastReceiver> cast_receiver_;
- media::VideoCaptureFormat format_;
- base::WeakPtrFactory<CastReceiverSessionDelegate> weak_factory_{this};
- DISALLOW_COPY_AND_ASSIGN(CastReceiverSessionDelegate);
-};
-
-#endif // CHROME_RENDERER_MEDIA_CAST_RECEIVER_SESSION_DELEGATE_H_
diff --git a/chromium/chrome/renderer/media/cast_rtp_stream.cc b/chromium/chrome/renderer/media/cast_rtp_stream.cc
deleted file mode 100644
index 1deb6336bbd..00000000000
--- a/chromium/chrome/renderer/media/cast_rtp_stream.cc
+++ /dev/null
@@ -1,578 +0,0 @@
-// Copyright 2013 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 "chrome/renderer/media/cast_rtp_stream.h"
-
-#include <stdint.h>
-
-#include <algorithm>
-#include <memory>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/timer/timer.h"
-#include "base/trace_event/trace_event.h"
-#include "base/values.h"
-#include "chrome/common/chrome_switches.h"
-#include "chrome/renderer/media/cast_session.h"
-#include "chrome/renderer/media/cast_udp_transport.h"
-#include "content/public/renderer/render_thread.h"
-#include "content/public/renderer/video_encode_accelerator.h"
-#include "media/base/audio_bus.h"
-#include "media/base/audio_converter.h"
-#include "media/base/audio_parameters.h"
-#include "media/base/bind_to_current_loop.h"
-#include "media/base/limits.h"
-#include "media/base/video_frame.h"
-#include "media/base/video_util.h"
-#include "media/cast/cast_config.h"
-#include "media/cast/cast_sender.h"
-#include "media/cast/net/cast_transport_config.h"
-#include "third_party/blink/public/platform/modules/mediastream/web_media_stream_audio_sink.h"
-#include "third_party/blink/public/platform/modules/mediastream/web_media_stream_sink.h"
-#include "third_party/blink/public/platform/web_media_stream_source.h"
-#include "third_party/blink/public/web/modules/mediastream/web_media_stream_utils.h"
-#include "ui/gfx/geometry/size.h"
-
-using media::cast::FrameSenderConfig;
-
-namespace {
-
-// The maximum number of milliseconds that should elapse since the last video
-// frame was received from the video source, before requesting refresh frames.
-const int kRefreshIntervalMilliseconds = 250;
-
-// The maximum number of refresh video frames to request/receive. After this
-// limit (60 * 250ms = 15 seconds), refresh frame requests will stop being made.
-const int kMaxConsecutiveRefreshFrames = 60;
-
-FrameSenderConfig DefaultOpusConfig() {
- FrameSenderConfig config;
- config.rtp_payload_type = media::cast::RtpPayloadType::AUDIO_OPUS;
- config.sender_ssrc = 1;
- config.receiver_ssrc = 2;
- config.rtp_timebase = media::cast::kDefaultAudioSamplingRate;
- config.channels = 2;
- config.min_bitrate = config.max_bitrate = config.start_bitrate =
- media::cast::kDefaultAudioEncoderBitrate;
- config.max_frame_rate = 100; // 10 ms audio frames
- config.codec = media::cast::CODEC_AUDIO_OPUS;
- return config;
-}
-
-FrameSenderConfig DefaultVp8Config() {
- FrameSenderConfig config;
- config.rtp_payload_type = media::cast::RtpPayloadType::VIDEO_VP8;
- config.sender_ssrc = 11;
- config.receiver_ssrc = 12;
- config.rtp_timebase = media::cast::kVideoFrequency;
- config.channels = 1;
- config.max_bitrate = media::cast::kDefaultMaxVideoBitrate;
- config.min_bitrate = media::cast::kDefaultMinVideoBitrate;
- config.max_frame_rate = media::cast::kDefaultMaxFrameRate;
- config.codec = media::cast::CODEC_VIDEO_VP8;
- return config;
-}
-
-FrameSenderConfig DefaultH264Config() {
- FrameSenderConfig config;
- config.rtp_payload_type = media::cast::RtpPayloadType::VIDEO_H264;
- config.sender_ssrc = 11;
- config.receiver_ssrc = 12;
- config.rtp_timebase = media::cast::kVideoFrequency;
- config.channels = 1;
- config.max_bitrate = media::cast::kDefaultMaxVideoBitrate;
- config.min_bitrate = media::cast::kDefaultMinVideoBitrate;
- config.max_frame_rate = media::cast::kDefaultMaxFrameRate;
- config.codec = media::cast::CODEC_VIDEO_H264;
- return config;
-}
-
-FrameSenderConfig DefaultRemotingAudioConfig() {
- FrameSenderConfig config;
- config.rtp_payload_type = media::cast::RtpPayloadType::REMOTE_AUDIO;
- config.sender_ssrc = 3;
- config.receiver_ssrc = 4;
- config.codec = media::cast::CODEC_AUDIO_REMOTE;
- config.rtp_timebase = media::cast::kRemotingRtpTimebase;
- config.max_bitrate = 1000000;
- config.min_bitrate = 0;
- config.channels = 2;
- config.max_frame_rate = 100; // 10 ms audio frames
-
- return config;
-}
-
-FrameSenderConfig DefaultRemotingVideoConfig() {
- FrameSenderConfig config;
- config.rtp_payload_type = media::cast::RtpPayloadType::REMOTE_VIDEO;
- config.sender_ssrc = 13;
- config.receiver_ssrc = 14;
- config.codec = media::cast::CODEC_VIDEO_REMOTE;
- config.rtp_timebase = media::cast::kRemotingRtpTimebase;
- config.max_bitrate = 10000000;
- config.min_bitrate = 0;
- config.channels = 1;
- config.max_frame_rate = media::cast::kDefaultMaxFrameRate;
- return config;
-}
-
-std::vector<FrameSenderConfig> SupportedAudioConfigs(bool for_remoting_stream) {
- if (for_remoting_stream)
- return {DefaultRemotingAudioConfig()};
- else
- return {DefaultOpusConfig()};
-}
-
-std::vector<FrameSenderConfig> SupportedVideoConfigs(bool for_remoting_stream) {
- if (for_remoting_stream)
- return {DefaultRemotingVideoConfig()};
-
- std::vector<FrameSenderConfig> supported_configs;
- // Prefer VP8 over H.264 for hardware encoder.
- if (CastRtpStream::IsHardwareVP8EncodingSupported())
- supported_configs.push_back(DefaultVp8Config());
- if (CastRtpStream::IsHardwareH264EncodingSupported())
- supported_configs.push_back(DefaultH264Config());
-
- // Propose the default software VP8 encoder, if no hardware encoders are
- // available.
- if (supported_configs.empty())
- supported_configs.push_back(DefaultVp8Config());
-
- return supported_configs;
-}
-
-} // namespace
-
-// This class receives MediaStreamTrack events and video frames from a
-// MediaStreamVideoTrack. It also includes a timer to request refresh frames
-// when the capturer halts (e.g., a screen capturer stops delivering frames
-// because the screen is not being updated). When a halt is detected, refresh
-// frames will be requested at regular intervals for a short period of time.
-// This provides the video encoder, downstream, several copies of the last frame
-// so that it may clear up lossy encoding artifacts.
-//
-// Threading: Video frames are received on the IO thread and then
-// forwarded to media::cast::VideoFrameInput. The inner class, Deliverer,
-// handles this. Otherwise, all methods and member variables of the outer class
-// must only be accessed on the render thread.
-class CastVideoSink : public base::SupportsWeakPtr<CastVideoSink>,
- public blink::WebMediaStreamSink {
- public:
- // |track| provides data for this sink.
- // |error_callback| is called if video formats don't match.
- CastVideoSink(const blink::WebMediaStreamTrack& track,
- CastRtpStream::ErrorCallback error_callback)
- : track_(track),
- deliverer_(base::MakeRefCounted<Deliverer>(std::move(error_callback))),
- consecutive_refresh_count_(0),
- expecting_a_refresh_frame_(false),
- is_connected_to_track_(false) {}
-
- ~CastVideoSink() override {
- if (is_connected_to_track_)
- blink::RemoveSinkFromMediaStreamTrack(track_, this);
- }
-
- // Attach this sink to a video track represented by |track_|.
- // Data received from the track will be submitted to |frame_input|.
- void AddToTrack(
- bool is_sink_secure,
- const scoped_refptr<media::cast::VideoFrameInput>& frame_input) {
- DCHECK(deliverer_);
- deliverer_->WillConnectToTrack(AsWeakPtr(), frame_input);
- refresh_timer_.Start(
- FROM_HERE,
- base::TimeDelta::FromMilliseconds(kRefreshIntervalMilliseconds),
- base::Bind(&CastVideoSink::OnRefreshTimerFired,
- base::Unretained(this)));
- blink::AddSinkToMediaStreamTrack(
- track_, this, base::BindRepeating(&Deliverer::OnVideoFrame, deliverer_),
- is_sink_secure);
- is_connected_to_track_ = true;
- }
-
- private:
- class Deliverer : public base::RefCountedThreadSafe<Deliverer> {
- public:
- explicit Deliverer(CastRtpStream::ErrorCallback error_callback)
- : main_task_runner_(base::ThreadTaskRunnerHandle::Get()),
- error_callback_(std::move(error_callback)) {}
-
- void WillConnectToTrack(
- base::WeakPtr<CastVideoSink> sink,
- scoped_refptr<media::cast::VideoFrameInput> frame_input) {
- DCHECK(main_task_runner_->RunsTasksInCurrentSequence());
- sink_ = sink;
- frame_input_ = std::move(frame_input);
- }
-
- void OnVideoFrame(scoped_refptr<media::VideoFrame> video_frame,
- base::TimeTicks estimated_capture_time) {
- main_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&CastVideoSink::DidReceiveFrame, sink_));
-
- const base::TimeTicks timestamp = estimated_capture_time.is_null()
- ? base::TimeTicks::Now()
- : estimated_capture_time;
-
- if (!(video_frame->format() == media::PIXEL_FORMAT_I420 ||
- video_frame->format() == media::PIXEL_FORMAT_YV12 ||
- video_frame->format() == media::PIXEL_FORMAT_I420A)) {
- error_callback_.Run("Incompatible video frame format.");
- return;
- }
- scoped_refptr<media::VideoFrame> frame = video_frame;
- // Drop alpha channel since we do not support it yet.
- if (frame->format() == media::PIXEL_FORMAT_I420A)
- frame = media::WrapAsI420VideoFrame(std::move(video_frame));
-
- // Used by chrome/browser/extension/api/cast_streaming/performance_test.cc
- TRACE_EVENT_INSTANT2("cast_perf_test", "ConsumeVideoFrame",
- TRACE_EVENT_SCOPE_THREAD, "timestamp",
- (timestamp - base::TimeTicks()).InMicroseconds(),
- "time_delta", frame->timestamp().InMicroseconds());
- frame_input_->InsertRawVideoFrame(std::move(frame), timestamp);
- }
-
- private:
- friend class base::RefCountedThreadSafe<Deliverer>;
- ~Deliverer() {}
-
- const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
- const CastRtpStream::ErrorCallback error_callback_;
-
- // These are set on the main thread after construction, and before the first
- // call to OnVideoFrame() on the IO thread. |sink_| may be passed around on
- // any thread, but must only be dereferenced on the main renderer thread.
- base::WeakPtr<CastVideoSink> sink_;
- scoped_refptr<media::cast::VideoFrameInput> frame_input_;
-
- DISALLOW_COPY_AND_ASSIGN(Deliverer);
- };
-
- private:
- void OnRefreshTimerFired() {
- ++consecutive_refresh_count_;
- if (consecutive_refresh_count_ >= kMaxConsecutiveRefreshFrames)
- refresh_timer_.Stop(); // Stop timer until receiving a non-refresh frame.
-
- DVLOG(1) << "CastVideoSink is requesting another refresh frame "
- "(consecutive count=" << consecutive_refresh_count_ << ").";
- expecting_a_refresh_frame_ = true;
- blink::RequestRefreshFrameFromVideoTrack(track_);
- }
-
- void DidReceiveFrame() {
- if (expecting_a_refresh_frame_) {
- // There is uncertainty as to whether the video frame was in response to a
- // refresh request. However, if it was not, more video frames will soon
- // follow, and before the refresh timer can fire again. Thus, the
- // behavior resulting from this logic will be correct.
- expecting_a_refresh_frame_ = false;
- } else {
- consecutive_refresh_count_ = 0;
- // The following re-starts the timer, scheduling it to fire at
- // kRefreshIntervalMilliseconds from now.
- refresh_timer_.Reset();
- }
- }
-
- const blink::WebMediaStreamTrack track_;
- const scoped_refptr<Deliverer> deliverer_;
-
- // Requests refresh frames at a constant rate while the source is paused, up
- // to a consecutive maximum.
- base::RepeatingTimer refresh_timer_;
-
- // Counter for the number of consecutive "refresh frames" requested.
- int consecutive_refresh_count_;
-
- // Set to true when a request for a refresh frame has been made. This is
- // cleared once the next frame is received.
- bool expecting_a_refresh_frame_;
-
- bool is_connected_to_track_;
-
- DISALLOW_COPY_AND_ASSIGN(CastVideoSink);
-};
-
-// Receives audio data from a MediaStreamTrack. Data is submitted to
-// media::cast::FrameInput.
-//
-// Threading: Audio frames are received on the real-time audio thread.
-// Note that RemoveFromAudioTrack() is synchronous and we have
-// gurantee that there will be no more audio data after calling it.
-class CastAudioSink : public base::SupportsWeakPtr<CastAudioSink>,
- public blink::WebMediaStreamAudioSink,
- public media::AudioConverter::InputCallback {
- public:
- // |track| provides data for this sink.
- CastAudioSink(const blink::WebMediaStreamTrack& track,
- int output_channels,
- int output_sample_rate)
- : track_(track),
- output_channels_(output_channels),
- output_sample_rate_(output_sample_rate),
- current_input_bus_(nullptr),
- sample_frames_in_(0),
- sample_frames_out_(0) {}
-
- ~CastAudioSink() override {
- if (frame_input_.get())
- RemoveFromAudioTrack(this, track_);
- }
-
- // Add this sink to the track. Data received from the track will be
- // submitted to |frame_input|.
- void AddToTrack(
- const scoped_refptr<media::cast::AudioFrameInput>& frame_input) {
- DCHECK(frame_input.get());
- DCHECK(!frame_input_.get());
- // This member is written here and then accessed on the IO thread
- // We will not get data until AddToAudioTrack is called so it is
- // safe to access this member now.
- frame_input_ = frame_input;
- AddToAudioTrack(this, track_);
- }
-
- protected:
- // Called on real-time audio thread.
- void OnData(const media::AudioBus& input_bus,
- base::TimeTicks estimated_capture_time) override {
- DCHECK(input_params_.IsValid());
- DCHECK_EQ(input_bus.channels(), input_params_.channels());
- DCHECK_EQ(input_bus.frames(), input_params_.frames_per_buffer());
- DCHECK(!estimated_capture_time.is_null());
- DCHECK(converter_.get());
-
- // Determine the duration of the audio signal enqueued within |converter_|.
- const base::TimeDelta signal_duration_already_buffered =
- (sample_frames_in_ * base::TimeDelta::FromSeconds(1) /
- input_params_.sample_rate()) -
- (sample_frames_out_ * base::TimeDelta::FromSeconds(1) /
- output_sample_rate_);
- DVLOG(2) << "Audio reference time adjustment: -("
- << signal_duration_already_buffered.InMicroseconds() << " us)";
- const base::TimeTicks capture_time_of_first_converted_sample =
- estimated_capture_time - signal_duration_already_buffered;
-
- // Convert the entire input signal. AudioConverter is efficient in that no
- // additional copying or conversion will occur if the input signal is in the
- // same format as the output. Note that, while the number of sample frames
- // provided as input is always the same, the chunk size (and the size of the
- // |audio_bus| here) can be variable. This is not an issue since
- // media::cast::AudioFrameInput can handle variable-sized AudioBuses.
- std::unique_ptr<media::AudioBus> audio_bus =
- media::AudioBus::Create(output_channels_, converter_->ChunkSize());
- // AudioConverter will call ProvideInput() to fetch from |current_data_|.
- current_input_bus_ = &input_bus;
- converter_->Convert(audio_bus.get());
- DCHECK(!current_input_bus_); // ProvideInput() called exactly once?
-
- sample_frames_in_ += input_params_.frames_per_buffer();
- sample_frames_out_ += audio_bus->frames();
-
- frame_input_->InsertAudio(std::move(audio_bus),
- capture_time_of_first_converted_sample);
- }
-
- // Called on real-time audio thread.
- void OnSetFormat(const media::AudioParameters& params) override {
- if (input_params_.Equals(params))
- return;
- input_params_ = params;
-
- DVLOG(1) << "Setting up audio resampling: {"
- << input_params_.channels() << " channels, "
- << input_params_.sample_rate() << " Hz} --> {"
- << output_channels_ << " channels, "
- << output_sample_rate_ << " Hz}";
- const media::AudioParameters output_params(
- media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
- media::GuessChannelLayout(output_channels_), output_sample_rate_,
- output_sample_rate_ * input_params_.frames_per_buffer() /
- input_params_.sample_rate());
- converter_.reset(
- new media::AudioConverter(input_params_, output_params, false));
- converter_->AddInput(this);
- sample_frames_in_ = 0;
- sample_frames_out_ = 0;
- }
-
- // Called on real-time audio thread.
- double ProvideInput(media::AudioBus* audio_bus,
- uint32_t frames_delayed) override {
- DCHECK(current_input_bus_);
- current_input_bus_->CopyTo(audio_bus);
- current_input_bus_ = nullptr;
- return 1.0;
- }
-
- private:
- const blink::WebMediaStreamTrack track_;
- const int output_channels_;
- const int output_sample_rate_;
-
- // This must be set before the real-time audio thread starts calling OnData(),
- // and remain unchanged until after the thread will stop calling OnData().
- scoped_refptr<media::cast::AudioFrameInput> frame_input_;
-
- // These members are accessed on the real-time audio time only.
- media::AudioParameters input_params_;
- std::unique_ptr<media::AudioConverter> converter_;
- const media::AudioBus* current_input_bus_;
- int64_t sample_frames_in_;
- int64_t sample_frames_out_;
-
- DISALLOW_COPY_AND_ASSIGN(CastAudioSink);
-};
-
-bool CastRtpStream::IsHardwareVP8EncodingSupported() {
- // Query for hardware VP8 encoder support.
- const std::vector<media::VideoEncodeAccelerator::SupportedProfile>
- vea_profiles = content::GetSupportedVideoEncodeAcceleratorProfiles();
- for (const auto& vea_profile : vea_profiles) {
- if (vea_profile.profile >= media::VP8PROFILE_MIN &&
- vea_profile.profile <= media::VP8PROFILE_MAX) {
- return true;
- }
- }
- return false;
-}
-
-bool CastRtpStream::IsHardwareH264EncodingSupported() {
-// Query for hardware H.264 encoder support.
-//
-// TODO(miu): Look into why H.264 hardware encoder on MacOS is broken.
-// http://crbug.com/596674
-// TODO(emircan): Look into HW encoder initialization issues on Win.
-// https://crbug.com/636064
-#if !defined(OS_MACOSX) && !defined(OS_WIN)
- const std::vector<media::VideoEncodeAccelerator::SupportedProfile>
- vea_profiles = content::GetSupportedVideoEncodeAcceleratorProfiles();
- for (const auto& vea_profile : vea_profiles) {
- if (vea_profile.profile >= media::H264PROFILE_MIN &&
- vea_profile.profile <= media::H264PROFILE_MAX) {
- return true;
- }
- }
-#endif // !defined(OS_MACOSX) && !defined(OS_WIN)
- return false;
-}
-
-CastRtpStream::CastRtpStream(const blink::WebMediaStreamTrack& track,
- const scoped_refptr<CastSession>& session)
- : track_(track),
- cast_session_(session),
- is_audio_(track_.Source().GetType() ==
- blink::WebMediaStreamSource::kTypeAudio) {}
-
-CastRtpStream::CastRtpStream(bool is_audio,
- const scoped_refptr<CastSession>& session)
- : cast_session_(session), is_audio_(is_audio) {}
-
-CastRtpStream::~CastRtpStream() {
- Stop();
-}
-
-std::vector<FrameSenderConfig> CastRtpStream::GetSupportedConfigs() {
- if (is_audio_)
- return SupportedAudioConfigs(track_.IsNull());
- else
- return SupportedVideoConfigs(track_.IsNull());
-}
-
-void CastRtpStream::Start(int32_t stream_id,
- const FrameSenderConfig& config,
- base::OnceClosure start_callback,
- base::OnceClosure stop_callback,
- ErrorCallback error_callback) {
- DCHECK(!start_callback.is_null());
- DCHECK(!stop_callback.is_null());
- DCHECK(!error_callback.is_null());
-
- DVLOG(1) << "CastRtpStream::Start = " << (is_audio_ ? "audio" : "video");
- stop_callback_ = std::move(stop_callback);
- error_callback_ = std::move(error_callback);
-
- if (track_.IsNull()) {
- cast_session_->StartRemotingStream(
- stream_id, config,
- base::BindOnce(&CastRtpStream::DidEncounterError,
- weak_factory_.GetWeakPtr()));
- } else if (is_audio_) {
- // In case of error we have to go through DidEncounterError() to stop
- // the streaming after reporting the error.
- audio_sink_.reset(
- new CastAudioSink(track_, config.channels, config.rtp_timebase));
- cast_session_->StartAudio(
- config,
- base::Bind(&CastAudioSink::AddToTrack, audio_sink_->AsWeakPtr()),
- base::Bind(&CastRtpStream::DidEncounterError,
- weak_factory_.GetWeakPtr()));
- } else {
- // See the code for audio above for explanation of callbacks.
- video_sink_.reset(new CastVideoSink(
- track_,
- media::BindToCurrentLoop(base::Bind(&CastRtpStream::DidEncounterError,
- weak_factory_.GetWeakPtr()))));
- cast_session_->StartVideo(
- config, base::Bind(&CastVideoSink::AddToTrack, video_sink_->AsWeakPtr(),
- !config.aes_key.empty()),
- base::Bind(&CastRtpStream::DidEncounterError,
- weak_factory_.GetWeakPtr()));
- }
- std::move(start_callback).Run();
-}
-
-void CastRtpStream::Stop() {
- DVLOG(1) << "CastRtpStream::Stop = " << (is_audio_ ? "audio" : "video");
- if (stop_callback_.is_null())
- return; // Already stopped.
- weak_factory_.InvalidateWeakPtrs();
- error_callback_.Reset();
- audio_sink_.reset();
- video_sink_.reset();
- std::move(stop_callback_).Run();
-}
-
-void CastRtpStream::ToggleLogging(bool enable) {
- DVLOG(1) << "CastRtpStream::ToggleLogging(" << enable
- << ") = " << (is_audio_ ? "audio" : "video");
- cast_session_->ToggleLogging(is_audio_, enable);
-}
-
-void CastRtpStream::GetRawEvents(
- const base::Callback<void(std::unique_ptr<base::Value>)>& callback,
- const std::string& extra_data) {
- DVLOG(1) << "CastRtpStream::GetRawEvents = "
- << (is_audio_ ? "audio" : "video");
- cast_session_->GetEventLogsAndReset(is_audio_, extra_data, callback);
-}
-
-void CastRtpStream::GetStats(
- const base::Callback<void(std::unique_ptr<base::DictionaryValue>)>&
- callback) {
- DVLOG(1) << "CastRtpStream::GetStats = " << (is_audio_ ? "audio" : "video");
- cast_session_->GetStatsAndReset(is_audio_, callback);
-}
-
-void CastRtpStream::DidEncounterError(const std::string& message) {
- DCHECK(content::RenderThread::Get());
- DVLOG(1) << "CastRtpStream::DidEncounterError(" << message
- << ") = " << (is_audio_ ? "audio" : "video");
- // Save the WeakPtr first because the error callback might delete this object.
- base::WeakPtr<CastRtpStream> ptr = weak_factory_.GetWeakPtr();
- error_callback_.Run(message);
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::BindOnce(&CastRtpStream::Stop, ptr));
-}
diff --git a/chromium/chrome/renderer/media/cast_rtp_stream.h b/chromium/chrome/renderer/media/cast_rtp_stream.h
deleted file mode 100644
index f39eb55f724..00000000000
--- a/chromium/chrome/renderer/media/cast_rtp_stream.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2013 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 CHROME_RENDERER_MEDIA_CAST_RTP_STREAM_H_
-#define CHROME_RENDERER_MEDIA_CAST_RTP_STREAM_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "media/cast/cast_config.h"
-#include "media/cast/constants.h"
-#include "third_party/blink/public/platform/web_media_stream_track.h"
-
-namespace base {
-class DictionaryValue;
-class Value;
-}
-
-class CastAudioSink;
-class CastSession;
-class CastVideoSink;
-
-// This object represents a RTP stream that encodes and optionally
-// encrypt audio or video data from a WebMediaStreamTrack.
-// Note that this object does not actually output packets. It allows
-// configuration of encoding and RTP parameters and control such a logical
-// stream.
-class CastRtpStream {
- public:
- using ErrorCallback = base::RepeatingCallback<void(const std::string&)>;
-
- static bool IsHardwareVP8EncodingSupported();
-
- static bool IsHardwareH264EncodingSupported();
-
- CastRtpStream(const blink::WebMediaStreamTrack& track,
- const scoped_refptr<CastSession>& session);
- CastRtpStream(bool is_audio, const scoped_refptr<CastSession>& session);
- ~CastRtpStream();
-
- // Return parameters currently supported by this stream.
- std::vector<media::cast::FrameSenderConfig> GetSupportedConfigs();
-
- // Begin encoding of media stream and then submit the encoded streams
- // to underlying transport.
- // |stream_id| is the unique ID of this stream.
- // When the stream is started |start_callback| is called.
- // When the stream is stopped |stop_callback| is called.
- // When there is an error |error_callback| is called with a message.
- void Start(int32_t stream_id,
- const media::cast::FrameSenderConfig& config,
- base::OnceClosure start_callback,
- base::OnceClosure stop_callback,
- ErrorCallback error_callback);
-
- // Stop encoding.
- void Stop();
-
- // Enables or disables logging for this stream.
- void ToggleLogging(bool enable);
-
- // Get serialized raw events for this stream with |extra_data| attached,
- // and invokes |callback| with the result.
- void GetRawEvents(
- const base::Callback<void(std::unique_ptr<base::Value>)>& callback,
- const std::string& extra_data);
-
- // Get stats in DictionaryValue format and invokves |callback| with
- // the result.
- void GetStats(const base::Callback<
- void(std::unique_ptr<base::DictionaryValue>)>& callback);
-
- private:
- void DidEncounterError(const std::string& message);
-
- blink::WebMediaStreamTrack track_;
- const scoped_refptr<CastSession> cast_session_;
- std::unique_ptr<CastAudioSink> audio_sink_;
- std::unique_ptr<CastVideoSink> video_sink_;
- base::OnceClosure stop_callback_;
- ErrorCallback error_callback_;
- bool is_audio_;
-
- base::WeakPtrFactory<CastRtpStream> weak_factory_{this};
-
- DISALLOW_COPY_AND_ASSIGN(CastRtpStream);
-};
-
-#endif // CHROME_RENDERER_MEDIA_CAST_RTP_STREAM_H_
diff --git a/chromium/chrome/renderer/media/cast_session.cc b/chromium/chrome/renderer/media/cast_session.cc
deleted file mode 100644
index fd031a658a3..00000000000
--- a/chromium/chrome/renderer/media/cast_session.cc
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2013 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 "chrome/renderer/media/cast_session.h"
-
-#include <stddef.h>
-
-#include <memory>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/memory/unsafe_shared_memory_region.h"
-#include "base/single_thread_task_runner.h"
-#include "chrome/renderer/media/cast_session_delegate.h"
-#include "content/public/renderer/render_thread.h"
-#include "content/public/renderer/video_encode_accelerator.h"
-#include "media/base/bind_to_current_loop.h"
-#include "media/base/video_frame.h"
-#include "media/cast/cast_sender.h"
-#include "media/cast/logging/logging_defines.h"
-
-namespace {
-
-void CreateVideoEncodeAccelerator(
- const media::cast::ReceiveVideoEncodeAcceleratorCallback& callback) {
- DCHECK(content::RenderThread::Get());
-
- // Delegate the call to content API on the render thread.
- content::CreateVideoEncodeAccelerator(callback);
-}
-
-void CreateVideoEncodeMemory(
- size_t size,
- const media::cast::ReceiveVideoEncodeMemoryCallback& callback) {
- DCHECK(content::RenderThread::Get());
-
- base::UnsafeSharedMemoryRegion shm =
- base::UnsafeSharedMemoryRegion::Create(size);
- DCHECK(shm.IsValid()) << "Failed to allocate shared memory";
- callback.Run(std::move(shm));
-}
-
-} // namespace
-
-CastSession::CastSession(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : delegate_(new CastSessionDelegate()),
- main_thread_task_runner_(std::move(task_runner)),
- io_task_runner_(content::RenderThread::Get()->GetIOTaskRunner()) {}
-
-CastSession::~CastSession() {
- // We should always be able to delete the object on the IO thread.
- CHECK(io_task_runner_->DeleteSoon(FROM_HERE, delegate_.release()));
-}
-
-void CastSession::StartAudio(const media::cast::FrameSenderConfig& config,
- const AudioFrameInputAvailableCallback& callback,
- const ErrorCallback& error_callback) {
- DCHECK(content::RenderThread::Get());
-
- io_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(
- &CastSessionDelegate::StartAudio, base::Unretained(delegate_.get()),
- config, media::BindToLoop(main_thread_task_runner_, callback),
- media::BindToLoop(main_thread_task_runner_, error_callback)));
-}
-
-void CastSession::StartVideo(const media::cast::FrameSenderConfig& config,
- const VideoFrameInputAvailableCallback& callback,
- const ErrorCallback& error_callback) {
- DCHECK(content::RenderThread::Get());
-
- io_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(
- &CastSessionDelegate::StartVideo, base::Unretained(delegate_.get()),
- config, media::BindToLoop(main_thread_task_runner_, callback),
- media::BindToLoop(main_thread_task_runner_, error_callback),
- media::BindToLoop(main_thread_task_runner_,
- base::Bind(&CreateVideoEncodeAccelerator)),
- media::BindToLoop(main_thread_task_runner_,
- base::Bind(&CreateVideoEncodeMemory))));
-}
-
-void CastSession::StartRemotingStream(
- int32_t stream_id,
- const media::cast::FrameSenderConfig& config,
- ErrorOnceCallback error_callback) {
- DCHECK(content::RenderThread::Get());
-
- io_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&CastSessionDelegate::StartRemotingStream,
- base::Unretained(delegate_.get()), stream_id, config,
- media::BindToLoop(main_thread_task_runner_,
- std::move(error_callback))));
-}
-
-void CastSession::StartUDP(const net::IPEndPoint& remote_endpoint,
- std::unique_ptr<base::DictionaryValue> options,
- const ErrorCallback& error_callback) {
- io_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(
- &CastSessionDelegate::StartUDP, base::Unretained(delegate_.get()),
- net::IPEndPoint(), remote_endpoint, std::move(options),
- media::BindToLoop(main_thread_task_runner_, error_callback)));
-}
-
-void CastSession::ToggleLogging(bool is_audio, bool enable) {
- io_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&CastSessionDelegate::ToggleLogging,
- base::Unretained(delegate_.get()), is_audio, enable));
-}
-
-void CastSession::GetEventLogsAndReset(
- bool is_audio, const std::string& extra_data,
- const EventLogsCallback& callback) {
- io_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&CastSessionDelegate::GetEventLogsAndReset,
- base::Unretained(delegate_.get()), is_audio, extra_data,
- media::BindToLoop(main_thread_task_runner_, callback)));
-}
-
-void CastSession::GetStatsAndReset(bool is_audio,
- const StatsCallback& callback) {
- io_task_runner_->PostTask(
- FROM_HERE,
- base::BindOnce(&CastSessionDelegate::GetStatsAndReset,
- base::Unretained(delegate_.get()), is_audio,
- media::BindToLoop(main_thread_task_runner_, callback)));
-}
diff --git a/chromium/chrome/renderer/media/cast_session.h b/chromium/chrome/renderer/media/cast_session.h
deleted file mode 100644
index 6a3f79e04fd..00000000000
--- a/chromium/chrome/renderer/media/cast_session.h
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2013 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 CHROME_RENDERER_MEDIA_CAST_SESSION_H_
-#define CHROME_RENDERER_MEDIA_CAST_SESSION_H_
-
-#include <memory>
-#include <vector>
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "media/cast/cast_config.h"
-#include "net/base/ip_endpoint.h"
-
-namespace base {
-class DictionaryValue;
-class SingleThreadTaskRunner;
-class Value;
-} // namespace base
-
-namespace media {
-namespace cast {
-class AudioFrameInput;
-class VideoFrameInput;
-} // namespace cast
-} // namespace media
-
-class CastSessionDelegate;
-
-// This class represents a Cast session and allows the session to be
-// configured on the main thread. Actual work is forwarded to
-// CastSessionDelegate on the IO thread.
-class CastSession : public base::RefCounted<CastSession> {
- public:
- using AudioFrameInputAvailableCallback =
- base::Callback<void(const scoped_refptr<media::cast::AudioFrameInput>&)>;
- using VideoFrameInputAvailableCallback =
- base::Callback<void(const scoped_refptr<media::cast::VideoFrameInput>&)>;
- using SendPacketCallback = base::Callback<void(const std::vector<char>&)>;
- using EventLogsCallback = base::Callback<void(std::unique_ptr<base::Value>)>;
- using StatsCallback =
- base::Callback<void(std::unique_ptr<base::DictionaryValue>)>;
- // TODO(crbug.com/1007641): remove ErrorCallback and rename ErrorOnceCallback
- // once all occurrences of base::Callback have been removed.
- using ErrorCallback = base::Callback<void(const std::string&)>;
- using ErrorOnceCallback = base::OnceCallback<void(const std::string&)>;
-
- explicit CastSession(scoped_refptr<base::SingleThreadTaskRunner> task_runner);
-
- // Start encoding of audio and video using the provided configuration.
- //
- // When Cast sender is started and ready to be used
- // media::cast::FrameInput will be given through |callback|.
- // If it encounters an error, |error_callback| will be invoked with the
- // error message. Both |callback| and |error_callback| will be made on
- // the main thread.
- // |StartUDP()| must be called before these methods.
- void StartAudio(const media::cast::FrameSenderConfig& config,
- const AudioFrameInputAvailableCallback& callback,
- const ErrorCallback& error_callback);
- void StartVideo(const media::cast::FrameSenderConfig& config,
- const VideoFrameInputAvailableCallback& callback,
- const ErrorCallback& error_callback);
-
- // Start remoting a stream. |error_callback| will be invoked when any error
- // occurs. |StartUDP()| must be called before calling this method.
- void StartRemotingStream(int32_t stream_id,
- const media::cast::FrameSenderConfig& config,
- ErrorOnceCallback error_callback);
-
- // This will create the Cast transport and connect to |remote_endpoint|.
- // |options| is a dictionary which contain optional configuration for the
- // udp transport.
- // Must be called before initialization of audio or video.
- void StartUDP(const net::IPEndPoint& remote_endpoint,
- std::unique_ptr<base::DictionaryValue> options,
- const ErrorCallback& error_callback);
-
- // Creates or destroys event subscriber for the audio or video stream.
- // |is_audio|: true if the event subscriber is for audio. Video otherwise.
- // |enable|: If true, creates an event subscriber. Otherwise destroys
- // existing subscriber and discards logs.
- void ToggleLogging(bool is_audio, bool enable);
-
- // Returns raw event logs in serialized format for either the audio or video
- // stream since last call and returns result in |callback|. Also attaches
- // |extra_data| to the log.
- void GetEventLogsAndReset(bool is_audio,
- const std::string& extra_data, const EventLogsCallback& callback);
-
- // Returns stats in a DictionaryValue format for either the audio or video
- // stream since last call and returns result in |callback|.
- void GetStatsAndReset(bool is_audio, const StatsCallback& callback);
-
- private:
- friend class base::RefCounted<CastSession>;
- virtual ~CastSession();
-
- // This member should never be dereferenced on the main thread.
- // CastSessionDelegate lives only on the IO thread. It is always
- // safe to post task on the IO thread to access CastSessionDelegate
- // because it is owned by this object.
- std::unique_ptr<CastSessionDelegate> delegate_;
-
- // A main thread task runner that might execute JavaScript.
- const scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
-
- // Proxy to the IO task runner.
- const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
-
- DISALLOW_COPY_AND_ASSIGN(CastSession);
-};
-
-#endif // CHROME_RENDERER_MEDIA_CAST_SESSION_H_
diff --git a/chromium/chrome/renderer/media/cast_session_browsertest.cc b/chromium/chrome/renderer/media/cast_session_browsertest.cc
deleted file mode 100644
index c4c4337d7e8..00000000000
--- a/chromium/chrome/renderer/media/cast_session_browsertest.cc
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2013 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 "chrome/renderer/media/cast_session.h"
-
-#include "base/run_loop.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "chrome/renderer/chrome_content_renderer_client.h"
-#include "chrome/test/base/chrome_render_view_test.h"
-#include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
-
-typedef ChromeRenderViewTest CastSessionBrowserTest;
-
-// Tests that CastSession is created and destroyed properly inside
-// chrome renderer.
-TEST_F(CastSessionBrowserTest, CreateAndDestroy) {
- chrome_render_thread_->set_io_task_runner(
- blink::scheduler::GetSingleThreadTaskRunnerForTesting());
- ChromeContentRendererClient* client =
- static_cast<ChromeContentRendererClient*>(content_renderer_client_.get());
- client->RenderThreadStarted();
-
- scoped_refptr<CastSession> session(
- new CastSession(blink::scheduler::GetSingleThreadTaskRunnerForTesting()));
-
- // Causes CastSession to destruct.
- session.reset();
- base::RunLoop().RunUntilIdle();
-}
diff --git a/chromium/chrome/renderer/media/cast_session_delegate.cc b/chromium/chrome/renderer/media/cast_session_delegate.cc
deleted file mode 100644
index 7bc22f2ecc5..00000000000
--- a/chromium/chrome/renderer/media/cast_session_delegate.cc
+++ /dev/null
@@ -1,336 +0,0 @@
-// Copyright 2013 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 "chrome/renderer/media/cast_session_delegate.h"
-
-#include <memory>
-#include <utility>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/single_thread_task_runner.h"
-#include "base/strings/stringprintf.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "base/values.h"
-#include "build/build_config.h"
-#include "chrome/renderer/media/cast_threads.h"
-#include "chrome/renderer/media/cast_transport_ipc.h"
-#include "components/version_info/version_info.h"
-#include "content/public/renderer/render_thread.h"
-#include "media/cast/cast_config.h"
-#include "media/cast/cast_environment.h"
-#include "media/cast/cast_sender.h"
-#include "media/cast/logging/log_serializer.h"
-#include "media/cast/logging/logging_defines.h"
-#include "media/cast/logging/proto/raw_events.pb.h"
-#include "media/cast/logging/raw_event_subscriber_bundle.h"
-#include "media/cast/net/cast_transport.h"
-#include "media/cast/net/cast_transport_config.h"
-
-using media::cast::CastEnvironment;
-using media::cast::CastSender;
-using media::cast::FrameSenderConfig;
-
-static base::LazyInstance<CastThreads>::DestructorAtExit g_cast_threads =
- LAZY_INSTANCE_INITIALIZER;
-
-CastSessionDelegateBase::CastSessionDelegateBase()
- : io_task_runner_(content::RenderThread::Get()->GetIOTaskRunner()) {
- DCHECK(io_task_runner_.get());
-#if defined(OS_WIN)
- // Note that this also increases the accuracy of PostDelayTask,
- // which is is very helpful to cast.
- if (!base::Time::ActivateHighResolutionTimer(true)) {
- LOG(WARNING) << "Failed to activate high resolution timers for cast.";
- }
-#endif
-}
-
-CastSessionDelegateBase::~CastSessionDelegateBase() {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
-#if defined(OS_WIN)
- base::Time::ActivateHighResolutionTimer(false);
-#endif
-}
-
-void CastSessionDelegateBase::StartUDP(
- const net::IPEndPoint& local_endpoint,
- const net::IPEndPoint& remote_endpoint,
- std::unique_ptr<base::DictionaryValue> options,
- const ErrorCallback& error_callback) {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
-
- // CastSender uses the renderer's IO thread as the main thread. This reduces
- // thread hopping for incoming video frames and outgoing network packets.
- // TODO(hubbe): Create cast environment in ctor instead.
- cast_environment_ =
- new CastEnvironment(base::DefaultTickClock::GetInstance(),
- base::ThreadTaskRunnerHandle::Get(),
- g_cast_threads.Get().GetAudioEncodeTaskRunner(),
- g_cast_threads.Get().GetVideoEncodeTaskRunner());
-
- // Rationale for using unretained: The callback cannot be called after the
- // destruction of CastTransportIPC, and they both share the same thread.
- cast_transport_ = std::make_unique<CastTransportIPC>(
- local_endpoint, remote_endpoint, std::move(options),
- base::BindRepeating(&CastSessionDelegateBase::ReceivePacket,
- base::Unretained(this)),
- base::BindRepeating(&CastSessionDelegateBase::StatusNotificationCB,
- base::Unretained(this), error_callback),
- base::BindRepeating(
- &media::cast::LogEventDispatcher::DispatchBatchOfEvents,
- base::Unretained(cast_environment_->logger())));
-}
-
-void CastSessionDelegateBase::StatusNotificationCB(
- ErrorOnceCallback error_callback,
- media::cast::CastTransportStatus status) {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
- std::string error_message;
-
- switch (status) {
- case media::cast::TRANSPORT_STREAM_UNINITIALIZED:
- case media::cast::TRANSPORT_STREAM_INITIALIZED:
- return; // Not errors, do nothing.
- case media::cast::TRANSPORT_INVALID_CRYPTO_CONFIG:
- std::move(error_callback).Run("Invalid encrypt/decrypt configuration.");
- break;
- case media::cast::TRANSPORT_SOCKET_ERROR:
- std::move(error_callback).Run("Socket error.");
- break;
- }
-}
-
-CastSessionDelegate::CastSessionDelegate() {
- DCHECK(io_task_runner_.get());
-}
-
-CastSessionDelegate::~CastSessionDelegate() {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
-}
-
-void CastSessionDelegate::StartAudio(
- const FrameSenderConfig& config,
- const AudioFrameInputAvailableCallback& callback,
- ErrorOnceCallback error_callback) {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
-
- if (!cast_transport_ || !cast_sender_) {
- std::move(error_callback).Run("Destination not set.");
- return;
- }
-
- audio_frame_input_available_callback_ = callback;
- cast_sender_->InitializeAudio(
- config, base::BindOnce(&CastSessionDelegate::OnOperationalStatusChange,
- weak_factory_.GetWeakPtr(), true,
- std::move(error_callback)));
-}
-
-void CastSessionDelegate::StartVideo(
- const FrameSenderConfig& config,
- const VideoFrameInputAvailableCallback& callback,
- const ErrorCallback& error_callback,
- const media::cast::CreateVideoEncodeAcceleratorCallback& create_vea_cb,
- const media::cast::CreateVideoEncodeMemoryCallback&
- create_video_encode_mem_cb) {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
-
- if (!cast_transport_ || !cast_sender_) {
- error_callback.Run("Destination not set.");
- return;
- }
-
- video_frame_input_available_callback_ = callback;
-
- cast_sender_->InitializeVideo(
- config,
- base::BindRepeating(&CastSessionDelegate::OnOperationalStatusChange,
- weak_factory_.GetWeakPtr(), false, error_callback),
- create_vea_cb, create_video_encode_mem_cb);
-}
-
-void CastSessionDelegate::StartRemotingStream(
- int32_t stream_id,
- const FrameSenderConfig& config,
- ErrorOnceCallback error_callback) {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
-
- if (!cast_transport_) {
- std::move(error_callback).Run("Destination not set.");
- return;
- }
-
- media::cast::CastTransportRtpConfig transport_config;
- transport_config.ssrc = config.sender_ssrc;
- transport_config.feedback_ssrc = config.receiver_ssrc;
- transport_config.rtp_payload_type = config.rtp_payload_type;
- transport_config.rtp_stream_id = stream_id;
- transport_config.aes_key = config.aes_key;
- transport_config.aes_iv_mask = config.aes_iv_mask;
- cast_transport_->InitializeStream(transport_config, nullptr);
-}
-
-void CastSessionDelegate::StartUDP(
- const net::IPEndPoint& local_endpoint,
- const net::IPEndPoint& remote_endpoint,
- std::unique_ptr<base::DictionaryValue> options,
- const ErrorCallback& error_callback) {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
- CastSessionDelegateBase::StartUDP(local_endpoint, remote_endpoint,
- std::move(options), error_callback);
- event_subscribers_ = std::make_unique<media::cast::RawEventSubscriberBundle>(
- cast_environment_);
-
- cast_sender_ = CastSender::Create(cast_environment_, cast_transport_.get());
-}
-
-void CastSessionDelegate::ToggleLogging(bool is_audio, bool enable) {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
- if (!event_subscribers_.get())
- return;
-
- if (enable)
- event_subscribers_->AddEventSubscribers(is_audio);
- else
- event_subscribers_->RemoveEventSubscribers(is_audio);
-}
-
-void CastSessionDelegate::GetEventLogsAndReset(
- bool is_audio,
- const std::string& extra_data,
- const EventLogsCallback& callback) {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
-
- if (!event_subscribers_.get()) {
- callback.Run(std::make_unique<base::Value>(base::Value::Type::BINARY));
- return;
- }
-
- media::cast::EncodingEventSubscriber* subscriber =
- event_subscribers_->GetEncodingEventSubscriber(is_audio);
- if (!subscriber) {
- callback.Run(std::make_unique<base::Value>(base::Value::Type::BINARY));
- return;
- }
-
- media::cast::proto::LogMetadata metadata;
- media::cast::FrameEventList frame_events;
- media::cast::PacketEventList packet_events;
-
- subscriber->GetEventsAndReset(&metadata, &frame_events, &packet_events);
-
- if (!extra_data.empty())
- metadata.set_extra_data(extra_data);
- media::cast::proto::GeneralDescription* gen_desc =
- metadata.mutable_general_description();
- gen_desc->set_product(version_info::GetProductName());
- gen_desc->set_product_version(version_info::GetVersionNumber());
- gen_desc->set_os(version_info::GetOSType());
-
- std::unique_ptr<char[]> serialized_log(
- new char[media::cast::kMaxSerializedBytes]);
- int output_bytes;
- bool success = media::cast::SerializeEvents(metadata,
- frame_events,
- packet_events,
- true,
- media::cast::kMaxSerializedBytes,
- serialized_log.get(),
- &output_bytes);
-
- if (!success) {
- DVLOG(2) << "Failed to serialize event log.";
- callback.Run(std::make_unique<base::Value>(base::Value::Type::BINARY));
- return;
- }
-
- DVLOG(2) << "Serialized log length: " << output_bytes;
-
- auto blob = std::make_unique<base::Value>(std::vector<char>(
- serialized_log.get(), serialized_log.get() + output_bytes));
- callback.Run(std::move(blob));
-}
-
-void CastSessionDelegate::GetStatsAndReset(bool is_audio,
- const StatsCallback& callback) {
- DCHECK(io_task_runner_->BelongsToCurrentThread());
-
- if (!event_subscribers_.get()) {
- callback.Run(std::make_unique<base::DictionaryValue>());
- return;
- }
-
- media::cast::StatsEventSubscriber* subscriber =
- event_subscribers_->GetStatsEventSubscriber(is_audio);
- if (!subscriber) {
- callback.Run(std::make_unique<base::DictionaryValue>());
- return;
- }
-
- std::unique_ptr<base::DictionaryValue> stats = subscriber->GetStats();
- subscriber->Reset();
-
- callback.Run(std::move(stats));
-}
-
-void CastSessionDelegate::OnOperationalStatusChange(
- bool is_for_audio,
- ErrorOnceCallback error_callback,
- media::cast::OperationalStatus status) {
- DCHECK(cast_sender_);
-
- switch (status) {
- case media::cast::STATUS_UNINITIALIZED:
- case media::cast::STATUS_CODEC_REINIT_PENDING:
- // Not an error.
- // TODO(miu): As an optimization, signal the client to pause sending more
- // frames until the state becomes STATUS_INITIALIZED again.
- break;
- case media::cast::STATUS_INITIALIZED:
- // Once initialized, run the "frame input available" callback to allow the
- // client to begin sending frames. If STATUS_INITIALIZED is encountered
- // again, do nothing since this is only an indication that the codec has
- // successfully re-initialized.
- if (is_for_audio) {
- if (!audio_frame_input_available_callback_.is_null()) {
- std::move(audio_frame_input_available_callback_)
- .Run(cast_sender_->audio_frame_input());
- }
- } else {
- if (!video_frame_input_available_callback_.is_null()) {
- std::move(video_frame_input_available_callback_)
- .Run(cast_sender_->video_frame_input());
- }
- }
- break;
- case media::cast::STATUS_INVALID_CONFIGURATION:
- std::move(error_callback)
- .Run(base::StringPrintf("Invalid %s configuration.",
- is_for_audio ? "audio" : "video"));
- break;
- case media::cast::STATUS_UNSUPPORTED_CODEC:
- std::move(error_callback)
- .Run(base::StringPrintf("%s codec not supported.",
- is_for_audio ? "Audio" : "Video"));
- break;
- case media::cast::STATUS_CODEC_INIT_FAILED:
- std::move(error_callback)
- .Run(base::StringPrintf("%s codec initialization failed.",
- is_for_audio ? "Audio" : "Video"));
- break;
- case media::cast::STATUS_CODEC_RUNTIME_ERROR:
- std::move(error_callback)
- .Run(base::StringPrintf("%s codec runtime error.",
- is_for_audio ? "Audio" : "Video"));
- break;
- }
-}
-
-void CastSessionDelegate::ReceivePacket(
- std::unique_ptr<media::cast::Packet> packet) {
- // Do nothing (frees packet)
-}
diff --git a/chromium/chrome/renderer/media/cast_session_delegate.h b/chromium/chrome/renderer/media/cast_session_delegate.h
deleted file mode 100644
index b841c35479c..00000000000
--- a/chromium/chrome/renderer/media/cast_session_delegate.h
+++ /dev/null
@@ -1,156 +0,0 @@
-// Copyright 2013 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 CHROME_RENDERER_MEDIA_CAST_SESSION_DELEGATE_H_
-#define CHROME_RENDERER_MEDIA_CAST_SESSION_DELEGATE_H_
-
-#include <map>
-#include <memory>
-#include <vector>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "base/threading/thread.h"
-#include "base/threading/thread_checker.h"
-#include "base/time/default_tick_clock.h"
-#include "media/cast/cast_config.h"
-#include "media/cast/cast_sender.h"
-#include "media/cast/logging/logging_defines.h"
-
-namespace base {
-class DictionaryValue;
-class SingleThreadTaskRunner;
-class Value;
-} // namespace base
-
-namespace media {
-
-namespace cast {
-class CastEnvironment;
-class RawEventSubscriberBundle;
-
-namespace transport {
-class CastTransport;
-} // namespace transport
-} // namespace cast
-} // namespace media
-
-// Breaks out functionality that is common between CastSessionDelegate and
-// CastReceiverSessionDelegate.
-class CastSessionDelegateBase {
- public:
- // TODO(crbug.com/1007641): remove ErrorCallback and rename ErrorOnceCallback
- // once all occurrences of base::Callback have been removed.
- using ErrorCallback = base::RepeatingCallback<void(const std::string&)>;
- using ErrorOnceCallback = base::OnceCallback<void(const std::string&)>;
-
- CastSessionDelegateBase();
- virtual ~CastSessionDelegateBase();
-
- // This will start the session by configuring and creating the Cast transport
- // and the Cast sender.
- // Must be called before initialization of audio or video.
- void StartUDP(const net::IPEndPoint& local_endpoint,
- const net::IPEndPoint& remote_endpoint,
- std::unique_ptr<base::DictionaryValue> options,
- const ErrorCallback& error_callback);
-
- protected:
- void StatusNotificationCB(ErrorOnceCallback error_callback,
- media::cast::CastTransportStatus status);
-
- virtual void ReceivePacket(std::unique_ptr<media::cast::Packet> packet) = 0;
-
- base::ThreadChecker thread_checker_;
- scoped_refptr<media::cast::CastEnvironment> cast_environment_;
- std::unique_ptr<media::cast::CastTransport> cast_transport_;
-
- // Proxy to the IO message loop.
- const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
- base::WeakPtrFactory<CastSessionDelegateBase> weak_factory_{this};
-
- DISALLOW_COPY_AND_ASSIGN(CastSessionDelegateBase);
-};
-
-// This class hosts CastSender and connects it to audio/video frame input
-// and network socket.
-// This class is created on the render thread and destroyed on the IO
-// thread. All methods are accessible only on the IO thread.
-class CastSessionDelegate : public CastSessionDelegateBase {
- public:
- typedef base::Callback<void(const scoped_refptr<
- media::cast::AudioFrameInput>&)> AudioFrameInputAvailableCallback;
- typedef base::Callback<void(const scoped_refptr<
- media::cast::VideoFrameInput>&)> VideoFrameInputAvailableCallback;
- typedef base::Callback<void(std::unique_ptr<base::Value>)> EventLogsCallback;
- typedef base::Callback<void(std::unique_ptr<base::DictionaryValue>)>
- StatsCallback;
-
- CastSessionDelegate();
- ~CastSessionDelegate() override;
-
- void StartUDP(const net::IPEndPoint& local_endpoint,
- const net::IPEndPoint& remote_endpoint,
- std::unique_ptr<base::DictionaryValue> options,
- const ErrorCallback& error_callback);
-
- // After calling StartAudio() or StartVideo() encoding of that media will
- // begin as soon as data is delivered to its sink, if the second method is
- // called the first media will be restarted. It is strongly recommended not to
- // deliver any data between calling the two methods.
- // It's OK to call only one of the two methods.
- // StartUDP must be called before these methods.
- void StartAudio(const media::cast::FrameSenderConfig& config,
- const AudioFrameInputAvailableCallback& callback,
- ErrorOnceCallback error_callback);
-
- void StartVideo(
- const media::cast::FrameSenderConfig& config,
- const VideoFrameInputAvailableCallback& callback,
- const ErrorCallback& error_callback,
- const media::cast::CreateVideoEncodeAcceleratorCallback& create_vea_cb,
- const media::cast::CreateVideoEncodeMemoryCallback&
- create_video_encode_mem_cb);
-
- // Start remoting session for one stream. After calling this method, a
- // remoting sender will be ready for sending the demuxed stream. StartUDP()
- // must be called before calling this method.
- void StartRemotingStream(int32_t stream_id,
- const media::cast::FrameSenderConfig& config,
- ErrorOnceCallback error_callback);
-
- void ToggleLogging(bool is_audio, bool enable);
- void GetEventLogsAndReset(bool is_audio,
- const std::string& extra_data, const EventLogsCallback& callback);
- void GetStatsAndReset(bool is_audio, const StatsCallback& callback);
-
- protected:
- // Called to report back operational status changes. The first time this is
- // called with STATUS_INITIALIZED will result in running the "frame input
- // available" callback, to indicate the session is ready to accept incoming
- // audio/video frames. If this is called with an error that has halted the
- // session, the |error_callback| provided to StartXXX() will be run. This
- // method may be called multiple times during the session to indicate codec
- // re-initializations are taking place and/or runtime errors have occurred.
- void OnOperationalStatusChange(bool is_for_audio,
- ErrorOnceCallback error_callback,
- media::cast::OperationalStatus result);
-
- private:
- void ReceivePacket(std::unique_ptr<media::cast::Packet> packet) override;
-
- std::unique_ptr<media::cast::CastSender> cast_sender_;
-
- AudioFrameInputAvailableCallback audio_frame_input_available_callback_;
- VideoFrameInputAvailableCallback video_frame_input_available_callback_;
-
- std::unique_ptr<media::cast::RawEventSubscriberBundle> event_subscribers_;
-
- base::WeakPtrFactory<CastSessionDelegate> weak_factory_{this};
-
- DISALLOW_COPY_AND_ASSIGN(CastSessionDelegate);
-};
-
-#endif // CHROME_RENDERER_MEDIA_CAST_SESSION_DELEGATE_H_
diff --git a/chromium/chrome/renderer/media/cast_threads.cc b/chromium/chrome/renderer/media/cast_threads.cc
deleted file mode 100644
index 823df61f05e..00000000000
--- a/chromium/chrome/renderer/media/cast_threads.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2014 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 "chrome/renderer/media/cast_threads.h"
-
-#include "base/single_thread_task_runner.h"
-
-CastThreads::CastThreads()
- : audio_encode_thread_("CastAudioEncodeThread"),
- video_encode_thread_("CastVideoEncodeThread") {
- audio_encode_thread_.Start();
- video_encode_thread_.Start();
-}
-
-scoped_refptr<base::SingleThreadTaskRunner>
-CastThreads::GetAudioEncodeTaskRunner() {
- return audio_encode_thread_.task_runner();
-}
-
-scoped_refptr<base::SingleThreadTaskRunner>
-CastThreads::GetVideoEncodeTaskRunner() {
- return video_encode_thread_.task_runner();
-}
diff --git a/chromium/chrome/renderer/media/cast_threads.h b/chromium/chrome/renderer/media/cast_threads.h
deleted file mode 100644
index 01f05552a0c..00000000000
--- a/chromium/chrome/renderer/media/cast_threads.h
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2014 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.
-
-// Manages threads used by Cast Streaming Extensions API. There is a
-// singleton object of this class in the renderer.
-//
-// There are two threads owned by this class:
-// 1. Audio encode thread.
-// 2. Video encode thread.
-// These two threads are started this object is created.
-
-#ifndef CHROME_RENDERER_MEDIA_CAST_THREADS_H_
-#define CHROME_RENDERER_MEDIA_CAST_THREADS_H_
-
-#include "base/lazy_instance.h"
-#include "base/macros.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread.h"
-
-class CastThreads {
- public:
- scoped_refptr<base::SingleThreadTaskRunner> GetAudioEncodeTaskRunner();
- scoped_refptr<base::SingleThreadTaskRunner> GetVideoEncodeTaskRunner();
-
- private:
- friend struct base::LazyInstanceTraitsBase<CastThreads>;
-
- CastThreads();
-
- base::Thread audio_encode_thread_;
- base::Thread video_encode_thread_;
-
- DISALLOW_COPY_AND_ASSIGN(CastThreads);
-};
-
-#endif // CHROME_RENDERER_MEDIA_CAST_THREADS_H_
diff --git a/chromium/chrome/renderer/media/cast_transport_ipc.cc b/chromium/chrome/renderer/media/cast_transport_ipc.cc
deleted file mode 100644
index 06842f3bd02..00000000000
--- a/chromium/chrome/renderer/media/cast_transport_ipc.cc
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2014 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 "chrome/renderer/media/cast_transport_ipc.h"
-
-#include <memory>
-#include <utility>
-
-#include "base/callback.h"
-#include "base/containers/id_map.h"
-#include "chrome/common/cast_messages.h"
-#include "chrome/renderer/media/cast_ipc_dispatcher.h"
-#include "ipc/ipc_channel_proxy.h"
-#include "media/cast/cast_sender.h"
-
-CastTransportIPC::CastTransportIPC(
- const net::IPEndPoint& local_end_point,
- const net::IPEndPoint& remote_end_point,
- std::unique_ptr<base::DictionaryValue> options,
- media::cast::PacketReceiverCallback packet_callback,
- media::cast::CastTransportStatusCallback status_callback,
- BulkRawEventsCallback raw_events_cb)
- : channel_id_(-1),
- packet_callback_(std::move(packet_callback)),
- status_callback_(std::move(status_callback)),
- raw_events_callback_(std::move(raw_events_cb)) {
- if (CastIPCDispatcher::Get()) {
- // TODO(miu): CastIPCDispatcher should be provided as a ctor argument.
- channel_id_ = CastIPCDispatcher::Get()->AddSender(this);
- Send(new CastHostMsg_New(channel_id_, local_end_point, remote_end_point,
- *options));
- }
-}
-
-CastTransportIPC::~CastTransportIPC() {
- Send(new CastHostMsg_Delete(channel_id_));
- if (CastIPCDispatcher::Get()) {
- CastIPCDispatcher::Get()->RemoveSender(channel_id_);
- }
-}
-
-void CastTransportIPC::InitializeStream(
- const media::cast::CastTransportRtpConfig& config,
- std::unique_ptr<media::cast::RtcpObserver> rtcp_observer) {
- if (rtcp_observer) {
- DCHECK(clients_.find(config.ssrc) == clients_.end());
- clients_[config.ssrc] = std::move(rtcp_observer);
- }
- Send(new CastHostMsg_InitializeStream(channel_id_, config));
-}
-
-void CastTransportIPC::InsertFrame(uint32_t ssrc,
- const media::cast::EncodedFrame& frame) {
- Send(new CastHostMsg_InsertFrame(channel_id_, ssrc, frame));
-}
-
-void CastTransportIPC::SendSenderReport(
- uint32_t ssrc,
- base::TimeTicks current_time,
- media::cast::RtpTimeTicks current_time_as_rtp_timestamp) {
- Send(new CastHostMsg_SendSenderReport(channel_id_, ssrc, current_time,
- current_time_as_rtp_timestamp));
-}
-
-void CastTransportIPC::CancelSendingFrames(
- uint32_t ssrc,
- const std::vector<media::cast::FrameId>& frame_ids) {
- Send(new CastHostMsg_CancelSendingFrames(channel_id_, ssrc, frame_ids));
-}
-
-void CastTransportIPC::ResendFrameForKickstart(uint32_t ssrc,
- media::cast::FrameId frame_id) {
- Send(new CastHostMsg_ResendFrameForKickstart(channel_id_, ssrc, frame_id));
-}
-
-void CastTransportIPC::AddValidRtpReceiver(uint32_t rtp_sender_ssrc,
- uint32_t rtp_receiver_ssrc) {
- Send(new CastHostMsg_AddValidRtpReceiver(channel_id_, rtp_sender_ssrc,
- rtp_receiver_ssrc));
-}
-
-void CastTransportIPC::InitializeRtpReceiverRtcpBuilder(
- uint32_t rtp_receiver_ssrc,
- const media::cast::RtcpTimeData& time_data) {
- Send(new CastHostMsg_InitializeRtpReceiverRtcpBuilder(
- channel_id_, rtp_receiver_ssrc, time_data));
-}
-
-void CastTransportIPC::AddCastFeedback(
- const media::cast::RtcpCastMessage& cast_message,
- base::TimeDelta target_delay) {
- Send(
- new CastHostMsg_AddCastFeedback(channel_id_, cast_message, target_delay));
-}
-
-void CastTransportIPC::AddPli(const media::cast::RtcpPliMessage& pli_message) {
- Send(new CastHostMsg_AddPli(channel_id_, pli_message));
-}
-
-void CastTransportIPC::AddRtcpEvents(
- const media::cast::ReceiverRtcpEventSubscriber::RtcpEvents& rtcp_events) {
- Send(new CastHostMsg_AddRtcpEvents(channel_id_, rtcp_events));
-}
-
-void CastTransportIPC::AddRtpReceiverReport(
- const media::cast::RtcpReportBlock& rtp_receiver_report_block) {
- Send(new CastHostMsg_AddRtpReceiverReport(channel_id_,
- rtp_receiver_report_block));
-}
-
-void CastTransportIPC::SendRtcpFromRtpReceiver() {
- Send(new CastHostMsg_SendRtcpFromRtpReceiver(channel_id_));
-}
-
-void CastTransportIPC::OnNotifyStatusChange(
- media::cast::CastTransportStatus status) {
- status_callback_.Run(status);
-}
-
-void CastTransportIPC::OnRawEvents(
- const std::vector<media::cast::PacketEvent>& packet_events,
- const std::vector<media::cast::FrameEvent>& frame_events) {
- // Note: Casting away const to avoid having to copy all the data elements. As
- // the only consumer of this data in the IPC message, mutating the inputs
- // should be acceptable. Just nod and blame the interface we were given here.
- std::unique_ptr<std::vector<media::cast::FrameEvent>> taken_frame_events(
- new std::vector<media::cast::FrameEvent>());
- taken_frame_events->swap(
- const_cast<std::vector<media::cast::FrameEvent>&>(frame_events));
- std::unique_ptr<std::vector<media::cast::PacketEvent>> taken_packet_events(
- new std::vector<media::cast::PacketEvent>());
- taken_packet_events->swap(
- const_cast<std::vector<media::cast::PacketEvent>&>(packet_events));
- raw_events_callback_.Run(std::move(taken_frame_events),
- std::move(taken_packet_events));
-}
-
-void CastTransportIPC::OnRtt(uint32_t rtp_sender_ssrc, base::TimeDelta rtt) {
- auto it = clients_.find(rtp_sender_ssrc);
- if (it == clients_.end()) {
- LOG(ERROR) << "Received RTT report for unknown SSRC: " << rtp_sender_ssrc;
- return;
- }
- it->second->OnReceivedRtt(rtt);
-}
-
-void CastTransportIPC::OnRtcpCastMessage(
- uint32_t rtp_sender_ssrc,
- const media::cast::RtcpCastMessage& cast_message) {
- auto it = clients_.find(rtp_sender_ssrc);
- if (it == clients_.end()) {
- LOG(ERROR) << "Received cast message for unknown SSRC: " << rtp_sender_ssrc;
- return;
- }
- it->second->OnReceivedCastMessage(cast_message);
-}
-
-void CastTransportIPC::OnReceivedPli(uint32_t rtp_sender_ssrc) {
- auto it = clients_.find(rtp_sender_ssrc);
- if (it == clients_.end()) {
- LOG(ERROR) << "Received picture loss indicator for unknown SSRC: "
- << rtp_sender_ssrc;
- return;
- }
- it->second->OnReceivedPli();
-}
-
-void CastTransportIPC::OnReceivedPacket(const media::cast::Packet& packet) {
- if (!packet_callback_.is_null()) {
- // TODO(hubbe): Perhaps an non-ownership-transferring cb here?
- std::unique_ptr<media::cast::Packet> packet_copy(
- new media::cast::Packet(packet));
- packet_callback_.Run(std::move(packet_copy));
- } else {
- DVLOG(1) << "CastIPCDispatcher::OnReceivedPacket no packet callback yet.";
- }
-}
-
-void CastTransportIPC::Send(IPC::Message* message) {
- if (CastIPCDispatcher::Get() && channel_id_ != -1) {
- CastIPCDispatcher::Get()->Send(message);
- } else {
- delete message;
- }
-}
diff --git a/chromium/chrome/renderer/media/cast_transport_ipc.h b/chromium/chrome/renderer/media/cast_transport_ipc.h
deleted file mode 100644
index 3ee563bd636..00000000000
--- a/chromium/chrome/renderer/media/cast_transport_ipc.h
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2014 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 CHROME_RENDERER_MEDIA_CAST_TRANSPORT_IPC_H_
-#define CHROME_RENDERER_MEDIA_CAST_TRANSPORT_IPC_H_
-
-#include <stdint.h>
-
-#include <map>
-#include <memory>
-
-#include "base/macros.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "ipc/ipc_channel_proxy.h"
-#include "media/cast/logging/logging_defines.h"
-#include "media/cast/net/cast_transport.h"
-
-// This implementation of the CastTransport interface communicates with the
-// browser process over IPC and relays all calls to/from the cast transport to
-// the browser process. The primary reason for this arrangement is to give the
-// renderer less direct control over the UDP sockets.
-class CastTransportIPC : public media::cast::CastTransport {
- public:
- // Runs when a raw event completes.
- using BulkRawEventsCallback = base::RepeatingCallback<void(
- std::unique_ptr<std::vector<media::cast::FrameEvent>>,
- std::unique_ptr<std::vector<media::cast::PacketEvent>>)>;
-
- CastTransportIPC(const net::IPEndPoint& local_end_point,
- const net::IPEndPoint& remote_end_point,
- std::unique_ptr<base::DictionaryValue> options,
- media::cast::PacketReceiverCallback packet_callback,
- media::cast::CastTransportStatusCallback status_callback,
- BulkRawEventsCallback raw_events_cb);
-
- ~CastTransportIPC() override;
-
- // media::cast::CastTransport implementation.
- void InitializeStream(
- const media::cast::CastTransportRtpConfig& config,
- std::unique_ptr<media::cast::RtcpObserver> rtcp_observer) override;
- void InsertFrame(uint32_t ssrc,
- const media::cast::EncodedFrame& frame) override;
- void SendSenderReport(
- uint32_t ssrc,
- base::TimeTicks current_time,
- media::cast::RtpTimeTicks current_time_as_rtp_timestamp) override;
- void CancelSendingFrames(
- uint32_t ssrc,
- const std::vector<media::cast::FrameId>& frame_ids) override;
- void ResendFrameForKickstart(uint32_t ssrc,
- media::cast::FrameId frame_id) override;
- void AddValidRtpReceiver(uint32_t rtp_sender_ssrc,
- uint32_t rtp_receiver_ssrc) override;
- void InitializeRtpReceiverRtcpBuilder(
- uint32_t rtp_receiver_ssrc,
- const media::cast::RtcpTimeData& time_data) override;
- void AddCastFeedback(const media::cast::RtcpCastMessage& cast_message,
- base::TimeDelta target_delay) override;
- void AddPli(const media::cast::RtcpPliMessage& pli_message) override;
- void AddRtcpEvents(const media::cast::ReceiverRtcpEventSubscriber::RtcpEvents&
- rtcp_events) override;
- void AddRtpReceiverReport(
- const media::cast::RtcpReportBlock& rtp_receiver_report_block) override;
- void SendRtcpFromRtpReceiver() override;
- void SetOptions(const base::DictionaryValue& options) final {}
- void OnNotifyStatusChange(media::cast::CastTransportStatus status);
- void OnRawEvents(const std::vector<media::cast::PacketEvent>& packet_events,
- const std::vector<media::cast::FrameEvent>& frame_events);
- void OnRtt(uint32_t rtp_sender_ssrc, base::TimeDelta rtt);
- void OnRtcpCastMessage(uint32_t rtp_sender_ssrc,
- const media::cast::RtcpCastMessage& cast_message);
- void OnReceivedPli(uint32_t rtp_sender_ssrc);
- void OnReceivedPacket(const media::cast::Packet& packet);
-
- private:
- void Send(IPC::Message* message);
-
- int32_t channel_id_;
- media::cast::PacketReceiverCallback packet_callback_;
- media::cast::CastTransportStatusCallback status_callback_;
- const BulkRawEventsCallback raw_events_callback_;
- using ClientMap =
- std::map<uint32_t, std::unique_ptr<media::cast::RtcpObserver>>;
- ClientMap clients_;
-
- DISALLOW_COPY_AND_ASSIGN(CastTransportIPC);
-};
-
-#endif // CHROME_RENDERER_MEDIA_CAST_TRANSPORT_IPC_H_
diff --git a/chromium/chrome/renderer/media/cast_udp_transport.cc b/chromium/chrome/renderer/media/cast_udp_transport.cc
deleted file mode 100644
index a8302a8a0fa..00000000000
--- a/chromium/chrome/renderer/media/cast_udp_transport.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2013 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 "chrome/renderer/media/cast_udp_transport.h"
-
-#include <memory>
-#include <utility>
-
-#include "base/memory/ptr_util.h"
-#include "base/values.h"
-#include "chrome/renderer/media/cast_session.h"
-
-CastUdpTransport::CastUdpTransport(const scoped_refptr<CastSession>& session)
- : cast_session_(session), options_(new base::DictionaryValue) {}
-
-CastUdpTransport::~CastUdpTransport() {
-}
-
-void CastUdpTransport::SetDestination(
- const net::IPEndPoint& remote_address,
- const CastSessionDelegate::ErrorCallback& error_callback) {
- DVLOG(1) << "CastUdpTransport::SetDestination = "
- << remote_address.ToString();
- remote_address_ = remote_address;
- cast_session_->StartUDP(
- remote_address, base::WrapUnique(options_->DeepCopy()), error_callback);
-}
-
-void CastUdpTransport::SetOptions(
- std::unique_ptr<base::DictionaryValue> options) {
- options_ = std::move(options);
-}
diff --git a/chromium/chrome/renderer/media/cast_udp_transport.h b/chromium/chrome/renderer/media/cast_udp_transport.h
deleted file mode 100644
index 726edbe5c67..00000000000
--- a/chromium/chrome/renderer/media/cast_udp_transport.h
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2013 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 CHROME_RENDERER_MEDIA_CAST_UDP_TRANSPORT_H_
-#define CHROME_RENDERER_MEDIA_CAST_UDP_TRANSPORT_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "chrome/renderer/media/cast_session_delegate.h"
-#include "net/base/ip_endpoint.h"
-
-namespace base {
-class DictionaryValue;
-} // namespace base
-
-class CastSession;
-
-// This class represents the transport mechanism used by Cast RTP streams
-// to connect to a remote client. It specifies the destination address
-// and network protocol used to send Cast RTP streams.
-class CastUdpTransport {
- public:
- explicit CastUdpTransport(const scoped_refptr<CastSession>& session);
- virtual ~CastUdpTransport();
-
- // Specify the remote IP address and port.
- void SetDestination(const net::IPEndPoint& remote_address,
- const CastSessionDelegate::ErrorCallback& error_callback);
-
- // Set options.
- void SetOptions(std::unique_ptr<base::DictionaryValue> options);
-
- private:
- const scoped_refptr<CastSession> cast_session_;
- net::IPEndPoint remote_address_;
- std::unique_ptr<base::DictionaryValue> options_;
- base::WeakPtrFactory<CastUdpTransport> weak_factory_{this};
-
- DISALLOW_COPY_AND_ASSIGN(CastUdpTransport);
-};
-
-#endif // CHROME_RENDERER_MEDIA_CAST_UDP_TRANSPORT_H_
diff --git a/chromium/chrome/renderer/media/chrome_speech_recognition_client.cc b/chromium/chrome/renderer/media/chrome_speech_recognition_client.cc
index 2b35d6d399a..70da74b25e7 100644
--- a/chromium/chrome/renderer/media/chrome_speech_recognition_client.cc
+++ b/chromium/chrome/renderer/media/chrome_speech_recognition_client.cc
@@ -6,22 +6,60 @@
#include <utility>
+#include "base/metrics/field_trial_params.h"
#include "content/public/renderer/render_frame.h"
+#include "media/base/audio_bus.h"
+#include "media/base/audio_parameters.h"
+#include "media/base/bind_to_current_loop.h"
+#include "media/base/channel_mixer.h"
+#include "media/base/media_switches.h"
#include "media/mojo/mojom/media_types.mojom.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
+#include "third_party/blink/public/platform/web_string.h"
+#include "third_party/blink/public/web/web_frame.h"
+#include "third_party/blink/public/web/web_local_frame.h"
+
+// Get the list of blocked URLs defined by the Finch experiment parameter. These
+// websites provide captions by default and thus do not require the live caption
+// feature.
+std::vector<std::string> GetBlockedURLs() {
+ return base::SplitString(base::GetFieldTrialParamValueByFeature(
+ media::kLiveCaption, "blocked_websites"),
+ ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+}
ChromeSpeechRecognitionClient::ChromeSpeechRecognitionClient(
- content::RenderFrame* render_frame) {
+ content::RenderFrame* render_frame,
+ media::SpeechRecognitionClient::OnReadyCallback callback)
+ : on_ready_callback_(std::move(callback)), blocked_urls_(GetBlockedURLs()) {
mojo::PendingReceiver<media::mojom::SpeechRecognitionContext>
speech_recognition_context_receiver =
speech_recognition_context_.BindNewPipeAndPassReceiver();
speech_recognition_context_->BindRecognizer(
speech_recognition_recognizer_.BindNewPipeAndPassReceiver(),
- speech_recognition_client_receiver_.BindNewPipeAndPassRemote());
+ speech_recognition_client_receiver_.BindNewPipeAndPassRemote(),
+ base::BindOnce(&ChromeSpeechRecognitionClient::OnRecognizerBound,
+ base::Unretained(this)));
+
render_frame->GetBrowserInterfaceBroker()->GetInterface(
std::move(speech_recognition_context_receiver));
render_frame->GetBrowserInterfaceBroker()->GetInterface(
caption_host_.BindNewPipeAndPassReceiver());
+ is_website_blocked_ = IsUrlBlocked(
+ render_frame->GetWebFrame()->GetSecurityOrigin().ToString().Utf8());
+
+ send_audio_callback_ = media::BindToCurrentLoop(base::BindRepeating(
+ &ChromeSpeechRecognitionClient::SendAudioToSpeechRecognitionService,
+ weak_factory_.GetWeakPtr()));
+}
+
+void ChromeSpeechRecognitionClient::OnRecognizerBound(
+ bool is_multichannel_supported) {
+ is_multichannel_supported_ = is_multichannel_supported;
+ is_recognizer_bound_ = true;
+
+ if (on_ready_callback_)
+ std::move(on_ready_callback_).Run();
}
ChromeSpeechRecognitionClient::~ChromeSpeechRecognitionClient() = default;
@@ -29,21 +67,85 @@ ChromeSpeechRecognitionClient::~ChromeSpeechRecognitionClient() = default;
void ChromeSpeechRecognitionClient::AddAudio(
scoped_refptr<media::AudioBuffer> buffer) {
DCHECK(buffer);
- if (IsSpeechRecognitionAvailable()) {
- speech_recognition_recognizer_->SendAudioToSpeechRecognitionService(
- ConvertToAudioDataS16(std::move(buffer)));
- }
+ send_audio_callback_.Run(ConvertToAudioDataS16(std::move(buffer)));
+}
+
+void ChromeSpeechRecognitionClient::AddAudio(
+ std::unique_ptr<media::AudioBus> audio_bus,
+ int sample_rate,
+ media::ChannelLayout channel_layout) {
+ DCHECK(audio_bus);
+ send_audio_callback_.Run(
+ ConvertToAudioDataS16(std::move(audio_bus), sample_rate, channel_layout));
}
bool ChromeSpeechRecognitionClient::IsSpeechRecognitionAvailable() {
- return speech_recognition_recognizer_.is_bound() &&
- speech_recognition_recognizer_.is_connected();
+ // TODO(evliu): Check if SODA is available.
+ return !is_website_blocked_ && is_browser_requesting_transcription_ &&
+ is_recognizer_bound_;
+}
+
+// The OnReadyCallback is set by the owner of |this| and is executed when speech
+// recognition becomes available. Setting the callback will override any
+// existing callback.
+void ChromeSpeechRecognitionClient::SetOnReadyCallback(
+ SpeechRecognitionClient::OnReadyCallback callback) {
+ on_ready_callback_ = std::move(callback);
+
+ // Immediately run the callback if speech recognition is already available.
+ if (IsSpeechRecognitionAvailable() && on_ready_callback_)
+ std::move(on_ready_callback_).Run();
}
void ChromeSpeechRecognitionClient::OnSpeechRecognitionRecognitionEvent(
media::mojom::SpeechRecognitionResultPtr result) {
- caption_host_->OnTranscription(chrome::mojom::TranscriptionResult::New(
- result->transcription, result->is_final));
+ caption_host_->OnTranscription(
+ chrome::mojom::TranscriptionResult::New(result->transcription,
+ result->is_final),
+ base::BindOnce(&ChromeSpeechRecognitionClient::OnTranscriptionCallback,
+ base::Unretained(this)));
+}
+
+void ChromeSpeechRecognitionClient::OnTranscriptionCallback(bool success) {
+ is_browser_requesting_transcription_ = success;
+}
+
+void ChromeSpeechRecognitionClient::CopyBufferToTempAudioBus(
+ const media::AudioBuffer& buffer) {
+ if (!temp_audio_bus_ ||
+ buffer.channel_count() != temp_audio_bus_->channels() ||
+ buffer.frame_count() != temp_audio_bus_->frames()) {
+ temp_audio_bus_ =
+ media::AudioBus::Create(buffer.channel_count(), buffer.frame_count());
+ }
+
+ buffer.ReadFrames(buffer.frame_count(),
+ /* source_frame_offset */ 0, /* dest_frame_offset */ 0,
+ temp_audio_bus_.get());
+}
+
+void ChromeSpeechRecognitionClient::ResetChannelMixer(
+ int frame_count,
+ media::ChannelLayout channel_layout) {
+ if (!monaural_audio_bus_ || frame_count != monaural_audio_bus_->frames()) {
+ monaural_audio_bus_ =
+ media::AudioBus::Create(1 /* channels */, frame_count);
+ }
+
+ if (channel_layout != channel_layout_) {
+ channel_layout_ = channel_layout;
+ channel_mixer_ = std::make_unique<media::ChannelMixer>(
+ channel_layout, media::CHANNEL_LAYOUT_MONO);
+ }
+}
+
+void ChromeSpeechRecognitionClient::SendAudioToSpeechRecognitionService(
+ media::mojom::AudioDataS16Ptr audio_data) {
+ DCHECK(audio_data);
+ if (IsSpeechRecognitionAvailable()) {
+ speech_recognition_recognizer_->SendAudioToSpeechRecognitionService(
+ std::move(audio_data));
+ }
}
media::mojom::AudioDataS16Ptr
@@ -58,6 +160,21 @@ ChromeSpeechRecognitionClient::ConvertToAudioDataS16(
signed_buffer->frame_count = buffer->frame_count();
signed_buffer->sample_rate = buffer->sample_rate();
+ // If multichannel audio is not supported by the speech recognition service,
+ // mix the channels into a monaural channel before converting it.
+ if (buffer->channel_count() > 1 && !is_multichannel_supported_) {
+ signed_buffer->channel_count = 1;
+ CopyBufferToTempAudioBus(*buffer);
+ ResetChannelMixer(buffer->frame_count(), buffer->channel_layout());
+ signed_buffer->data.resize(buffer->frame_count());
+ channel_mixer_->Transform(temp_audio_bus_.get(), monaural_audio_bus_.get());
+ monaural_audio_bus_->ToInterleaved<media::SignedInt16SampleTypeTraits>(
+ monaural_audio_bus_->frames(), &signed_buffer->data[0]);
+ return signed_buffer;
+ }
+
+ // If the audio is already in the interleaved signed int 16 format, directly
+ // assign it to the buffer.
if (buffer->sample_format() == media::SampleFormat::kSampleFormatS16) {
int16_t* audio_data = reinterpret_cast<int16_t*>(buffer->channel_data()[0]);
signed_buffer->data.assign(
@@ -67,20 +184,48 @@ ChromeSpeechRecognitionClient::ConvertToAudioDataS16(
}
// Convert the raw audio to the interleaved signed int 16 sample type.
- if (!temp_audio_bus_ ||
- buffer->channel_count() != temp_audio_bus_->channels() ||
- buffer->frame_count() != temp_audio_bus_->frames()) {
- temp_audio_bus_ =
- media::AudioBus::Create(buffer->channel_count(), buffer->frame_count());
- }
-
- buffer->ReadFrames(buffer->frame_count(),
- /* source_frame_offset */ 0, /* dest_frame_offset */ 0,
- temp_audio_bus_.get());
-
+ CopyBufferToTempAudioBus(*buffer);
signed_buffer->data.resize(buffer->frame_count() * buffer->channel_count());
temp_audio_bus_->ToInterleaved<media::SignedInt16SampleTypeTraits>(
temp_audio_bus_->frames(), &signed_buffer->data[0]);
return signed_buffer;
}
+
+media::mojom::AudioDataS16Ptr
+ChromeSpeechRecognitionClient::ConvertToAudioDataS16(
+ std::unique_ptr<media::AudioBus> audio_bus,
+ int sample_rate,
+ media::ChannelLayout channel_layout) {
+ DCHECK_GT(audio_bus->frames(), 0);
+ DCHECK_GT(audio_bus->channels(), 0);
+
+ auto signed_buffer = media::mojom::AudioDataS16::New();
+ signed_buffer->channel_count = audio_bus->channels();
+ signed_buffer->frame_count = audio_bus->frames();
+ signed_buffer->sample_rate = sample_rate;
+
+ // If multichannel audio is not supported by the speech recognition service,
+ // mix the channels into a monaural channel before converting it.
+ if (audio_bus->channels() > 1 && !is_multichannel_supported_) {
+ signed_buffer->channel_count = 1;
+ ResetChannelMixer(audio_bus->frames(), channel_layout);
+ signed_buffer->data.resize(audio_bus->frames());
+
+ channel_mixer_->Transform(audio_bus.get(), monaural_audio_bus_.get());
+ monaural_audio_bus_->ToInterleaved<media::SignedInt16SampleTypeTraits>(
+ monaural_audio_bus_->frames(), &signed_buffer->data[0]);
+
+ return signed_buffer;
+ }
+
+ signed_buffer->data.resize(audio_bus->frames() * audio_bus->channels());
+ audio_bus->ToInterleaved<media::SignedInt16SampleTypeTraits>(
+ audio_bus->frames(), &signed_buffer->data[0]);
+
+ return signed_buffer;
+}
+
+bool ChromeSpeechRecognitionClient::IsUrlBlocked(const std::string& url) const {
+ return blocked_urls_.find(url) != blocked_urls_.end();
+}
diff --git a/chromium/chrome/renderer/media/chrome_speech_recognition_client.h b/chromium/chrome/renderer/media/chrome_speech_recognition_client.h
index 5f08b42cfd9..df0e0574a87 100644
--- a/chromium/chrome/renderer/media/chrome_speech_recognition_client.h
+++ b/chromium/chrome/renderer/media/chrome_speech_recognition_client.h
@@ -8,6 +8,8 @@
#include <memory>
#include <string>
+#include "base/containers/flat_set.h"
+#include "base/memory/weak_ptr.h"
#include "chrome/common/caption.mojom.h"
#include "media/base/audio_buffer.h"
#include "media/base/speech_recognition_client.h"
@@ -19,11 +21,21 @@ namespace content {
class RenderFrame;
} // namespace content
+namespace media {
+class AudioBus;
+class ChannelMixer;
+} // namespace media
+
class ChromeSpeechRecognitionClient
: public media::SpeechRecognitionClient,
public media::mojom::SpeechRecognitionRecognizerClient {
public:
- explicit ChromeSpeechRecognitionClient(content::RenderFrame* render_frame);
+ using SendAudioToSpeechRecognitionServiceCallback =
+ base::RepeatingCallback<void(media::mojom::AudioDataS16Ptr audio_data)>;
+
+ explicit ChromeSpeechRecognitionClient(
+ content::RenderFrame* render_frame,
+ media::SpeechRecognitionClient::OnReadyCallback callback);
ChromeSpeechRecognitionClient(const ChromeSpeechRecognitionClient&) = delete;
ChromeSpeechRecognitionClient& operator=(
const ChromeSpeechRecognitionClient&) = delete;
@@ -31,16 +43,51 @@ class ChromeSpeechRecognitionClient
// media::SpeechRecognitionClient
void AddAudio(scoped_refptr<media::AudioBuffer> buffer) override;
+ void AddAudio(std::unique_ptr<media::AudioBus> audio_bus,
+ int sample_rate,
+ media::ChannelLayout channel_layout) override;
bool IsSpeechRecognitionAvailable() override;
+ void SetOnReadyCallback(
+ SpeechRecognitionClient::OnReadyCallback callback) override;
+
+ // Callback executed when the recognizer is bound. Sets the flag indicating
+ // whether the speech recognition service supports multichannel audio.
+ void OnRecognizerBound(bool is_multichannel_supported);
// media::mojom::SpeechRecognitionRecognizerClient
void OnSpeechRecognitionRecognitionEvent(
media::mojom::SpeechRecognitionResultPtr result) override;
private:
+ void SendAudioToSpeechRecognitionService(
+ media::mojom::AudioDataS16Ptr audio_data);
+
media::mojom::AudioDataS16Ptr ConvertToAudioDataS16(
scoped_refptr<media::AudioBuffer> buffer);
+ // Called as a response to sending a transcription to the browser.
+ void OnTranscriptionCallback(bool success);
+
+ media::mojom::AudioDataS16Ptr ConvertToAudioDataS16(
+ std::unique_ptr<media::AudioBus> audio_bus,
+ int sample_rate,
+ media::ChannelLayout channel_layout);
+
+ // Recreates the temporary audio bus if the frame count or channel count
+ // changed and reads the frames from the buffer into the temporary audio bus.
+ void CopyBufferToTempAudioBus(const media::AudioBuffer& buffer);
+
+ // Resets the temporary monaural audio bus and the channel mixer used to
+ // combine multiple audio channels.
+ void ResetChannelMixer(int frame_count, media::ChannelLayout channel_layout);
+
+ bool IsUrlBlocked(const std::string& url) const;
+
+ media::SpeechRecognitionClient::OnReadyCallback on_ready_callback_;
+
+ // Sends audio to the speech recognition thread on the renderer thread.
+ SendAudioToSpeechRecognitionServiceCallback send_audio_callback_;
+
mojo::Remote<media::mojom::SpeechRecognitionContext>
speech_recognition_context_;
mojo::Remote<media::mojom::SpeechRecognitionRecognizer>
@@ -49,9 +96,33 @@ class ChromeSpeechRecognitionClient
speech_recognition_client_receiver_{this};
mojo::Remote<chrome::mojom::CaptionHost> caption_host_;
+ bool is_website_blocked_ = false;
+ const base::flat_set<std::string> blocked_urls_;
+
// The temporary audio bus used to convert the raw audio to the appropriate
// format.
std::unique_ptr<media::AudioBus> temp_audio_bus_;
+
+ // Whether the browser is still requesting transcriptions.
+ bool is_browser_requesting_transcription_ = true;
+
+ bool is_recognizer_bound_ = false;
+
+ // The temporary audio bus used to mix multichannel audio into a single
+ // channel.
+ std::unique_ptr<media::AudioBus> monaural_audio_bus_;
+
+ std::unique_ptr<media::ChannelMixer> channel_mixer_;
+
+ // The layout used to instantiate the channel mixer.
+ media::ChannelLayout channel_layout_ =
+ media::ChannelLayout::CHANNEL_LAYOUT_NONE;
+
+ // A flag indicating whether the speech recognition service supports
+ // multichannel audio.
+ bool is_multichannel_supported_ = false;
+
+ base::WeakPtrFactory<ChromeSpeechRecognitionClient> weak_factory_{this};
};
#endif // CHROME_RENDERER_MEDIA_CHROME_SPEECH_RECOGNITION_CLIENT_H_
diff --git a/chromium/chrome/renderer/media/media_feeds.cc b/chromium/chrome/renderer/media/media_feeds.cc
index cdbc1995457..fae6fdeb893 100644
--- a/chromium/chrome/renderer/media/media_feeds.cc
+++ b/chromium/chrome/renderer/media/media_feeds.cc
@@ -45,14 +45,9 @@ base::Optional<GURL> MediaFeeds::GetMediaFeedURL(content::RenderFrame* frame) {
if (!elem.HasHTMLTagName("link"))
continue;
- // The <link> rel must be feed.
+ // The <link> rel must be media-feed.
std::string rel = elem.GetAttribute("rel").Utf8();
- if (!base::LowerCaseEqualsASCII(rel, "feed"))
- continue;
-
- // The <link> type must the JSON+LD mime type.
- std::string type = elem.GetAttribute("type").Utf8();
- if (!base::LowerCaseEqualsASCII(type, "application/ld+json"))
+ if (!base::LowerCaseEqualsASCII(rel, "media-feed"))
continue;
WebString href = elem.GetAttribute("href");
diff --git a/chromium/chrome/renderer/media/webrtc_logging_agent_impl.cc b/chromium/chrome/renderer/media/webrtc_logging_agent_impl.cc
index b8b24d4ebb9..d2495adc221 100644
--- a/chromium/chrome/renderer/media/webrtc_logging_agent_impl.cc
+++ b/chromium/chrome/renderer/media/webrtc_logging_agent_impl.cc
@@ -82,6 +82,7 @@ void WebRtcLoggingAgentImpl::AddReceiver(
void WebRtcLoggingAgentImpl::Start(
mojo::PendingRemote<mojom::WebRtcLoggingClient> pending_client) {
// We only support one client at a time. OK to drop any existing client.
+ client_.reset();
client_.Bind(std::move(pending_client));
WebRtcLogMessageDelegateImpl::GetInstance()->Start(base::BindRepeating(
diff --git a/chromium/chrome/renderer/net/net_error_helper.cc b/chromium/chrome/renderer/net/net_error_helper.cc
index b09c9aacc91..f9c56beebe6 100644
--- a/chromium/chrome/renderer/net/net_error_helper.cc
+++ b/chromium/chrome/renderer/net/net_error_helper.cc
@@ -225,13 +225,7 @@ void NetErrorHelper::DidStartNavigation(
core_->OnStartLoad(GetFrameType(render_frame()), GetLoadingPageType(url));
}
-void NetErrorHelper::DidCommitProvisionalLoad(bool is_same_document_navigation,
- ui::PageTransition transition) {
- // If this is a "same-document" navigation, it's not a real navigation. There
- // wasn't a start event for it, either, so just ignore it.
- if (is_same_document_navigation)
- return;
-
+void NetErrorHelper::DidCommitProvisionalLoad(ui::PageTransition transition) {
// Invalidate weak pointers from old error page controllers. If loading a new
// error page, the controller has not yet been attached, so this won't affect
// it.
@@ -323,6 +317,15 @@ chrome::mojom::NetworkEasterEgg* NetErrorHelper::GetRemoteNetworkEasterEgg() {
return remote_network_easter_egg_.get();
}
+chrome::mojom::NetErrorPageSupport*
+NetErrorHelper::GetRemoteNetErrorPageSupport() {
+ if (!remote_net_error_page_support_) {
+ render_frame()->GetRemoteAssociatedInterfaces()->GetInterface(
+ &remote_net_error_page_support_);
+ }
+ return remote_net_error_page_support_.get();
+}
+
LocalizedError::PageState NetErrorHelper::GenerateLocalizedErrorPage(
const error_page::Error& error,
bool is_failed_post,
@@ -476,18 +479,15 @@ void NetErrorHelper::DiagnoseError(const GURL& page_url) {
}
void NetErrorHelper::DownloadPageLater() {
-#if defined(OS_ANDROID)
- render_frame()->Send(new ChromeViewHostMsg_DownloadPageLater(
- render_frame()->GetRoutingID()));
-#endif // defined(OS_ANDROID)
+#if BUILDFLAG(ENABLE_OFFLINE_PAGES)
+ GetRemoteNetErrorPageSupport()->DownloadPageLater();
+#endif // BUILDFLAG(ENABLE_OFFLINE_PAGES)
}
void NetErrorHelper::SetIsShowingDownloadButton(bool show) {
-#if defined(OS_ANDROID)
- render_frame()->Send(
- new ChromeViewHostMsg_SetIsShowingDownloadButtonInErrorPage(
- render_frame()->GetRoutingID(), show));
-#endif // defined(OS_ANDROID)
+#if BUILDFLAG(ENABLE_OFFLINE_PAGES)
+ GetRemoteNetErrorPageSupport()->SetIsShowingDownloadButtonInErrorPage(show);
+#endif // BUILDFLAG(ENABLE_OFFLINE_PAGES)
}
void NetErrorHelper::OfflineContentAvailable(
diff --git a/chromium/chrome/renderer/net/net_error_helper.h b/chromium/chrome/renderer/net/net_error_helper.h
index 00ae60941fe..6ce1ed95f09 100644
--- a/chromium/chrome/renderer/net/net_error_helper.h
+++ b/chromium/chrome/renderer/net/net_error_helper.h
@@ -13,6 +13,7 @@
#include "base/memory/weak_ptr.h"
#include "build/build_config.h"
#include "chrome/common/navigation_corrector.mojom.h"
+#include "chrome/common/net/net_error_page_support.mojom.h"
#include "chrome/common/network_diagnostics.mojom.h"
#include "chrome/common/network_easter_egg.mojom.h"
#include "chrome/renderer/net/net_error_helper_core.h"
@@ -27,6 +28,7 @@
#include "mojo/public/cpp/bindings/associated_receiver_set.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
+#include "mojo/public/cpp/bindings/remote.h"
#include "net/base/net_errors.h"
class GURL;
@@ -80,8 +82,7 @@ class NetErrorHelper
void DidStartNavigation(
const GURL& url,
base::Optional<blink::WebNavigationType> navigation_type) override;
- void DidCommitProvisionalLoad(bool is_same_document_navigation,
- ui::PageTransition transition) override;
+ void DidCommitProvisionalLoad(ui::PageTransition transition) override;
void DidFinishLoad() override;
void OnStop() override;
void WasShown() override;
@@ -110,6 +111,7 @@ class NetErrorHelper
const GURL& url) const;
chrome::mojom::NetworkDiagnostics* GetRemoteNetworkDiagnostics();
chrome::mojom::NetworkEasterEgg* GetRemoteNetworkEasterEgg();
+ chrome::mojom::NetErrorPageSupport* GetRemoteNetErrorPageSupport();
// NetErrorHelperCore::Delegate implementation:
error_page::LocalizedError::PageState GenerateLocalizedErrorPage(
@@ -189,6 +191,8 @@ class NetErrorHelper
navigation_corrector_receivers_;
mojo::AssociatedRemote<chrome::mojom::NetworkEasterEgg>
remote_network_easter_egg_;
+ mojo::AssociatedRemote<chrome::mojom::NetErrorPageSupport>
+ remote_net_error_page_support_;
// Weak factories for vending weak pointers to PageControllers. Weak
// pointers are invalidated on each commit, to prevent getting messages from
diff --git a/chromium/chrome/renderer/net/net_error_helper_core.cc b/chromium/chrome/renderer/net/net_error_helper_core.cc
index 7ce51f9d9d2..e2e56100e63 100644
--- a/chromium/chrome/renderer/net/net_error_helper_core.cc
+++ b/chromium/chrome/renderer/net/net_error_helper_core.cc
@@ -469,9 +469,8 @@ bool NetErrorHelperCore::IsReloadableError(
info.error.reason() != net::ERR_SSL_PROTOCOL_ERROR &&
// Do not trigger for blacklisted URLs.
// https://crbug.com/803839
- info.error.reason() != net::ERR_BLOCKED_BY_ADMINISTRATOR &&
// Do not trigger for requests that were blocked by the browser itself.
- info.error.reason() != net::ERR_BLOCKED_BY_CLIENT &&
+ !net::IsRequestBlockedError(info.error.reason()) &&
!info.was_failed_post &&
// Do not trigger for this error code because it is used by Chrome
// while an auth prompt is being displayed.
@@ -501,7 +500,8 @@ NetErrorHelperCore::NetErrorHelperCore(Delegate* delegate,
online_(content::RenderThread::Get()->IsOnline()),
visible_(is_visible),
auto_reload_count_(0),
- navigation_from_button_(NO_BUTTON)
+ navigation_from_button_(NO_BUTTON),
+ custom_error_page_(false)
#if defined(OS_ANDROID)
,
page_auto_fetcher_helper_(
@@ -662,7 +662,8 @@ void NetErrorHelperCore::OnFinishLoad(FrameType frame_type) {
committed_error_page_info_->error,
*committed_error_page_info_->navigation_correction_params));
} else if (auto_reload_enabled_ &&
- IsReloadableError(*committed_error_page_info_)) {
+ IsReloadableError(*committed_error_page_info_) &&
+ !custom_error_page_) {
MaybeStartAutoReloadTimer();
}
@@ -691,10 +692,13 @@ void NetErrorHelperCore::PrepareErrorPage(FrameType frame_type,
PrepareErrorPageForMainFrame(pending_error_page_info_.get(), error_html);
} else {
if (error_html) {
+ custom_error_page_ = false;
delegate_->GenerateLocalizedErrorPage(
error, is_failed_post,
false /* No diagnostics dialogs allowed for subframes. */, nullptr,
error_html);
+ } else {
+ custom_error_page_ = true;
}
}
}
@@ -764,9 +768,12 @@ void NetErrorHelperCore::PrepareErrorPageForMainFrame(
error = GetUpdatedError(*pending_error_page_info);
}
if (error_html) {
+ custom_error_page_ = false;
pending_error_page_info->page_state = delegate_->GenerateLocalizedErrorPage(
error, pending_error_page_info->was_failed_post,
can_show_network_diagnostics_dialog_, nullptr, error_html);
+ } else {
+ custom_error_page_ = true;
}
}
diff --git a/chromium/chrome/renderer/net/net_error_helper_core.h b/chromium/chrome/renderer/net/net_error_helper_core.h
index a58cc7ee50b..25862bebe44 100644
--- a/chromium/chrome/renderer/net/net_error_helper_core.h
+++ b/chromium/chrome/renderer/net/net_error_helper_core.h
@@ -339,6 +339,10 @@ class NetErrorHelperCore {
// in errors.
Button navigation_from_button_;
+ // True if the current error page is displaying custom HTML (e.g.
+ // security interstitials).
+ bool custom_error_page_;
+
#if defined(OS_ANDROID)
AvailableOfflineContentHelper available_content_helper_;
std::unique_ptr<PageAutoFetcherHelper> page_auto_fetcher_helper_;
diff --git a/chromium/chrome/renderer/net/net_error_helper_core_unittest.cc b/chromium/chrome/renderer/net/net_error_helper_core_unittest.cc
index b7d13ca7f39..1220513a2d3 100644
--- a/chromium/chrome/renderer/net/net_error_helper_core_unittest.cc
+++ b/chromium/chrome/renderer/net/net_error_helper_core_unittest.cc
@@ -171,7 +171,7 @@ class NetErrorHelperCoreTest : public testing::Test,
public NetErrorHelperCore::Delegate {
public:
NetErrorHelperCoreTest()
- : timer_(NULL),
+ : timer_(nullptr),
update_count_(0),
error_html_update_count_(0),
reload_count_(0),
@@ -310,6 +310,20 @@ class NetErrorHelperCoreTest : public testing::Test,
DoErrorLoadOfURL(error, GURL(kFailedUrl));
}
+ void DoErrorLoadWithCustomErrorPage(net::Error error) {
+ core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
+ NetErrorHelperCore::NON_ERROR_PAGE);
+ // Custom error pages pass nullptr to PrepareErrorPage, since they set the
+ // error HTML on their own.
+ core()->PrepareErrorPage(NetErrorHelperCore::MAIN_FRAME,
+ NetErrorForURL(error, GURL(kFailedUrl)),
+ false /* is_failed_post */, nullptr);
+ core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
+ NetErrorHelperCore::ERROR_PAGE);
+ core()->OnCommitLoad(NetErrorHelperCore::MAIN_FRAME, error_url());
+ core()->OnFinishLoad(NetErrorHelperCore::MAIN_FRAME);
+ }
+
void DoSuccessLoad() {
core()->OnStartLoad(NetErrorHelperCore::MAIN_FRAME,
NetErrorHelperCore::NON_ERROR_PAGE);
@@ -2421,6 +2435,25 @@ TEST_F(NetErrorHelperCoreAutoReloadTest, ManualReloadShowsError) {
net::ERR_CONNECTION_RESET));
}
+TEST_F(NetErrorHelperCoreAutoReloadTest,
+ AutoReloadDisabledForCustomErrorPages) {
+ // This error code would normally trigger auto-reloads, but shouldn't if we
+ // are showing a custom error page (e.g. an interstitial.).
+ DoErrorLoadWithCustomErrorPage(net::ERR_CONNECTION_RESET);
+
+ EXPECT_FALSE(timer()->IsRunning());
+ EXPECT_EQ(0, reload_count());
+}
+
+TEST_F(NetErrorHelperCoreAutoReloadTest,
+ AutoReloadEnabledAfterCustomErrorPage) {
+ DoErrorLoadWithCustomErrorPage(net::ERR_CONNECTION_RESET);
+ EXPECT_FALSE(timer()->IsRunning());
+ EXPECT_EQ(0, reload_count());
+ DoErrorLoad(net::ERR_CONNECTION_RESET);
+ EXPECT_TRUE(timer()->IsRunning());
+}
+
TEST_F(NetErrorHelperCoreTest, ExplicitReloadSucceeds) {
DoErrorLoad(net::ERR_CONNECTION_RESET);
EXPECT_EQ(0, reload_count());
diff --git a/chromium/chrome/renderer/performance_manager/OWNERS b/chromium/chrome/renderer/performance_manager/OWNERS
index 0a5168e1964..6ef4e6df1e5 100644
--- a/chromium/chrome/renderer/performance_manager/OWNERS
+++ b/chromium/chrome/renderer/performance_manager/OWNERS
@@ -1 +1 @@
-file://chrome/browser/performance_manager/OWNERS
+file://components/performance_manager/OWNERS
diff --git a/chromium/chrome/renderer/plugins/chrome_plugin_placeholder.cc b/chromium/chrome/renderer/plugins/chrome_plugin_placeholder.cc
index 4410ede5cb6..d662fe9310c 100644
--- a/chromium/chrome/renderer/plugins/chrome_plugin_placeholder.cc
+++ b/chromium/chrome/renderer/plugins/chrome_plugin_placeholder.cc
@@ -15,7 +15,6 @@
#include "base/values.h"
#include "chrome/common/buildflags.h"
#include "chrome/common/chrome_features.h"
-#include "chrome/common/prerender_messages.h"
#include "chrome/common/render_messages.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/grit/renderer_resources.h"
@@ -24,6 +23,7 @@
#include "chrome/renderer/plugins/plugin_preroller.h"
#include "chrome/renderer/plugins/plugin_uma.h"
#include "components/content_settings/renderer/content_settings_agent_impl.h"
+#include "components/prerender/common/prerender_messages.h"
#include "components/strings/grit/components_strings.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/untrustworthy_context_menu_params.h"
@@ -212,9 +212,9 @@ void ChromePluginPlaceholder::UpdateFailure() {
}
void ChromePluginPlaceholder::OnSetPrerenderMode(
- prerender::PrerenderMode mode,
+ prerender::mojom::PrerenderMode mode,
const std::string& histogram_prefix) {
- OnSetIsPrerendering(mode != prerender::NO_PRERENDER);
+ OnSetIsPrerendering(mode != prerender::mojom::PrerenderMode::kNoPrerender);
}
void ChromePluginPlaceholder::PluginListChanged() {
diff --git a/chromium/chrome/renderer/plugins/chrome_plugin_placeholder.h b/chromium/chrome/renderer/plugins/chrome_plugin_placeholder.h
index 738a37a2679..88c7e513e2a 100644
--- a/chromium/chrome/renderer/plugins/chrome_plugin_placeholder.h
+++ b/chromium/chrome/renderer/plugins/chrome_plugin_placeholder.h
@@ -11,9 +11,9 @@
#include "base/macros.h"
#include "chrome/common/buildflags.h"
#include "chrome/common/plugin.mojom.h"
-#include "chrome/common/prerender_types.h"
#include "chrome/renderer/plugins/power_saver_info.h"
#include "components/plugins/renderer/loadable_plugin_placeholder.h"
+#include "components/prerender/common/prerender_types.mojom.h"
#include "content/public/renderer/context_menu_client.h"
#include "content/public/renderer/render_thread_observer.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
@@ -87,7 +87,7 @@ class ChromePluginPlaceholder final
void UpdateFailure() override;
// IPC message handlers:
- void OnSetPrerenderMode(prerender::PrerenderMode mode,
+ void OnSetPrerenderMode(prerender::mojom::PrerenderMode mode,
const std::string& histogram_prefix);
chrome::mojom::PluginStatus status_;
diff --git a/chromium/chrome/renderer/prerender/prerender_helper.cc b/chromium/chrome/renderer/prerender/prerender_helper.cc
index 2097753f052..92103602000 100644
--- a/chromium/chrome/renderer/prerender/prerender_helper.cc
+++ b/chromium/chrome/renderer/prerender/prerender_helper.cc
@@ -6,8 +6,8 @@
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h"
-#include "chrome/common/prerender_messages.h"
#include "chrome/common/prerender_url_loader_throttle.h"
+#include "components/prerender/common/prerender_messages.h"
#include "content/public/renderer/document_state.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_thread.h"
@@ -19,14 +19,14 @@
namespace prerender {
PrerenderHelper::PrerenderHelper(content::RenderFrame* render_frame,
- PrerenderMode prerender_mode,
+ prerender::mojom::PrerenderMode prerender_mode,
const std::string& histogram_prefix)
: content::RenderFrameObserver(render_frame),
content::RenderFrameObserverTracker<PrerenderHelper>(render_frame),
prerender_mode_(prerender_mode),
histogram_prefix_(histogram_prefix),
start_time_(base::TimeTicks::Now()) {
- DCHECK_NE(prerender_mode_, NO_PRERENDER);
+ DCHECK_NE(prerender_mode_, prerender::mojom::PrerenderMode::kNoPrerender);
}
PrerenderHelper::~PrerenderHelper() = default;
@@ -43,7 +43,7 @@ std::unique_ptr<blink::URLLoaderThrottle> PrerenderHelper::MaybeCreateThrottle(
if (!prerender_helper)
return nullptr;
- mojo::PendingRemote<chrome::mojom::PrerenderCanceler> canceler;
+ mojo::PendingRemote<prerender::mojom::PrerenderCanceler> canceler;
render_frame->GetBrowserInterfaceBroker()->GetInterface(
canceler.InitWithNewPipeAndPassReceiver());
@@ -56,23 +56,26 @@ std::unique_ptr<blink::URLLoaderThrottle> PrerenderHelper::MaybeCreateThrottle(
// static.
bool PrerenderHelper::IsPrerendering(const content::RenderFrame* render_frame) {
- return PrerenderHelper::GetPrerenderMode(render_frame) != NO_PRERENDER;
+ return PrerenderHelper::GetPrerenderMode(render_frame) !=
+ prerender::mojom::PrerenderMode::kNoPrerender;
}
// static.
-PrerenderMode PrerenderHelper::GetPrerenderMode(
+prerender::mojom::PrerenderMode PrerenderHelper::GetPrerenderMode(
const content::RenderFrame* render_frame) {
PrerenderHelper* helper = PrerenderHelper::Get(render_frame);
if (!helper)
- return NO_PRERENDER;
+ return prerender::mojom::PrerenderMode::kNoPrerender;
- DCHECK_NE(helper->prerender_mode_, NO_PRERENDER);
+ DCHECK_NE(helper->prerender_mode_,
+ prerender::mojom::PrerenderMode::kNoPrerender);
return helper->prerender_mode_;
}
void PrerenderHelper::DidFinishDocumentLoad() {
- if (prerender_mode_ != PREFETCH_ONLY)
+ if (prerender_mode_ != prerender::mojom::PrerenderMode::kPrefetchOnly)
return;
+
parsed_time_ = base::TimeTicks::Now();
prefetch_finished_ = true;
if (prefetch_count_ == 0)
@@ -93,11 +96,11 @@ void PrerenderHelper::OnDestruct() {
delete this;
}
-void PrerenderHelper::OnSetIsPrerendering(PrerenderMode mode,
+void PrerenderHelper::OnSetIsPrerendering(prerender::mojom::PrerenderMode mode,
const std::string& histogram_prefix) {
// Immediately after construction, |this| may receive the message that
// triggered its creation. If so, ignore it.
- if (mode != prerender::NO_PRERENDER)
+ if (mode != prerender::mojom::PrerenderMode::kNoPrerender)
return;
std::vector<base::WeakPtr<PrerenderURLLoaderThrottle>> throttles =
@@ -120,7 +123,7 @@ void PrerenderHelper::AddThrottle(
// sending the "prefetch finished" signal until they are destroyed. This is
// important since that signal tells the browser that it can tear down this
// renderer which could interrupt subresource prefetching.
- if (prerender_mode_ == PREFETCH_ONLY) {
+ if (prerender_mode_ == prerender::mojom::PrerenderMode::kPrefetchOnly) {
prefetch_count_++;
throttle->set_destruction_closure(base::BindOnce(
&PrerenderHelper::OnThrottleDestroyed, weak_factory_.GetWeakPtr()));
diff --git a/chromium/chrome/renderer/prerender/prerender_helper.h b/chromium/chrome/renderer/prerender/prerender_helper.h
index 6bd8cbca918..e479e1a82cb 100644
--- a/chromium/chrome/renderer/prerender/prerender_helper.h
+++ b/chromium/chrome/renderer/prerender/prerender_helper.h
@@ -9,7 +9,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
-#include "chrome/common/prerender_types.h"
+#include "components/prerender/common/prerender_types.mojom.h"
#include "content/public/renderer/render_frame_observer.h"
#include "content/public/renderer/render_frame_observer_tracker.h"
@@ -27,7 +27,7 @@ class PrerenderHelper
public content::RenderFrameObserverTracker<PrerenderHelper> {
public:
PrerenderHelper(content::RenderFrame* render_frame,
- PrerenderMode prerender_mode,
+ prerender::mojom::PrerenderMode prerender_mode,
const std::string& histogram_prefix);
~PrerenderHelper() override;
@@ -40,10 +40,12 @@ class PrerenderHelper
// Returns true if |render_frame| is currently prerendering.
static bool IsPrerendering(const content::RenderFrame* render_frame);
- static PrerenderMode GetPrerenderMode(
+ static prerender::mojom::PrerenderMode GetPrerenderMode(
const content::RenderFrame* render_frame);
- PrerenderMode prerender_mode() const { return prerender_mode_; }
+ prerender::mojom::PrerenderMode prerender_mode() const {
+ return prerender_mode_;
+ }
std::string histogram_prefix() const { return histogram_prefix_; }
private:
@@ -52,14 +54,14 @@ class PrerenderHelper
bool OnMessageReceived(const IPC::Message& message) override;
void OnDestruct() override;
- void OnSetIsPrerendering(PrerenderMode mode,
+ void OnSetIsPrerendering(prerender::mojom::PrerenderMode mode,
const std::string& histogram_prefix);
void AddThrottle(const base::WeakPtr<PrerenderURLLoaderThrottle>& throttle);
void OnThrottleDestroyed();
void SendPrefetchFinished();
- PrerenderMode prerender_mode_;
+ prerender::mojom::PrerenderMode prerender_mode_;
std::string histogram_prefix_;
// Pending requests for this frame..
diff --git a/chromium/chrome/renderer/prerender/prerenderer_client.cc b/chromium/chrome/renderer/prerender/prerenderer_client.cc
index c82d6e61174..76c809faacf 100644
--- a/chromium/chrome/renderer/prerender/prerenderer_client.cc
+++ b/chromium/chrome/renderer/prerender/prerenderer_client.cc
@@ -23,7 +23,8 @@ PrerendererClient::~PrerendererClient() = default;
bool PrerendererClient::IsPrefetchOnly() {
return PrerenderHelper::GetPrerenderMode(
- render_view()->GetMainRenderFrame()) == PREFETCH_ONLY;
+ render_view()->GetMainRenderFrame()) ==
+ prerender::mojom::PrerenderMode::kPrefetchOnly;
}
void PrerendererClient::OnDestruct() {
diff --git a/chromium/chrome/renderer/previews/resource_loading_hints_agent.cc b/chromium/chrome/renderer/previews/resource_loading_hints_agent.cc
index 5e0737dc806..154008b2061 100644
--- a/chromium/chrome/renderer/previews/resource_loading_hints_agent.cc
+++ b/chromium/chrome/renderer/previews/resource_loading_hints_agent.cc
@@ -7,6 +7,7 @@
#include <vector>
#include "base/metrics/histogram_macros.h"
+#include "base/metrics/histogram_macros_local.h"
#include "content/public/renderer/render_frame.h"
#include "third_party/blink/public/platform/web_loading_hints_provider.h"
#include "third_party/blink/public/platform/web_string.h"
@@ -38,8 +39,6 @@ ResourceLoadingHintsAgent::ResourceLoadingHintsAgent(
content::RenderFrameObserverTracker<ResourceLoadingHintsAgent>(
render_frame) {
DCHECK(render_frame);
- DCHECK(IsMainFrame());
-
associated_interfaces->AddInterface(base::BindRepeating(
&ResourceLoadingHintsAgent::SetReceiver, base::Unretained(this)));
}
@@ -51,17 +50,23 @@ GURL ResourceLoadingHintsAgent::GetDocumentURL() const {
void ResourceLoadingHintsAgent::DidStartNavigation(
const GURL& url,
base::Optional<blink::WebNavigationType> navigation_type) {
+ if (!IsMainFrame())
+ return;
subresource_redirect_hints_agent_.DidStartNavigation();
}
void ResourceLoadingHintsAgent::ReadyToCommitNavigation(
blink::WebDocumentLoader* document_loader) {
+ if (!IsMainFrame())
+ return;
+
subresource_redirect_hints_agent_.ReadyToCommitNavigation(
render_frame()->GetRoutingID());
}
void ResourceLoadingHintsAgent::DidCreateNewDocument() {
- DCHECK(IsMainFrame());
+ if (!IsMainFrame())
+ return;
if (!GetDocumentURL().SchemeIsHTTPOrHTTPS())
return;
@@ -101,7 +106,8 @@ bool ResourceLoadingHintsAgent::IsMainFrame() const {
void ResourceLoadingHintsAgent::SetResourceLoadingHints(
blink::mojom::PreviewsResourceLoadingHintsPtr resource_loading_hints) {
- DCHECK(IsMainFrame());
+ if (!IsMainFrame())
+ return;
UMA_HISTOGRAM_COUNTS_100(
"ResourceLoadingHints.CountBlockedSubresourcePatterns",
@@ -117,8 +123,37 @@ void ResourceLoadingHintsAgent::SetResourceLoadingHints(
void ResourceLoadingHintsAgent::SetCompressPublicImagesHints(
blink::mojom::CompressPublicImagesHintsPtr images_hints) {
+ if (!IsMainFrame())
+ return;
subresource_redirect_hints_agent_.SetCompressPublicImagesHints(
std::move(images_hints));
}
+void ResourceLoadingHintsAgent::NotifyHttpsImageCompressionFetchFailed(
+ base::TimeDelta retry_after) {
+ if (!subresource_redirect_service_remote_) {
+ render_frame()->GetRemoteAssociatedInterfaces()->GetInterface(
+ &subresource_redirect_service_remote_);
+ }
+ subresource_redirect_service_remote_->NotifyCompressedImageFetchFailed(
+ retry_after);
+}
+
+void ResourceLoadingHintsAgent::SetLiteVideoHint(
+ blink::mojom::LiteVideoHintPtr lite_video_hint) {
+ auto* lite_video_hint_agent =
+ lite_video::LiteVideoHintAgent::Get(render_frame());
+ if (lite_video_hint_agent)
+ lite_video_hint_agent->SetLiteVideoHint(std::move(lite_video_hint));
+}
+
+void ResourceLoadingHintsAgent::StopThrottlingMediaRequests() {
+ auto* lite_video_hint_agent =
+ lite_video::LiteVideoHintAgent::Get(render_frame());
+ if (lite_video_hint_agent) {
+ LOCAL_HISTOGRAM_BOOLEAN("LiteVideo.HintsAgent.StopThrottling", true);
+ lite_video_hint_agent->StopThrottling();
+ }
+}
+
} // namespace previews
diff --git a/chromium/chrome/renderer/previews/resource_loading_hints_agent.h b/chromium/chrome/renderer/previews/resource_loading_hints_agent.h
index 85fdc2b4d88..370b2789d54 100644
--- a/chromium/chrome/renderer/previews/resource_loading_hints_agent.h
+++ b/chromium/chrome/renderer/previews/resource_loading_hints_agent.h
@@ -8,9 +8,10 @@
#include <memory>
#include "base/bind.h"
-#include "base/logging.h"
#include "base/macros.h"
#include "base/optional.h"
+#include "chrome/common/subresource_redirect_service.mojom.h"
+#include "chrome/renderer/lite_video/lite_video_hint_agent.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.h"
#include "content/public/renderer/render_frame_observer.h"
#include "content/public/renderer/render_frame_observer_tracker.h"
@@ -44,6 +45,9 @@ class ResourceLoadingHintsAgent
return subresource_redirect_hints_agent_;
}
+ // Notifies the browser process that https image compression fetch had failed.
+ void NotifyHttpsImageCompressionFetchFailed(base::TimeDelta retry_after);
+
private:
// content::RenderFrameObserver:
void DidStartNavigation(
@@ -61,6 +65,9 @@ class ResourceLoadingHintsAgent
resource_loading_hints) override;
void SetCompressPublicImagesHints(
blink::mojom::CompressPublicImagesHintsPtr images_hints) override;
+ void SetLiteVideoHint(
+ blink::mojom::LiteVideoHintPtr lite_video_hint) override;
+ void StopThrottlingMediaRequests() override;
void SetReceiver(
mojo::PendingAssociatedReceiver<
@@ -74,6 +81,10 @@ class ResourceLoadingHintsAgent
mojo::AssociatedReceiver<blink::mojom::PreviewsResourceLoadingHintsReceiver>
receiver_{this};
+ mojo::AssociatedRemote<
+ subresource_redirect::mojom::SubresourceRedirectService>
+ subresource_redirect_service_remote_;
+
subresource_redirect::SubresourceRedirectHintsAgent
subresource_redirect_hints_agent_;
diff --git a/chromium/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc b/chromium/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc
index 49086491846..8fd541ac8bf 100644
--- a/chromium/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc
+++ b/chromium/chrome/renderer/printing/chrome_print_render_frame_helper_delegate.cc
@@ -43,10 +43,14 @@ blink::WebElement ChromePrintRenderFrameHelperDelegate::GetPdfElement(
url.host_piece() == extension_misc::kPdfExtensionId;
if (inside_print_preview || inside_pdf_extension) {
// <object> with id="plugin" is created in
- // chrome/browser/resources/pdf/pdf_viewer.js.
- auto plugin_element = frame->GetDocument().GetElementById("plugin");
- if (!plugin_element.IsNull()) {
- return plugin_element;
+ // chrome/browser/resources/pdf/pdf_viewer_base.js.
+ auto viewer_element = frame->GetDocument().GetElementById("viewer");
+ if (!viewer_element.IsNull() && !viewer_element.ShadowRoot().IsNull()) {
+ auto plugin_element =
+ viewer_element.ShadowRoot().QuerySelector("#plugin");
+ if (!plugin_element.IsNull()) {
+ return plugin_element;
+ }
}
NOTREACHED();
}
diff --git a/chromium/chrome/renderer/resources/default_100_percent/common/sadplugin.png b/chromium/chrome/renderer/resources/default_100_percent/common/sadplugin.png
deleted file mode 100644
index 9ad1225ac67..00000000000
--- a/chromium/chrome/renderer/resources/default_100_percent/common/sadplugin.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/renderer/resources/default_100_percent/common/webview-crash.png b/chromium/chrome/renderer/resources/default_100_percent/common/webview-crash.png
deleted file mode 100644
index 0ce1db18805..00000000000
--- a/chromium/chrome/renderer/resources/default_100_percent/common/webview-crash.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/renderer/resources/default_200_percent/common/sadplugin.png b/chromium/chrome/renderer/resources/default_200_percent/common/sadplugin.png
deleted file mode 100644
index 78286797176..00000000000
--- a/chromium/chrome/renderer/resources/default_200_percent/common/sadplugin.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/renderer/resources/default_200_percent/common/webview-crash.png b/chromium/chrome/renderer/resources/default_200_percent/common/webview-crash.png
deleted file mode 100644
index eeb34b253a6..00000000000
--- a/chromium/chrome/renderer/resources/default_200_percent/common/webview-crash.png
+++ /dev/null
Binary files differ
diff --git a/chromium/chrome/renderer/resources/extensions/cast_streaming_receiver_session_custom_bindings.js b/chromium/chrome/renderer/resources/extensions/cast_streaming_receiver_session_custom_bindings.js
deleted file mode 100644
index 64c5370d233..00000000000
--- a/chromium/chrome/renderer/resources/extensions/cast_streaming_receiver_session_custom_bindings.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 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.
-
-// Custom binding for the Cast Streaming Session API.
-
-var natives = requireNative('cast_streaming_natives');
-
-apiBridge.registerCustomHook(function(bindingsAPI, extensionId) {
- var apiFunctions = bindingsAPI.apiFunctions;
- apiFunctions.setHandleRequest(
- 'createAndBind',
- function(ap, vp, local, weidgth, height, fr, url, cb, op) {
- });
-});
diff --git a/chromium/chrome/renderer/resources/extensions/cast_streaming_rtp_stream_custom_bindings.js b/chromium/chrome/renderer/resources/extensions/cast_streaming_rtp_stream_custom_bindings.js
deleted file mode 100644
index 8e4f312d147..00000000000
--- a/chromium/chrome/renderer/resources/extensions/cast_streaming_rtp_stream_custom_bindings.js
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2013 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.
-
-// Custom binding for the Cast Streaming RtpStream API.
-
-var natives = requireNative('cast_streaming_natives');
-
-apiBridge.registerCustomHook(function(bindingsAPI, extensionId) {
- var apiFunctions = bindingsAPI.apiFunctions;
-
- apiFunctions.setHandleRequest('destroy',
- function(transportId) {
- natives.DestroyCastRtpStream(transportId);
- });
- apiFunctions.setHandleRequest('getSupportedParams',
- function(transportId) {
- return natives.GetSupportedParamsCastRtpStream(transportId);
- });
- apiFunctions.setHandleRequest('start',
- function(transportId, params) {
- natives.StartCastRtpStream(transportId, params);
- });
- apiFunctions.setHandleRequest('stop',
- function(transportId) {
- natives.StopCastRtpStream(transportId);
- });
- apiFunctions.setHandleRequest('toggleLogging',
- function(transportId, enable) {
- natives.ToggleLogging(transportId, enable);
- });
- apiFunctions.setHandleRequest('getRawEvents',
- function(transportId, extraData, callback) {
- natives.GetRawEvents(transportId, extraData, callback);
- });
- apiFunctions.setHandleRequest('getStats',
- function(transportId, callback) {
- natives.GetStats(transportId, callback);
- });
-});
diff --git a/chromium/chrome/renderer/resources/extensions/cast_streaming_session_custom_bindings.js b/chromium/chrome/renderer/resources/extensions/cast_streaming_session_custom_bindings.js
deleted file mode 100644
index 05afdd6a0d9..00000000000
--- a/chromium/chrome/renderer/resources/extensions/cast_streaming_session_custom_bindings.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2013 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.
-
-// Custom binding for the Cast Streaming Session API.
-
-var natives = requireNative('cast_streaming_natives');
-
-apiBridge.registerCustomHook(function(bindingsAPI, extensionId) {
- var apiFunctions = bindingsAPI.apiFunctions;
- apiFunctions.setHandleRequest('create',
- function(audioTrack, videoTrack, callback) {
- natives.CreateSession(audioTrack, videoTrack, callback);
- });
-});
diff --git a/chromium/chrome/renderer/resources/extensions/cast_streaming_udp_transport_custom_bindings.js b/chromium/chrome/renderer/resources/extensions/cast_streaming_udp_transport_custom_bindings.js
deleted file mode 100644
index c3f64736225..00000000000
--- a/chromium/chrome/renderer/resources/extensions/cast_streaming_udp_transport_custom_bindings.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2013 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.
-
-// Custom binding for the Cast Streaming UdpTransport API.
-
-var natives = requireNative('cast_streaming_natives');
-
-apiBridge.registerCustomHook(function(bindingsAPI, extensionId) {
- var apiFunctions = bindingsAPI.apiFunctions;
-
- apiFunctions.setHandleRequest('destroy', function(transportId) {
- natives.DestroyCastUdpTransport(transportId);
- });
- apiFunctions.setHandleRequest('setDestination',
- function(transportId, destination) {
- natives.SetDestinationCastUdpTransport(transportId, destination);
- });
- apiFunctions.setHandleRequest('setOptions',
- function(transportId, options) {
- natives.SetOptionsCastUdpTransport(transportId, options);
- });
-});
diff --git a/chromium/chrome/renderer/resources/extensions/chromeos_tts_stream_bindings.js b/chromium/chrome/renderer/resources/extensions/chromeos_tts_stream_bindings.js
new file mode 100644
index 00000000000..de636071106
--- /dev/null
+++ b/chromium/chrome/renderer/resources/extensions/chromeos_tts_stream_bindings.js
@@ -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.
+
+'use strict';
+
+if ((typeof mojo === 'undefined') || !mojo.bindingsLibraryInitialized) {
+ loadScript('mojo_bindings');
+}
+mojo.config.autoLoadMojomDeps = false;
+
+loadScript('chromeos.tts.mojom.tts_stream.mojom');
+
+(function() {
+ let ptr = new chromeos.tts.mojom.TtsStreamPtr;
+ Mojo.bindInterface(
+ chromeos.tts.mojom.TtsStream.name, mojo.makeRequest(ptr).handle);
+ exports.$set('returnValue', ptr);
+})();
diff --git a/chromium/chrome/renderer/resources/extensions/media_router_bindings.js b/chromium/chrome/renderer/resources/extensions/media_router_bindings.js
index 6564c71d924..f24fc18793e 100644
--- a/chromium/chrome/renderer/resources/extensions/media_router_bindings.js
+++ b/chromium/chrome/renderer/resources/extensions/media_router_bindings.js
@@ -536,7 +536,7 @@ function routeToMojo_(route) {
'iconUrl': route.iconUrl,
'isLocal': route.isLocal,
'forDisplay': route.forDisplay,
- 'isIncognito': route.offTheRecord,
+ 'isOffTheRecord': route.offTheRecord,
'isLocalPresentation': route.isOffscreenPresentation,
'controllerType': route.controllerType,
'presentationId': route.presentationId,
@@ -973,6 +973,13 @@ MediaRouter.prototype.getMediaSinkServiceStatus = function() {
}
/**
+ * @return {!Promise<!{status: string}>}
+ */
+MediaRouter.prototype.getLogsAsString = function() {
+ return this.service_.getLogsAsString();
+}
+
+/**
* @param {int32} target_tab_id
* @param {!mojo.InterfaceRequest} request
*/
@@ -1186,19 +1193,19 @@ MediaRouteProvider.prototype.stopObservingMediaSinks =
* @param {!number} tabId ID of tab requesting presentation.
* @param {!mojo_base.mojom.TimeDelta} timeout If positive, the timeout
* duration for the request. Otherwise, the default duration will be used.
- * @param {!boolean} incognito If true, the route is being requested by
- * an incognito profile.
+ * @param {!boolean} off_the_record If true, the route is being requested by
+ * an off_the_record profile.
* @return {!Promise.<!Object>} A Promise resolving to an object describing
* the newly created media route, or rejecting with an error message on
* failure.
*/
MediaRouteProvider.prototype.createRoute =
function(sourceUrn, sinkId, presentationId, origin, tabId,
- timeout, incognito) {
+ timeout, off_the_record) {
this.handlers_.onBeforeInvokeHandler();
return this.handlers_.createRoute(
sourceUrn, sinkId, presentationId, origin, tabId,
- Math.floor(timeout.microseconds / 1000), incognito)
+ Math.floor(timeout.microseconds / 1000), off_the_record)
.then(function(route) {
return toSuccessRouteResponse_(route);
},
@@ -1217,19 +1224,19 @@ MediaRouteProvider.prototype.createRoute =
* @param {!number} tabId ID of tab requesting join.
* @param {!mojo_base.mojom.TimeDelta} timeout If positive, the timeout
* duration for the request. Otherwise, the default duration will be used.
- * @param {!boolean} incognito If true, the route is being requested by
- * an incognito profile.
+ * @param {!boolean} off_the_record If true, the route is being requested by
+ * an off_the_record profile.
* @return {!Promise.<!Object>} A Promise resolving to an object describing
* the newly created media route, or rejecting with an error message on
* failure.
*/
MediaRouteProvider.prototype.joinRoute =
function(sourceUrn, presentationId, origin, tabId, timeout,
- incognito) {
+ off_the_record) {
this.handlers_.onBeforeInvokeHandler();
return this.handlers_.joinRoute(
sourceUrn, presentationId, origin, tabId,
- Math.floor(timeout.microseconds / 1000), incognito)
+ Math.floor(timeout.microseconds / 1000), off_the_record)
.then(function(route) {
return toSuccessRouteResponse_(route);
},
@@ -1249,19 +1256,19 @@ MediaRouteProvider.prototype.joinRoute =
* @param {!number} tabId ID of tab requesting join.
* @param {!mojo_base.mojom.TimeDelta} timeout If positive, the timeout
* duration for the request. Otherwise, the default duration will be used.
- * @param {!boolean} incognito If true, the route is being requested by
- * an incognito profile.
+ * @param {!boolean} off_the_record If true, the route is being requested by
+ * an off_the_record profile.
* @return {!Promise.<!Object>} A Promise resolving to an object describing
* the newly created media route, or rejecting with an error message on
* failure.
*/
MediaRouteProvider.prototype.connectRouteByRouteId =
function(sourceUrn, routeId, presentationId, origin, tabId,
- timeout, incognito) {
+ timeout, off_the_record) {
this.handlers_.onBeforeInvokeHandler();
return this.handlers_.connectRouteByRouteId(
sourceUrn, routeId, presentationId, origin, tabId,
- Math.floor(timeout.microseconds / 1000), incognito)
+ Math.floor(timeout.microseconds / 1000), off_the_record)
.then(function(route) {
return toSuccessRouteResponse_(route);
},
diff --git a/chromium/chrome/renderer/resources/extensions/platform_keys/get_public_key.js b/chromium/chrome/renderer/resources/extensions/platform_keys/get_public_key.js
index 5bf7255e88b..d5105f0902f 100644
--- a/chromium/chrome/renderer/resources/extensions/platform_keys/get_public_key.js
+++ b/chromium/chrome/renderer/resources/extensions/platform_keys/get_public_key.js
@@ -10,12 +10,14 @@ var normalizeAlgorithm =
// Returns the normalized parameters of |importParams|.
// Any unknown parameters will be ignored.
function normalizeImportParams(importParams) {
- if (!importParams.name ||
- Object.prototype.toString.call(importParams.name) !== '[object String]') {
+ if (!importParams.name || typeof importParams.name !== 'string') {
throw new Error('Algorithm: name: Missing or not a String');
}
- var filteredParams = { name: importParams.name };
+ var filteredParams = {
+ name: importParams.name,
+ namedCurve: importParams.namedCurve
+ };
var hashIsNone = false;
if (importParams.hash) {
@@ -29,9 +31,13 @@ function normalizeImportParams(importParams) {
}
}
+ if (importParams.name === 'ECDSA' && importParams.namedCurve !== 'P-256') {
+ throw new Error('Only P-256 named curve is supported.');
+ }
+
// Apply WebCrypto's algorithm normalization.
var resultParams = normalizeAlgorithm(filteredParams, 'ImportKey');
- if (!resultParams ) {
+ if (!resultParams) {
throw new Error('A required parameter was missing or out-of-range');
}
if (hashIsNone) {
@@ -47,11 +53,14 @@ function combineAlgorithms(algorithm, importParams) {
algorithm.publicExponent = new Uint8Array(algorithm.publicExponent);
}
- algorithm.hash = importParams.hash;
+ if (importParams.hash) {
+ algorithm.hash = importParams.hash;
+ }
return algorithm;
}
function getPublicKey(cert, importParams, callback) {
+ // TODO(crbug.com/1096486): Check cert type is ArrayBuffer.
importParams = normalizeImportParams(importParams);
internalAPI.getPublicKey(
cert, importParams.name, function(publicKey, algorithm) {
@@ -64,4 +73,21 @@ function getPublicKey(cert, importParams, callback) {
});
}
+function getPublicKeyBySpki(publicKeySpkiDer, importParams, callback) {
+ if (!(publicKeySpkiDer instanceof ArrayBuffer)){
+ throw $Error.self('publicKeySpkiDer: Not an ArrayBuffer');
+ }
+ importParams = normalizeImportParams(importParams);
+ internalAPI.getPublicKeyBySpki(
+ publicKeySpkiDer, importParams.name, function(publicKey, algorithm) {
+ if (bindingUtil.hasLastError()) {
+ callback();
+ return;
+ }
+ var combinedAlgorithm = combineAlgorithms(algorithm, importParams);
+ callback(publicKey, combinedAlgorithm);
+ });
+}
+
exports.$set('getPublicKey', getPublicKey);
+exports.$set('getPublicKeyBySpki', getPublicKeyBySpki);
diff --git a/chromium/chrome/renderer/resources/extensions/platform_keys/internal_api.js b/chromium/chrome/renderer/resources/extensions/platform_keys/internal_api.js
index b3c4c0fef36..324eee7fa77 100644
--- a/chromium/chrome/renderer/resources/extensions/platform_keys/internal_api.js
+++ b/chromium/chrome/renderer/resources/extensions/platform_keys/internal_api.js
@@ -2,8 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// TODO(crbug.com/1096029): Make consumers use the API directly by calling
+// getInternalApi themselves.
var binding = getInternalApi('platformKeysInternal');
exports.$set('selectClientCertificates', binding.selectClientCertificates);
exports.$set('sign', binding.sign);
exports.$set('getPublicKey', binding.getPublicKey);
+exports.$set('getPublicKeyBySpki', binding.getPublicKeyBySpki);
diff --git a/chromium/chrome/renderer/resources/extensions/platform_keys_custom_bindings.js b/chromium/chrome/renderer/resources/extensions/platform_keys_custom_bindings.js
index 70faf9bd0a8..147269975db 100644
--- a/chromium/chrome/renderer/resources/extensions/platform_keys_custom_bindings.js
+++ b/chromium/chrome/renderer/resources/extensions/platform_keys_custom_bindings.js
@@ -5,7 +5,9 @@
// Custom binding for the platformKeys API.
var SubtleCrypto = require('platformKeys.SubtleCrypto').SubtleCrypto;
-var getPublicKey = require('platformKeys.getPublicKey').getPublicKey;
+var publicKeyUtil = require('platformKeys.getPublicKeyUtil');
+var getPublicKey = publicKeyUtil.getPublicKey;
+var getPublicKeyBySpki = publicKeyUtil.getPublicKeyBySpki;
var internalAPI = require('platformKeys.internalAPI');
var keyModule = require('platformKeys.Key');
@@ -60,4 +62,18 @@ apiBridge.registerCustomHook(function(api) {
createPrivateKey(publicKey, algorithm));
});
});
+
+ apiFunctions.setHandleRequest(
+ 'getKeyPairBySpki', function(publicKeySpkiDer, params, callback) {
+ getPublicKeyBySpki(
+ publicKeySpkiDer, params, function(publicKey, algorithm) {
+ if (bindingUtil.hasLastError()) {
+ callback();
+ return;
+ }
+ callback(
+ createPublicKey(publicKey, algorithm),
+ createPrivateKey(publicKey, algorithm));
+ });
+ });
});
diff --git a/chromium/chrome/renderer/resources/renderer_resources.grd b/chromium/chrome/renderer/resources/renderer_resources.grd
index 3f31e156ca7..076fd011a55 100644
--- a/chromium/chrome/renderer/resources/renderer_resources.grd
+++ b/chromium/chrome/renderer/resources/renderer_resources.grd
@@ -9,10 +9,6 @@
<output filename="renderer_resources_300_percent.pak" type="data_package" context="default_300_percent" />
</outputs>
<release seq="1">
- <structures fallback_to_low_resolution="true">
- <structure type="chrome_scaled_image" name="IDR_SAD_WEBVIEW" file="common\webview-crash.png" />
- <structure type="chrome_scaled_image" name="IDR_SAD_PLUGIN" file="common\sadplugin.png" />
- </structures>
<includes>
<include name="IDR_BLOCKED_PLUGIN_HTML" file="plugins/blocked_plugin.html" flattenhtml="true" type="BINDATA" />
<include name="IDR_DISABLED_PLUGIN_HTML" file="plugins/disabled_plugin.html" flattenhtml="true" type="BINDATA" />
@@ -25,10 +21,6 @@
<!-- Custom bindings for extension APIs. -->
<include name="IDR_ACTION_CUSTOM_BINDINGS_JS" file="extensions\action_custom_bindings.js" type="BINDATA" />
<include name="IDR_BROWSER_ACTION_CUSTOM_BINDINGS_JS" file="extensions\browser_action_custom_bindings.js" type="BINDATA" />
- <include name="IDR_CAST_STREAMING_RTP_STREAM_CUSTOM_BINDINGS_JS" file="extensions\cast_streaming_rtp_stream_custom_bindings.js" type="BINDATA" />
- <include name="IDR_CAST_STREAMING_SESSION_CUSTOM_BINDINGS_JS" file="extensions\cast_streaming_session_custom_bindings.js" type="BINDATA" />
- <include name="IDR_CAST_STREAMING_UDP_TRANSPORT_CUSTOM_BINDINGS_JS" file="extensions\cast_streaming_udp_transport_custom_bindings.js" type="BINDATA" />
- <include name="IDR_CAST_STREAMING_RECEIVER_SESSION_CUSTOM_BINDINGS_JS" file="extensions\cast_streaming_receiver_session_custom_bindings.js" type="BINDATA" />
<include name="IDR_CHROME_WEB_VIEW_INTERNAL_CUSTOM_BINDINGS_JS" file="extensions\web_view\chrome_web_view_internal_custom_bindings.js" type="BINDATA" />
<include name="IDR_CHROME_WEB_VIEW_JS" file="extensions\web_view\chrome_web_view.js" type="BINDATA" />
<include name="IDR_DECLARATIVE_CONTENT_CUSTOM_BINDINGS_JS" file="extensions\declarative_content_custom_bindings.js" type="BINDATA" />
@@ -72,6 +64,9 @@
<!-- ChromeOS IME Mojo service and bindings. -->
<include name="IDR_IME_SERVICE_BINDINGS_JS" file="extensions\chromeos_ime_service_bindings.js" type="BINDATA" />
<include name="IDR_IME_SERVICE_MOJOM_JS" file="${mojom_root}\chromeos/services/ime/public/mojom/input_engine.mojom.js" use_base_dir="false" type="BINDATA" />
+
+ <include name="IDR_TTS_STREAM_BINDINGS_JS" file="extensions\chromeos_tts_stream_bindings.js" type="BINDATA" />
+ <include name="IDR_TTS_STREAM_MOJOM_JS" file="${mojom_root}\chromeos/services/tts/public/mojom/tts_service.mojom.js" use_base_dir="false" type="BINDATA" />
</if>
<!-- Media Router Mojo service and bindings. -->
<include name="IDR_MEDIA_CONTROLLER_MOJOM_JS" file="${mojom_root}\chrome\common\media_router\mojom\media_controller.mojom.js" use_base_dir="false" type="BINDATA" />
diff --git a/chromium/chrome/renderer/safe_browsing/DEPS b/chromium/chrome/renderer/safe_browsing/DEPS
index 76dae5d8e5a..6b8537549c7 100644
--- a/chromium/chrome/renderer/safe_browsing/DEPS
+++ b/chromium/chrome/renderer/safe_browsing/DEPS
@@ -1,9 +1,12 @@
include_rules = [
+ "+components/paint_preview/common",
"+components/safe_browsing/content/renderer",
+ "+components/safe_browsing/content/password_protection/visual_utils.h",
"+components/safe_browsing/core/common",
"+components/safe_browsing/core/proto/csd.pb.h",
"+components/safe_browsing/core/proto/client_model.pb.h",
"+components/safe_browsing/core/features.h",
+ "+cc/paint",
"+third_party/smhasher",
]
diff --git a/chromium/chrome/renderer/safe_browsing/feature_extractor_clock.cc b/chromium/chrome/renderer/safe_browsing/feature_extractor_clock.cc
deleted file mode 100644
index 45fbd4d4437..00000000000
--- a/chromium/chrome/renderer/safe_browsing/feature_extractor_clock.cc
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2010 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 "chrome/renderer/safe_browsing/feature_extractor_clock.h"
-
-namespace safe_browsing {
-
-FeatureExtractorClock::~FeatureExtractorClock() {}
-
-base::TimeTicks FeatureExtractorClock::Now() {
- return base::TimeTicks::Now();
-}
-
-} // namespace safe_browsing
diff --git a/chromium/chrome/renderer/safe_browsing/feature_extractor_clock.h b/chromium/chrome/renderer/safe_browsing/feature_extractor_clock.h
deleted file mode 100644
index 930c1a4b7ab..00000000000
--- a/chromium/chrome/renderer/safe_browsing/feature_extractor_clock.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2010 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.
-//
-// A simple abstraction for getting the current time during feature extraction.
-// This can be mocked out for testing.
-
-#ifndef CHROME_RENDERER_SAFE_BROWSING_FEATURE_EXTRACTOR_CLOCK_H_
-#define CHROME_RENDERER_SAFE_BROWSING_FEATURE_EXTRACTOR_CLOCK_H_
-
-#include "base/macros.h"
-#include "base/time/time.h"
-
-namespace safe_browsing {
-
-class FeatureExtractorClock {
- public:
- FeatureExtractorClock() {}
- virtual ~FeatureExtractorClock();
-
- // Returns the current time. May be mocked for testing.
- virtual base::TimeTicks Now();
-
- private:
- DISALLOW_COPY_AND_ASSIGN(FeatureExtractorClock);
-};
-
-} // namespace safe_browsing
-
-#endif // CHROME_RENDERER_SAFE_BROWSING_FEATURE_EXTRACTOR_CLOCK_H_
diff --git a/chromium/chrome/renderer/safe_browsing/mock_feature_extractor_clock.cc b/chromium/chrome/renderer/safe_browsing/mock_feature_extractor_clock.cc
deleted file mode 100644
index 665baf0b5c3..00000000000
--- a/chromium/chrome/renderer/safe_browsing/mock_feature_extractor_clock.cc
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2011 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 "chrome/renderer/safe_browsing/mock_feature_extractor_clock.h"
-
-namespace safe_browsing {
-
-MockFeatureExtractorClock::MockFeatureExtractorClock()
- : FeatureExtractorClock() {}
-
-MockFeatureExtractorClock::~MockFeatureExtractorClock() {}
-
-} // namespace safe_browsing
diff --git a/chromium/chrome/renderer/safe_browsing/mock_feature_extractor_clock.h b/chromium/chrome/renderer/safe_browsing/mock_feature_extractor_clock.h
deleted file mode 100644
index 7012ee81090..00000000000
--- a/chromium/chrome/renderer/safe_browsing/mock_feature_extractor_clock.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2010 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.
-//
-// A mock implementation of FeatureExtractorClock for testing.
-
-#ifndef CHROME_RENDERER_SAFE_BROWSING_MOCK_FEATURE_EXTRACTOR_CLOCK_H_
-#define CHROME_RENDERER_SAFE_BROWSING_MOCK_FEATURE_EXTRACTOR_CLOCK_H_
-
-#include "base/macros.h"
-#include "chrome/renderer/safe_browsing/feature_extractor_clock.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-namespace safe_browsing {
-
-class MockFeatureExtractorClock : public FeatureExtractorClock {
- public:
- MockFeatureExtractorClock();
- ~MockFeatureExtractorClock() override;
-
- MOCK_METHOD0(Now, base::TimeTicks());
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockFeatureExtractorClock);
-};
-
-} // namespace safe_browsing
-
-#endif // CHROME_RENDERER_SAFE_BROWSING_MOCK_FEATURE_EXTRACTOR_CLOCK_H_
diff --git a/chromium/chrome/renderer/safe_browsing/phishing_classifier.cc b/chromium/chrome/renderer/safe_browsing/phishing_classifier.cc
index 0842c7ea50a..c53c18d31b5 100644
--- a/chromium/chrome/renderer/safe_browsing/phishing_classifier.cc
+++ b/chromium/chrome/renderer/safe_browsing/phishing_classifier.cc
@@ -11,18 +11,18 @@
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/location.h"
-#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "cc/paint/skia_paint_canvas.h"
#include "chrome/common/url_constants.h"
-#include "chrome/renderer/safe_browsing/feature_extractor_clock.h"
#include "chrome/renderer/safe_browsing/features.h"
#include "chrome/renderer/safe_browsing/phishing_dom_feature_extractor.h"
#include "chrome/renderer/safe_browsing/phishing_term_feature_extractor.h"
#include "chrome/renderer/safe_browsing/phishing_url_feature_extractor.h"
#include "chrome/renderer/safe_browsing/scorer.h"
+#include "components/paint_preview/common/paint_preview_tracker.h"
#include "components/safe_browsing/core/proto/csd.pb.h"
#include "content/public/renderer/render_frame.h"
#include "crypto/sha2.h"
@@ -32,6 +32,7 @@
#include "third_party/blink/public/web/web_document_loader.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/public/web/web_view.h"
+#include "ui/gfx/geometry/rect_conversions.h"
#include "url/gurl.h"
namespace safe_browsing {
@@ -39,32 +40,29 @@ namespace safe_browsing {
const float PhishingClassifier::kInvalidScore = -1.0;
const float PhishingClassifier::kPhishyThreshold = 0.5;
-PhishingClassifier::PhishingClassifier(content::RenderFrame* render_frame,
- FeatureExtractorClock* clock)
- : render_frame_(render_frame), scorer_(nullptr), clock_(clock) {
+PhishingClassifier::PhishingClassifier(content::RenderFrame* render_frame)
+ : render_frame_(render_frame), scorer_(nullptr) {
Clear();
}
PhishingClassifier::~PhishingClassifier() {
// The RenderView should have called CancelPendingClassification() before
// we are destroyed.
- CheckNoPendingClassification();
+ DCHECK(done_callback_.is_null());
+ DCHECK(!page_text_);
}
void PhishingClassifier::set_phishing_scorer(const Scorer* scorer) {
- CheckNoPendingClassification();
+ DCHECK(done_callback_.is_null());
+ DCHECK(!page_text_);
scorer_ = scorer;
if (scorer_) {
- url_extractor_.reset(new PhishingUrlFeatureExtractor);
- dom_extractor_.reset(new PhishingDOMFeatureExtractor(clock_.get()));
- term_extractor_.reset(new PhishingTermFeatureExtractor(
- &scorer_->page_terms(),
- &scorer_->page_words(),
- scorer_->max_words_per_term(),
- scorer_->murmurhash3_seed(),
- scorer_->max_shingles_per_page(),
- scorer_->shingle_size(),
- clock_.get()));
+ url_extractor_ = std::make_unique<PhishingUrlFeatureExtractor>();
+ dom_extractor_ = std::make_unique<PhishingDOMFeatureExtractor>();
+ term_extractor_ = std::make_unique<PhishingTermFeatureExtractor>(
+ &scorer_->page_terms(), &scorer_->page_words(),
+ scorer_->max_words_per_term(), scorer_->murmurhash3_seed(),
+ scorer_->max_shingles_per_page(), scorer_->shingle_size());
} else {
// We're disabling client-side phishing detection, so tear down all
// of the relevant objects.
@@ -75,7 +73,7 @@ void PhishingClassifier::set_phishing_scorer(const Scorer* scorer) {
}
bool PhishingClassifier::is_ready() const {
- return scorer_ != NULL;
+ return !!scorer_;
}
void PhishingClassifier::BeginClassification(const base::string16* page_text,
@@ -84,7 +82,8 @@ void PhishingClassifier::BeginClassification(const base::string16* page_text,
// The RenderView should have called CancelPendingClassification() before
// starting a new classification, so DCHECK this.
- CheckNoPendingClassification();
+ DCHECK(done_callback_.is_null());
+ DCHECK(!page_text_);
// However, in an opt build, we will go ahead and clean up the pending
// classification so that we can start in a known state.
CancelPendingClassification();
@@ -158,41 +157,70 @@ void PhishingClassifier::DOMExtractionFinished(bool success) {
void PhishingClassifier::TermExtractionFinished(bool success) {
if (success) {
- blink::WebLocalFrame* main_frame = render_frame_->GetWebFrame();
-
- // Hash all of the features so that they match the model, then compute
- // the score.
- FeatureMap hashed_features;
- ClientPhishingRequest verdict;
- verdict.set_model_version(scorer_->model_version());
- verdict.set_url(main_frame->GetDocument().Url().GetString().Utf8());
- for (const auto& it : features_->features()) {
- bool result = hashed_features.AddRealFeature(
- crypto::SHA256HashString(it.first), it.second);
- DCHECK(result);
- ClientPhishingRequest::Feature* feature = verdict.add_feature_map();
- feature->set_name(it.first);
- feature->set_value(it.second);
- }
- for (const auto& it : *shingle_hashes_) {
- verdict.add_shingle_hashes(it);
- }
- float score = static_cast<float>(scorer_->ComputeScore(hashed_features));
- verdict.set_client_score(score);
- verdict.set_is_phishing(score >= scorer_->threshold_probability());
- RunCallback(verdict);
+ ExtractVisualFeatures();
} else {
RunFailureCallback();
}
}
-void PhishingClassifier::CheckNoPendingClassification() {
- DCHECK(done_callback_.is_null());
- DCHECK(!page_text_);
- if (!done_callback_.is_null() || page_text_) {
- LOG(ERROR) << "Classification in progress, missing call to "
- << "CancelPendingClassification";
+void PhishingClassifier::ExtractVisualFeatures() {
+ blink::WebLocalFrame* frame = render_frame_->GetWebFrame();
+ gfx::SizeF viewport_size = frame->View()->VisualViewportSize();
+ gfx::Rect bounds = ToEnclosingRect(gfx::RectF(viewport_size));
+ bitmap_ = std::make_unique<SkBitmap>();
+ // Use the Rec. 2020 color space, in case the user input is wide-gamut.
+ sk_sp<SkColorSpace> rec2020 = SkColorSpace::MakeRGB(
+ {2.22222f, 0.909672f, 0.0903276f, 0.222222f, 0.0812429f, 0, 0},
+ SkNamedGamut::kRec2020);
+ SkImageInfo bitmap_info = SkImageInfo::Make(
+ bounds.width(), bounds.height(), SkColorType::kRGBA_8888_SkColorType,
+ SkAlphaType::kUnpremul_SkAlphaType, rec2020);
+ if (!bitmap_->tryAllocPixels(bitmap_info))
+ return VisualExtractionFinished(/*success=*/false);
+ SkCanvas sk_canvas(*bitmap_);
+ cc::SkiaPaintCanvas cc_canvas(&sk_canvas);
+ auto tracker = std::make_unique<paint_preview::PaintPreviewTracker>(
+ base::UnguessableToken::Create(), frame->GetEmbeddingToken(),
+ /*is_main_frame=*/true);
+ cc_canvas.SetPaintPreviewTracker(tracker.get());
+ VisualExtractionFinished(frame->CapturePaintPreview(
+ bounds, &cc_canvas, /*include_linked_destinations=*/false));
+}
+
+void PhishingClassifier::VisualExtractionFinished(bool success) {
+ if (!success) {
+ RunFailureCallback();
+ return;
+ }
+
+ blink::WebLocalFrame* main_frame = render_frame_->GetWebFrame();
+
+ // Hash all of the features so that they match the model, then compute
+ // the score.
+ FeatureMap hashed_features;
+ ClientPhishingRequest verdict;
+ verdict.set_model_version(scorer_->model_version());
+ verdict.set_url(main_frame->GetDocument().Url().GetString().Utf8());
+ for (const auto& it : features_->features()) {
+ bool result = hashed_features.AddRealFeature(
+ crypto::SHA256HashString(it.first), it.second);
+ DCHECK(result);
+ ClientPhishingRequest::Feature* feature = verdict.add_feature_map();
+ feature->set_name(it.first);
+ feature->set_value(it.second);
}
+ for (const auto& it : *shingle_hashes_) {
+ verdict.add_shingle_hashes(it);
+ }
+ float score = static_cast<float>(scorer_->ComputeScore(hashed_features));
+ verdict.set_client_score(score);
+ verdict.set_is_phishing(score >= scorer_->threshold_probability());
+
+ if (scorer_->GetMatchingVisualTargets(*bitmap_, &verdict)) {
+ verdict.set_is_phishing(true);
+ }
+
+ RunCallback(verdict);
}
void PhishingClassifier::RunCallback(const ClientPhishingRequest& verdict) {
@@ -211,10 +239,11 @@ void PhishingClassifier::RunFailureCallback() {
}
void PhishingClassifier::Clear() {
- page_text_ = NULL;
+ page_text_ = nullptr;
done_callback_.Reset();
- features_.reset(NULL);
- shingle_hashes_.reset(NULL);
+ features_.reset(nullptr);
+ shingle_hashes_.reset(nullptr);
+ bitmap_.reset(nullptr);
}
} // namespace safe_browsing
diff --git a/chromium/chrome/renderer/safe_browsing/phishing_classifier.h b/chromium/chrome/renderer/safe_browsing/phishing_classifier.h
index 9528c434cce..401ae402dba 100644
--- a/chromium/chrome/renderer/safe_browsing/phishing_classifier.h
+++ b/chromium/chrome/renderer/safe_browsing/phishing_classifier.h
@@ -27,6 +27,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
+#include "third_party/skia/include/core/SkBitmap.h"
namespace content {
class RenderFrame;
@@ -34,7 +35,6 @@ class RenderFrame;
namespace safe_browsing {
class ClientPhishingRequest;
-class FeatureExtractorClock;
class FeatureMap;
class PhishingDOMFeatureExtractor;
class PhishingTermFeatureExtractor;
@@ -55,11 +55,9 @@ class PhishingClassifier {
static const float kInvalidScore;
// Creates a new PhishingClassifier object that will operate on
- // |render_view|. |clock| is used to time feature extractor operations, and
- // the PhishingClassifier takes ownership of this object. Note that the
- // classifier will not be 'ready' until set_phishing_scorer() is called.
- PhishingClassifier(content::RenderFrame* render_frame,
- FeatureExtractorClock* clock);
+ // |render_view|. Note that the classifier will not be 'ready' until
+ // set_phishing_scorer() is called.
+ explicit PhishingClassifier(content::RenderFrame* render_frame);
virtual ~PhishingClassifier();
// Sets a scorer for the classifier to use in computing the phishiness score.
@@ -110,15 +108,18 @@ class PhishingClassifier {
void DOMExtractionFinished(bool success);
// Callback to be run when term feature extraction is complete.
+ // If it was successful, begins visual feature extraction, otherwise runs the
+ // DoneCallback with a non-phishy verdict.
+ void TermExtractionFinished(bool success);
+
+ // Called to extract the visual features of the current page.
+ void ExtractVisualFeatures();
+
+ // Callback when visual feature extraction is complete.
// If it was successful, computes a score and runs the DoneCallback.
// If extraction was unsuccessful, runs the DoneCallback with a
// non-phishy verdict.
- void TermExtractionFinished(bool success);
-
- // Helper to verify that there is no pending phishing classification. Dies
- // in debug builds if the state is not as expected. This is a no-op in
- // release builds.
- void CheckNoPendingClassification();
+ void VisualExtractionFinished(bool success);
// Helper method to run the DoneCallback and clear the state.
void RunCallback(const ClientPhishingRequest& verdict);
@@ -132,7 +133,6 @@ class PhishingClassifier {
content::RenderFrame* render_frame_; // owns us
const Scorer* scorer_; // owned by the caller
- std::unique_ptr<FeatureExtractorClock> clock_;
std::unique_ptr<PhishingUrlFeatureExtractor> url_extractor_;
std::unique_ptr<PhishingDOMFeatureExtractor> dom_extractor_;
std::unique_ptr<PhishingTermFeatureExtractor> term_extractor_;
@@ -141,6 +141,7 @@ class PhishingClassifier {
std::unique_ptr<FeatureMap> features_;
std::unique_ptr<std::set<uint32_t>> shingle_hashes_;
const base::string16* page_text_; // owned by the caller
+ std::unique_ptr<SkBitmap> bitmap_;
DoneCallback done_callback_;
// Used in scheduling BeginFeatureExtraction tasks.
diff --git a/chromium/chrome/renderer/safe_browsing/phishing_classifier_browsertest.cc b/chromium/chrome/renderer/safe_browsing/phishing_classifier_browsertest.cc
index 2600269b203..484958e30db 100644
--- a/chromium/chrome/renderer/safe_browsing/phishing_classifier_browsertest.cc
+++ b/chromium/chrome/renderer/safe_browsing/phishing_classifier_browsertest.cc
@@ -12,9 +12,9 @@
#include "base/run_loop.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/test/test_discardable_memory_allocator.h"
#include "chrome/renderer/chrome_content_renderer_client.h"
#include "chrome/renderer/safe_browsing/features.h"
-#include "chrome/renderer/safe_browsing/mock_feature_extractor_clock.h"
#include "chrome/renderer/safe_browsing/murmurhash3_util.h"
#include "chrome/renderer/safe_browsing/scorer.h"
#include "chrome/test/base/chrome_render_view_test.h"
@@ -60,6 +60,8 @@ class PhishingClassifierTest : public ChromeRenderViewTest {
ChromeRenderViewTest::SetUp();
PrepareModel();
SetUpClassifier();
+
+ base::DiscardableMemoryAllocator::SetInstance(&test_allocator_);
}
void PrepareModel() {
@@ -99,18 +101,16 @@ class PhishingClassifierTest : public ChromeRenderViewTest {
model.set_max_shingles_per_page(100);
model.set_shingle_size(3);
- clock_ = new MockFeatureExtractorClock;
+ // Add an empty visual target to ensure visual detection runs.
+ model.mutable_vision_model()->add_targets();
+
scorer_.reset(Scorer::Create(model.SerializeAsString()));
ASSERT_TRUE(scorer_.get());
-
- // These tests don't exercise the extraction timing.
- EXPECT_CALL(*clock_, Now())
- .WillRepeatedly(::testing::Return(base::TimeTicks::Now()));
}
void SetUpClassifier() {
- classifier_.reset(
- new PhishingClassifier(view_->GetMainRenderFrame(), clock_));
+ classifier_ =
+ std::make_unique<PhishingClassifier>(view_->GetMainRenderFrame());
// No scorer yet, so the classifier is not ready.
ASSERT_FALSE(classifier_->is_ready());
@@ -138,6 +138,8 @@ class PhishingClassifierTest : public ChromeRenderViewTest {
verdict.feature_map(i).value());
}
is_phishing_ = verdict.is_phishing();
+ screenshot_phash_ = verdict.screenshot_phash();
+ phash_dimension_size_ = verdict.phash_dimension_size();
}
void LoadHtml(const GURL& url, const std::string& content) {
@@ -153,7 +155,6 @@ class PhishingClassifierTest : public ChromeRenderViewTest {
std::string response_content_;
std::unique_ptr<Scorer> scorer_;
std::unique_ptr<PhishingClassifier> classifier_;
- MockFeatureExtractorClock* clock_; // Owned by classifier_.
// Features that are in the model.
const std::string url_tld_token_net_;
@@ -165,6 +166,11 @@ class PhishingClassifierTest : public ChromeRenderViewTest {
FeatureMap feature_map_;
float phishy_score_;
bool is_phishing_;
+ std::string screenshot_phash_;
+ int phash_dimension_size_;
+
+ // A DiscardableMemoryAllocator is needed for certain Skia operations.
+ base::TestDiscardableMemoryAllocator test_allocator_;
};
TEST_F(PhishingClassifierTest, TestClassificationOfPhishingDotComHttp) {
@@ -261,6 +267,15 @@ TEST_F(PhishingClassifierTest, DisableDetection) {
EXPECT_FALSE(classifier_->is_ready());
}
+TEST_F(PhishingClassifierTest, TestSendsVisualHash) {
+ LoadHtml(GURL("https://host.net"),
+ "<html><body><a href=\"http://safe.com/\">login</a></body></html>");
+ RunPhishingClassifier(&page_text_);
+
+ EXPECT_EQ(phash_dimension_size_, 48);
+ EXPECT_FALSE(screenshot_phash_.empty());
+}
+
// TODO(jialiul): Add test to verify that classification only starts on GET
// method. It seems there is no easy way to simulate a HTTP POST in
// ChromeRenderViewTest.
diff --git a/chromium/chrome/renderer/safe_browsing/phishing_classifier_delegate.cc b/chromium/chrome/renderer/safe_browsing/phishing_classifier_delegate.cc
index 0afae4ea172..b65c048fd82 100644
--- a/chromium/chrome/renderer/safe_browsing/phishing_classifier_delegate.cc
+++ b/chromium/chrome/renderer/safe_browsing/phishing_classifier_delegate.cc
@@ -12,10 +12,8 @@
#include "base/callback.h"
#include "base/debug/stack_trace.h"
#include "base/lazy_instance.h"
-#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
-#include "chrome/renderer/safe_browsing/feature_extractor_clock.h"
#include "chrome/renderer/safe_browsing/phishing_classifier.h"
#include "chrome/renderer/safe_browsing/scorer.h"
#include "components/safe_browsing/content/common/safe_browsing.mojom-forward.h"
@@ -54,42 +52,6 @@ base::LazyInstance<std::unique_ptr<const safe_browsing::Scorer>>::
} // namespace
-// static
-void PhishingClassifierFilter::Create(
- mojo::PendingReceiver<mojom::PhishingModelSetter> receiver) {
- mojo::MakeSelfOwnedReceiver(std::make_unique<PhishingClassifierFilter>(),
- std::move(receiver));
-}
-
-PhishingClassifierFilter::PhishingClassifierFilter() {}
-
-PhishingClassifierFilter::~PhishingClassifierFilter() {}
-
-void PhishingClassifierFilter::SetPhishingModel(const std::string& model) {
- safe_browsing::Scorer* scorer = NULL;
- // An empty model string means we should disable client-side phishing
- // detection.
- if (!model.empty()) {
- scorer = safe_browsing::Scorer::Create(model);
- if (!scorer) {
- DLOG(ERROR) << "Unable to create a PhishingScorer - corrupt model?";
- return;
- }
- }
- for (auto* delegate : PhishingClassifierDelegates())
- delegate->SetPhishingScorer(scorer);
- g_phishing_scorer.Get().reset(scorer);
-}
-
-// static
-PhishingClassifierDelegate* PhishingClassifierDelegate::Create(
- content::RenderFrame* render_frame,
- PhishingClassifier* classifier) {
- // Private constructor and public static Create() method to facilitate
- // stubbing out this class for binary-size reduction purposes.
- return new PhishingClassifierDelegate(render_frame, classifier);
-}
-
PhishingClassifierDelegate::PhishingClassifierDelegate(
content::RenderFrame* render_frame,
PhishingClassifier* classifier)
@@ -99,8 +61,7 @@ PhishingClassifierDelegate::PhishingClassifierDelegate(
is_classifying_(false) {
PhishingClassifierDelegates().insert(this);
if (!classifier) {
- classifier =
- new PhishingClassifier(render_frame, new FeatureExtractorClock());
+ classifier = new PhishingClassifier(render_frame);
}
classifier_.reset(classifier);
@@ -118,6 +79,29 @@ PhishingClassifierDelegate::~PhishingClassifierDelegate() {
PhishingClassifierDelegates().erase(this);
}
+void PhishingClassifierDelegate::SetPhishingModel(const std::string& model) {
+ safe_browsing::Scorer* scorer = nullptr;
+ // An empty model string means we should disable client-side phishing
+ // detection.
+ if (!model.empty()) {
+ scorer = safe_browsing::Scorer::Create(model);
+ if (!scorer)
+ return;
+ }
+ for (auto* delegate : PhishingClassifierDelegates())
+ delegate->SetPhishingScorer(scorer);
+ g_phishing_scorer.Get().reset(scorer);
+}
+
+// static
+PhishingClassifierDelegate* PhishingClassifierDelegate::Create(
+ content::RenderFrame* render_frame,
+ PhishingClassifier* classifier) {
+ // Private constructor and public static Create() method to facilitate
+ // stubbing out this class for binary-size reduction purposes.
+ return new PhishingClassifierDelegate(render_frame, classifier);
+}
+
void PhishingClassifierDelegate::SetPhishingScorer(
const safe_browsing::Scorer* scorer) {
if (is_classifying_) {
@@ -159,23 +143,22 @@ void PhishingClassifierDelegate::StartPhishingDetection(
}
void PhishingClassifierDelegate::DidCommitProvisionalLoad(
- bool is_same_document_navigation,
ui::PageTransition transition) {
blink::WebLocalFrame* frame = render_frame()->GetWebFrame();
// A new page is starting to load, so cancel classificaiton.
- //
+ CancelPendingClassification(NAVIGATE_AWAY);
+ if (!frame->Parent())
+ last_main_frame_transition_ = transition;
+}
+
+void PhishingClassifierDelegate::DidFinishSameDocumentNavigation() {
// TODO(bryner): We shouldn't need to cancel classification if the navigation
// is within the same document. However, if we let classification continue in
// this case, we need to properly deal with the fact that PageCaptured will
// be called again for the same-document navigation. We need to be sure not
// to swap out the page text while the term feature extractor is still
// running.
- CancelPendingClassification(is_same_document_navigation ? NAVIGATE_WITHIN_PAGE
- : NAVIGATE_AWAY);
- if (frame->Parent())
- return;
-
- last_main_frame_transition_ = transition;
+ CancelPendingClassification(NAVIGATE_WITHIN_PAGE);
}
void PhishingClassifierDelegate::PageCaptured(base::string16* page_text,
@@ -196,8 +179,8 @@ void PhishingClassifierDelegate::PageCaptured(base::string16* page_text,
have_page_text_ = true;
GURL stripped_last_load_url(StripRef(last_finished_load_url_));
+ // Check if toplevel URL has changed.
if (stripped_last_load_url == StripRef(last_url_sent_to_classifier_)) {
- DVLOG(2) << "Toplevel URL is unchanged, not starting classification.";
return;
}
@@ -225,8 +208,6 @@ void PhishingClassifierDelegate::CancelPendingClassification(
void PhishingClassifierDelegate::ClassificationDone(
const ClientPhishingRequest& verdict) {
- DVLOG(2) << "Phishy verdict = " << verdict.is_phishing()
- << " score = " << verdict.client_score();
is_phishing_detection_running_ = false;
if (callback_.is_null())
return;
@@ -255,7 +236,6 @@ void PhishingClassifierDelegate::MaybeStartClassification() {
// classified at all (as opposed to deferring it until we get an IPC or
// the load completes), we discard the page text since it won't be needed.
if (!classifier_->is_ready()) {
- DVLOG(2) << "Not starting classification, no Scorer created.";
is_phishing_detection_running_ = false;
// Keep classifier_page_text_, in case a Scorer is set later.
if (!callback_.is_null())
@@ -268,7 +248,6 @@ void PhishingClassifierDelegate::MaybeStartClassification() {
// Skip loads from session history navigation. However, update the
// last URL sent to the classifier, so that we'll properly detect
// same-document navigations.
- DVLOG(2) << "Not starting classification for back/forward navigation";
last_url_sent_to_classifier_ = last_finished_load_url_;
classifier_page_text_.clear(); // we won't need this.
have_page_text_ = false;
@@ -281,7 +260,6 @@ void PhishingClassifierDelegate::MaybeStartClassification() {
GURL stripped_last_load_url(StripRef(last_finished_load_url_));
if (!have_page_text_) {
- DVLOG(2) << "Not starting classification, there is no page text ready.";
RecordEvent(SBPhishingClassifierEvent::kPageTextNotLoaded);
return;
}
@@ -292,15 +270,11 @@ void PhishingClassifierDelegate::MaybeStartClassification() {
// so defer classification for now. Note: the ref does not affect
// any of the browser's preclassification checks, so we don't require it
// to match.
- DVLOG(2) << "Not starting classification, last url from browser is "
- << last_url_received_from_browser_ << ", last finished load is "
- << last_finished_load_url_;
// Keep classifier_page_text_, in case the browser notifies us later that
// we should classify the URL.
return;
}
- DVLOG(2) << "Starting classification for " << last_finished_load_url_;
last_url_sent_to_classifier_ = last_finished_load_url_;
is_classifying_ = true;
classifier_->BeginClassification(
diff --git a/chromium/chrome/renderer/safe_browsing/phishing_classifier_delegate.h b/chromium/chrome/renderer/safe_browsing/phishing_classifier_delegate.h
index 9910fc79509..80aa1193e95 100644
--- a/chromium/chrome/renderer/safe_browsing/phishing_classifier_delegate.h
+++ b/chromium/chrome/renderer/safe_browsing/phishing_classifier_delegate.h
@@ -38,21 +38,6 @@ enum class SBPhishingClassifierEvent {
kMaxValue = kDestructedBeforeClassificationDone,
};
-class PhishingClassifierFilter : public mojom::PhishingModelSetter {
- public:
- PhishingClassifierFilter();
- ~PhishingClassifierFilter() override;
-
- static void Create(
- mojo::PendingReceiver<mojom::PhishingModelSetter> receiver);
-
- private:
- // mojom::PhishingModelSetter
- void SetPhishingModel(const std::string& model) override;
-
- DISALLOW_COPY_AND_ASSIGN(PhishingClassifierFilter);
-};
-
class PhishingClassifierDelegate : public content::RenderFrameObserver,
public mojom::PhishingDetector {
public:
@@ -63,6 +48,9 @@ class PhishingClassifierDelegate : public content::RenderFrameObserver,
PhishingClassifier* classifier);
~PhishingClassifierDelegate() override;
+ // mojom::PhishingDetector
+ void SetPhishingModel(const std::string& model) override;
+
// Called by the RenderFrame once there is a phishing scorer available.
// The scorer is passed on to the classifier.
void SetPhishingScorer(const safe_browsing::Scorer* scorer);
@@ -78,10 +66,11 @@ class PhishingClassifierDelegate : public content::RenderFrameObserver,
// Called by the RenderFrame when a page has started loading in the given
// WebFrame. Typically, this will cause any pending classification to be
- // cancelled. However, if the navigation is within the same page, we
- // continue running the current classification.
- void DidCommitProvisionalLoad(bool is_same_document_navigation,
- ui::PageTransition transition) override;
+ // cancelled.
+ void DidCommitProvisionalLoad(ui::PageTransition transition) override;
+ // Called by the RenderFrame when the same-document navigation has been
+ // committed. We continue running the current classification.
+ void DidFinishSameDocumentNavigation() override;
private:
friend class PhishingClassifierDelegateTest;
diff --git a/chromium/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc b/chromium/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc
index 2acec9d451c..0ae43da87c5 100644
--- a/chromium/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc
+++ b/chromium/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc
@@ -37,7 +37,7 @@ namespace {
class MockPhishingClassifier : public PhishingClassifier {
public:
explicit MockPhishingClassifier(content::RenderFrame* render_frame)
- : PhishingClassifier(render_frame, NULL /* clock */) {}
+ : PhishingClassifier(render_frame) {}
~MockPhishingClassifier() override {}
@@ -229,6 +229,25 @@ TEST_F(PhishingClassifierDelegateTest, Navigation) {
EXPECT_CALL(*classifier_, CancelPendingClassification());
}
+TEST_F(PhishingClassifierDelegateTest, NoPhishingModel) {
+ ASSERT_FALSE(classifier_->is_ready());
+ delegate_->SetPhishingModel("");
+ // The scorer is nullptr so the classifier should still not be ready.
+ ASSERT_FALSE(classifier_->is_ready());
+}
+
+TEST_F(PhishingClassifierDelegateTest, HasPhishingModel) {
+ ASSERT_FALSE(classifier_->is_ready());
+
+ ClientSideModel model;
+ model.set_max_words_per_term(1);
+ delegate_->SetPhishingModel(model.SerializeAsString());
+ ASSERT_TRUE(classifier_->is_ready());
+
+ // The delegate will cancel pending classification on destruction.
+ EXPECT_CALL(*classifier_, CancelPendingClassification());
+}
+
TEST_F(PhishingClassifierDelegateTest, NoScorer) {
// For this test, we'll create the delegate with no scorer available yet.
ASSERT_FALSE(classifier_->is_ready());
diff --git a/chromium/chrome/renderer/safe_browsing/phishing_dom_feature_extractor.cc b/chromium/chrome/renderer/safe_browsing/phishing_dom_feature_extractor.cc
index f1a9fb37d82..c31a97320cb 100644
--- a/chromium/chrome/renderer/safe_browsing/phishing_dom_feature_extractor.cc
+++ b/chromium/chrome/renderer/safe_browsing/phishing_dom_feature_extractor.cc
@@ -9,13 +9,12 @@
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/location.h"
-#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "base/time/default_tick_clock.h"
#include "base/time/time.h"
-#include "chrome/renderer/safe_browsing/feature_extractor_clock.h"
#include "chrome/renderer/safe_browsing/features.h"
#include "content/public/renderer/render_view.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
@@ -102,16 +101,17 @@ struct PhishingDOMFeatureExtractor::FrameData {
std::string domain;
};
-PhishingDOMFeatureExtractor::PhishingDOMFeatureExtractor(
- FeatureExtractorClock* clock)
- : clock_(clock) {
+PhishingDOMFeatureExtractor::PhishingDOMFeatureExtractor()
+ : clock_(base::DefaultTickClock::GetInstance()) {
Clear();
}
PhishingDOMFeatureExtractor::~PhishingDOMFeatureExtractor() {
// The RenderView should have called CancelPendingExtraction() before
// we are destroyed.
- CheckNoPendingExtraction();
+ DCHECK(done_callback_.is_null());
+ DCHECK(!cur_frame_data_.get());
+ DCHECK(cur_document_.IsNull());
}
void PhishingDOMFeatureExtractor::ExtractFeatures(blink::WebDocument document,
@@ -119,7 +119,9 @@ void PhishingDOMFeatureExtractor::ExtractFeatures(blink::WebDocument document,
DoneCallback done_callback) {
// The RenderView should have called CancelPendingExtraction() before
// starting a new extraction, so DCHECK this.
- CheckNoPendingExtraction();
+ DCHECK(done_callback_.is_null());
+ DCHECK(!cur_frame_data_.get());
+ DCHECK(cur_document_.IsNull());
// However, in an opt build, we will go ahead and clean up the pending
// extraction so that we can start in a known state.
CancelPendingExtraction();
@@ -127,7 +129,7 @@ void PhishingDOMFeatureExtractor::ExtractFeatures(blink::WebDocument document,
features_ = features;
done_callback_ = std::move(done_callback);
- page_feature_state_.reset(new PageFeatureState(clock_->Now()));
+ page_feature_state_ = std::make_unique<PageFeatureState>(clock_->NowTicks());
cur_document_ = document;
base::ThreadTaskRunnerHandle::Get()->PostTask(
@@ -145,7 +147,7 @@ void PhishingDOMFeatureExtractor::CancelPendingExtraction() {
void PhishingDOMFeatureExtractor::ExtractFeaturesWithTimeout() {
DCHECK(page_feature_state_.get());
++page_feature_state_->num_iterations;
- base::TimeTicks current_chunk_start_time = clock_->Now();
+ base::TimeTicks current_chunk_start_time = clock_->NowTicks();
if (cur_document_.IsNull()) {
// This will only happen if we weren't able to get the document for the
@@ -166,7 +168,7 @@ void PhishingDOMFeatureExtractor::ExtractFeaturesWithTimeout() {
// modified between our chunks of work. Log how long this takes, so we
// can tell if it's too slow.
UMA_HISTOGRAM_TIMES("SBClientPhishing.DOMFeatureResumeTime",
- clock_->Now() - current_chunk_start_time);
+ clock_->NowTicks() - current_chunk_start_time);
} else {
// We just moved to a new frame, so update our frame state
// and advance to the first element.
@@ -190,10 +192,9 @@ void PhishingDOMFeatureExtractor::ExtractFeaturesWithTimeout() {
if (++num_elements >= kClockCheckGranularity) {
num_elements = 0;
- base::TimeTicks now = clock_->Now();
+ base::TimeTicks now = clock_->NowTicks();
if (now - page_feature_state_->start_time >=
base::TimeDelta::FromMilliseconds(kMaxTotalTimeMs)) {
- DLOG(ERROR) << "Feature extraction took too long, giving up";
// We expect this to happen infrequently, so record when it does.
UMA_HISTOGRAM_COUNTS_1M("SBClientPhishing.DOMFeatureTimeout", 1);
RunCallback(false);
@@ -233,20 +234,16 @@ void PhishingDOMFeatureExtractor::ExtractFeaturesWithTimeout() {
void PhishingDOMFeatureExtractor::HandleLink(
const blink::WebElement& element) {
// Count the number of times we link to a different host.
- if (!element.HasAttribute("href")) {
- DVLOG(1) << "Skipping anchor tag with no href";
+ if (!element.HasAttribute("href"))
return;
- }
// Retrieve the link and resolve the link in case it's relative.
blink::WebURL full_url = CompleteURL(element, element.GetAttribute("href"));
std::string domain;
bool is_external = IsExternalDomain(full_url, &domain);
- if (domain.empty()) {
- DVLOG(1) << "Could not extract domain from link: " << full_url;
+ if (domain.empty())
return;
- }
if (is_external) {
++page_feature_state_->external_links;
@@ -279,10 +276,8 @@ void PhishingDOMFeatureExtractor::HandleForm(
std::string domain;
bool is_external = IsExternalDomain(full_url, &domain);
- if (domain.empty()) {
- DVLOG(1) << "Could not extract domain from form action: " << full_url;
+ if (domain.empty())
return;
- }
if (is_external) {
++page_feature_state_->action_other_domain;
@@ -292,22 +287,16 @@ void PhishingDOMFeatureExtractor::HandleForm(
void PhishingDOMFeatureExtractor::HandleImage(
const blink::WebElement& element) {
- if (!element.HasAttribute("src")) {
- DVLOG(1) << "Skipping img tag with no src";
- }
-
// Record whether the image points to a different domain.
blink::WebURL full_url = CompleteURL(element, element.GetAttribute("src"));
std::string domain;
bool is_external = IsExternalDomain(full_url, &domain);
- if (domain.empty()) {
- DVLOG(1) << "Could not extract domain from image src: " << full_url;
+ if (domain.empty())
return;
- }
- if (is_external) {
+ if (is_external)
++page_feature_state_->img_other_domain;
- }
+
++page_feature_state_->total_imgs;
}
@@ -340,17 +329,6 @@ void PhishingDOMFeatureExtractor::HandleScript(
++page_feature_state_->num_script_tags;
}
-void PhishingDOMFeatureExtractor::CheckNoPendingExtraction() {
- DCHECK(done_callback_.is_null());
- DCHECK(!cur_frame_data_.get());
- DCHECK(cur_document_.IsNull());
- if (!done_callback_.is_null() || cur_frame_data_.get() ||
- !cur_document_.IsNull()) {
- LOG(ERROR) << "Extraction in progress, missing call to "
- << "CancelPendingExtraction";
- }
-}
-
void PhishingDOMFeatureExtractor::RunCallback(bool success) {
// Record some timing stats that we can use to evaluate feature extraction
// performance. These include both successful and failed extractions.
@@ -358,7 +336,7 @@ void PhishingDOMFeatureExtractor::RunCallback(bool success) {
UMA_HISTOGRAM_COUNTS_1M("SBClientPhishing.DOMFeatureIterations",
page_feature_state_->num_iterations);
UMA_HISTOGRAM_TIMES("SBClientPhishing.DOMFeatureTotalTime",
- clock_->Now() - page_feature_state_->start_time);
+ clock_->NowTicks() - page_feature_state_->start_time);
DCHECK(!done_callback_.is_null());
std::move(done_callback_).Run(success);
@@ -366,9 +344,9 @@ void PhishingDOMFeatureExtractor::RunCallback(bool success) {
}
void PhishingDOMFeatureExtractor::Clear() {
- features_ = NULL;
+ features_ = nullptr;
done_callback_.Reset();
- cur_frame_data_.reset(NULL);
+ cur_frame_data_.reset(nullptr);
cur_document_.Reset();
}
diff --git a/chromium/chrome/renderer/safe_browsing/phishing_dom_feature_extractor.h b/chromium/chrome/renderer/safe_browsing/phishing_dom_feature_extractor.h
index 6f4e2c1503c..4639f620f2c 100644
--- a/chromium/chrome/renderer/safe_browsing/phishing_dom_feature_extractor.h
+++ b/chromium/chrome/renderer/safe_browsing/phishing_dom_feature_extractor.h
@@ -16,6 +16,7 @@
#include "base/callback.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
+#include "base/time/tick_clock.h"
#include "third_party/blink/public/web/web_document.h"
class GURL;
@@ -25,7 +26,6 @@ class WebElement;
}
namespace safe_browsing {
-class FeatureExtractorClock;
class FeatureMap;
class PhishingDOMFeatureExtractor {
@@ -35,9 +35,7 @@ class PhishingDOMFeatureExtractor {
typedef base::OnceCallback<void(bool)> DoneCallback;
// Creates a PhishingDOMFeatureExtractor instance.
- // |clock| is used for timing feature extractor operations, and may be
- // mocked for testing. The caller maintains ownership of the clock.
- explicit PhishingDOMFeatureExtractor(FeatureExtractorClock* clock);
+ PhishingDOMFeatureExtractor();
virtual ~PhishingDOMFeatureExtractor();
// Begins extracting features into the given FeatureMap for the page.
@@ -55,6 +53,8 @@ class PhishingDOMFeatureExtractor {
// is unloaded or the PhishingDOMFeatureExtractor is destroyed.
void CancelPendingExtraction();
+ void SetTickClockForTesting(const base::TickClock* clock) { clock_ = clock; }
+
private:
struct FrameData;
struct PageFeatureState;
@@ -88,11 +88,6 @@ class PhishingDOMFeatureExtractor {
void HandleInput(const blink::WebElement& element);
void HandleScript(const blink::WebElement& element);
- // Helper to verify that there is no pending feature extraction. Dies in
- // debug builds if the state is not as expected. This is a no-op in release
- // builds.
- void CheckNoPendingExtraction();
-
// Runs |done_callback_| and then clears all internal state.
void RunCallback(bool success);
@@ -122,9 +117,7 @@ class PhishingDOMFeatureExtractor {
// description of which features are computed.
void InsertFeatures();
-
- // Non-owned pointer to our clock.
- FeatureExtractorClock* clock_;
+ const base::TickClock* clock_;
// The output parameters from the most recent call to ExtractFeatures().
FeatureMap* features_; // The caller keeps ownership of this.
diff --git a/chromium/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc b/chromium/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc
index e64fd770af3..0586f5a9a5a 100644
--- a/chromium/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc
+++ b/chromium/chrome/renderer/safe_browsing/phishing_dom_feature_extractor_browsertest.cc
@@ -13,7 +13,6 @@
#include "base/time/time.h"
#include "chrome/renderer/chrome_content_renderer_client.h"
#include "chrome/renderer/safe_browsing/features.h"
-#include "chrome/renderer/safe_browsing/mock_feature_extractor_clock.h"
#include "chrome/renderer/safe_browsing/test_utils.h"
#include "chrome/test/base/chrome_render_view_test.h"
#include "content/public/common/content_switches.h"
@@ -30,22 +29,28 @@
#include "third_party/blink/public/web/web_script_source.h"
#include "ui/native_theme/native_theme_features.h"
+using blink::WebRuntimeFeatures;
using ::testing::DoAll;
using ::testing::Invoke;
using ::testing::Return;
-using blink::WebRuntimeFeatures;
+using ::testing::StrictMock;
namespace safe_browsing {
+class MockTickClock : public base::TickClock {
+ public:
+ MockTickClock() = default;
+ ~MockTickClock() override = default;
+
+ MOCK_CONST_METHOD0(NowTicks, base::TimeTicks());
+};
+
// TestPhishingDOMFeatureExtractor has nearly identical behavior as
// PhishingDOMFeatureExtractor, except the IsExternalDomain() and
// CompleteURL() functions. This is to work around the fact that
// ChromeRenderViewTest object does not know where the html content is hosted.
class TestPhishingDOMFeatureExtractor : public PhishingDOMFeatureExtractor {
public:
- explicit TestPhishingDOMFeatureExtractor(FeatureExtractorClock* clock)
- : PhishingDOMFeatureExtractor(clock) {}
-
void SetDocumentDomain(std::string domain) { base_domain_ = domain; }
void SetURLToFrameDomainCheckingMap(
@@ -106,9 +111,6 @@ class TestPhishingDOMFeatureExtractor : public PhishingDOMFeatureExtractor {
const std::string frame_domain = it->second;
full_url = GURL("http://" + it->second).Resolve(partial_url.Utf8());
url_to_frame_domain_map_[full_url.spec()] = it->second;
- } else {
- NOTREACHED() << "Testing input setup is incorrect. "
- "Please check url_to_frame_domain_map_ setup.";
}
}
return blink::WebURL(full_url);
@@ -191,7 +193,7 @@ class PhishingDOMFeatureExtractorTest : public ChromeRenderViewTest {
ChromeRenderViewTest::SetUp();
WebRuntimeFeatures::EnableOverlayScrollbars(
ui::IsOverlayScrollbarEnabled());
- extractor_.reset(new TestPhishingDOMFeatureExtractor(&clock_));
+ extractor_ = std::make_unique<TestPhishingDOMFeatureExtractor>();
}
void TearDown() override {
@@ -218,7 +220,6 @@ class PhishingDOMFeatureExtractorTest : public ChromeRenderViewTest {
"document.body.removeChild(document.getElementById('frame1'));"));
}
- MockFeatureExtractorClock clock_;
bool success_;
std::unique_ptr<TestPhishingDOMFeatureExtractor> extractor_;
scoped_refptr<content::MessageLoopRunner> message_loop_;
@@ -226,9 +227,6 @@ class PhishingDOMFeatureExtractorTest : public ChromeRenderViewTest {
};
TEST_F(PhishingDOMFeatureExtractorTest, FormFeatures) {
- // This test doesn't exercise the extraction timing.
- EXPECT_CALL(clock_, Now()).WillRepeatedly(Return(base::TimeTicks::Now()));
-
FeatureMap expected_features;
expected_features.AddBooleanFeature(features::kPageHasForms);
expected_features.AddRealFeature(features::kPageActionOtherDomainFreq, 0.25);
@@ -296,9 +294,6 @@ TEST_F(PhishingDOMFeatureExtractorTest, FormFeatures) {
}
TEST_F(PhishingDOMFeatureExtractorTest, LinkFeatures) {
- // This test doesn't exercise the extraction timing.
- EXPECT_CALL(clock_, Now()).WillRepeatedly(Return(base::TimeTicks::Now()));
-
FeatureMap expected_features;
expected_features.AddRealFeature(features::kPageExternalLinksFreq, 0.5);
expected_features.AddRealFeature(features::kPageSecureLinksFreq, 0.0);
@@ -334,9 +329,6 @@ TEST_F(PhishingDOMFeatureExtractorTest, LinkFeatures) {
}
TEST_F(PhishingDOMFeatureExtractorTest, ScriptAndImageFeatures) {
- // This test doesn't exercise the extraction timing.
- EXPECT_CALL(clock_, Now()).WillRepeatedly(Return(base::TimeTicks::Now()));
-
FeatureMap expected_features;
expected_features.AddBooleanFeature(features::kPageNumScriptTagsGTOne);
@@ -370,10 +362,6 @@ TEST_F(PhishingDOMFeatureExtractorTest, ScriptAndImageFeatures) {
// iframe2 / \ iframe1
// \ iframe3
TEST_F(PhishingDOMFeatureExtractorTest, SubFrames) {
- // This test doesn't exercise the extraction timing.
- // Test that features are aggregated across all frames.
- EXPECT_CALL(clock_, Now()).WillRepeatedly(Return(base::TimeTicks::Now()));
-
const char urlprefix[] = "data:text/html;charset=utf-8,";
std::unordered_map<std::string, std::string> url_iframe_map;
std::string iframe1_nested_html(
@@ -443,8 +431,7 @@ TEST_F(PhishingDOMFeatureExtractorTest, SubFrames) {
}
TEST_F(PhishingDOMFeatureExtractorTest, Continuation) {
- // For this test, we'll cause the feature extraction to run multiple
- // iterations by incrementing the clock.
+ StrictMock<MockTickClock> tick_clock;
// This page has a total of 50 elements. For the external forms feature to
// be computed correctly, the extractor has to examine the whole document.
@@ -462,7 +449,7 @@ TEST_F(PhishingDOMFeatureExtractorTest, Continuation) {
// Note that this assumes kClockCheckGranularity = 10 and
// kMaxTimePerChunkMs = 10.
base::TimeTicks now = base::TimeTicks::Now();
- EXPECT_CALL(clock_, Now())
+ EXPECT_CALL(tick_clock, NowTicks())
// Time check at the start of extraction.
.WillOnce(Return(now))
// Time check at the start of the first chunk of work.
@@ -489,6 +476,7 @@ TEST_F(PhishingDOMFeatureExtractorTest, Continuation) {
.WillOnce(Return(now + base::TimeDelta::FromMilliseconds(54)))
// A final time check for the histograms.
.WillOnce(Return(now + base::TimeDelta::FromMilliseconds(56)));
+ extractor_->SetTickClockForTesting(&tick_clock);
FeatureMap expected_features;
expected_features.AddBooleanFeature(features::kPageHasForms);
@@ -502,13 +490,13 @@ TEST_F(PhishingDOMFeatureExtractorTest, Continuation) {
ExtractFeatures("host.com", html, &features);
ExpectFeatureMapsAreEqual(features, expected_features);
// Make sure none of the mock expectations carry over to the next test.
- ::testing::Mock::VerifyAndClearExpectations(&clock_);
+ ::testing::Mock::VerifyAndClearExpectations(&tick_clock);
// Now repeat the test with the same page, but advance the clock faster so
// that the extraction time exceeds the maximum total time for the feature
// extractor. Extraction should fail. Note that this assumes
// kMaxTotalTimeMs = 500.
- EXPECT_CALL(clock_, Now())
+ EXPECT_CALL(tick_clock, NowTicks())
// Time check at the start of extraction.
.WillOnce(Return(now))
// Time check at the start of the first chunk of work.
@@ -542,7 +530,8 @@ TEST_F(PhishingDOMFeatureExtractorTest, SubframeRemoval) {
GURL iframe1_url(urlprefix + iframe1_html);
base::TimeTicks now = base::TimeTicks::Now();
- EXPECT_CALL(clock_, Now())
+ StrictMock<MockTickClock> tick_clock;
+ EXPECT_CALL(tick_clock, NowTicks())
// Time check at the start of extraction.
.WillOnce(Return(now))
// Time check at the start of the first chunk of work.
@@ -559,6 +548,7 @@ TEST_F(PhishingDOMFeatureExtractorTest, SubframeRemoval) {
.WillOnce(Return(now + base::TimeDelta::FromMilliseconds(27)))
// A final time check for the histograms.
.WillOnce(Return(now + base::TimeDelta::FromMilliseconds(33)));
+ extractor_->SetTickClockForTesting(&tick_clock);
FeatureMap expected_features;
expected_features.AddBooleanFeature(features::kPageHasForms);
diff --git a/chromium/chrome/renderer/safe_browsing/phishing_term_feature_extractor.cc b/chromium/chrome/renderer/safe_browsing/phishing_term_feature_extractor.cc
index 2bea4a2ea43..61d045735cb 100644
--- a/chromium/chrome/renderer/safe_browsing/phishing_term_feature_extractor.cc
+++ b/chromium/chrome/renderer/safe_browsing/phishing_term_feature_extractor.cc
@@ -15,13 +15,12 @@
#include "base/i18n/break_iterator.h"
#include "base/i18n/case_conversion.h"
#include "base/location.h"
-#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
+#include "base/time/default_tick_clock.h"
#include "base/time/time.h"
-#include "chrome/renderer/safe_browsing/feature_extractor_clock.h"
#include "chrome/renderer/safe_browsing/features.h"
#include "chrome/renderer/safe_browsing/murmurhash3_util.h"
#include "crypto/sha2.h"
@@ -74,11 +73,8 @@ struct PhishingTermFeatureExtractor::ExtractionState {
std::unique_ptr<base::i18n::BreakIterator> i(new base::i18n::BreakIterator(
text, base::i18n::BreakIterator::BREAK_WORD));
- if (i->Init()) {
+ if (i->Init())
iterator = std::move(i);
- } else {
- DLOG(ERROR) << "failed to open iterator";
- }
}
};
@@ -88,22 +84,22 @@ PhishingTermFeatureExtractor::PhishingTermFeatureExtractor(
size_t max_words_per_term,
uint32_t murmurhash3_seed,
size_t max_shingles_per_page,
- size_t shingle_size,
- FeatureExtractorClock* clock)
+ size_t shingle_size)
: page_term_hashes_(page_term_hashes),
page_word_hashes_(page_word_hashes),
max_words_per_term_(max_words_per_term),
murmurhash3_seed_(murmurhash3_seed),
max_shingles_per_page_(max_shingles_per_page),
shingle_size_(shingle_size),
- clock_(clock) {
+ clock_(base::DefaultTickClock::GetInstance()) {
Clear();
}
PhishingTermFeatureExtractor::~PhishingTermFeatureExtractor() {
// The RenderView should have called CancelPendingExtraction() before
// we are destroyed.
- CheckNoPendingExtraction();
+ DCHECK(done_callback_.is_null());
+ DCHECK(!state_.get());
}
void PhishingTermFeatureExtractor::ExtractFeatures(
@@ -113,7 +109,8 @@ void PhishingTermFeatureExtractor::ExtractFeatures(
DoneCallback done_callback) {
// The RenderView should have called CancelPendingExtraction() before
// starting a new extraction, so DCHECK this.
- CheckNoPendingExtraction();
+ DCHECK(done_callback_.is_null());
+ DCHECK(!state_.get());
// However, in an opt build, we will go ahead and clean up the pending
// extraction so that we can start in a known state.
CancelPendingExtraction();
@@ -122,7 +119,7 @@ void PhishingTermFeatureExtractor::ExtractFeatures(
features_ = features;
shingle_hashes_ = shingle_hashes, done_callback_ = std::move(done_callback);
- state_.reset(new ExtractionState(*page_text_, clock_->Now()));
+ state_ = std::make_unique<ExtractionState>(*page_text_, clock_->NowTicks());
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&PhishingTermFeatureExtractor::ExtractFeaturesWithTimeout,
@@ -138,7 +135,7 @@ void PhishingTermFeatureExtractor::CancelPendingExtraction() {
void PhishingTermFeatureExtractor::ExtractFeaturesWithTimeout() {
DCHECK(state_.get());
++state_->num_iterations;
- base::TimeTicks current_chunk_start_time = clock_->Now();
+ base::TimeTicks current_chunk_start_time = clock_->NowTicks();
if (!state_->iterator.get()) {
// We failed to initialize the break iterator, so stop now.
@@ -158,10 +155,9 @@ void PhishingTermFeatureExtractor::ExtractFeaturesWithTimeout() {
if (num_words >= kClockCheckGranularity) {
num_words = 0;
- base::TimeTicks now = clock_->Now();
+ base::TimeTicks now = clock_->NowTicks();
if (now - state_->start_time >=
base::TimeDelta::FromMilliseconds(kMaxTotalTimeMs)) {
- DLOG(ERROR) << "Feature extraction took too long, giving up";
// We expect this to happen infrequently, so record when it does.
UMA_HISTOGRAM_COUNTS_1M("SBClientPhishing.TermFeatureTimeout", 1);
RunCallback(false);
@@ -261,15 +257,6 @@ void PhishingTermFeatureExtractor::HandleWord(
}
}
-void PhishingTermFeatureExtractor::CheckNoPendingExtraction() {
- DCHECK(done_callback_.is_null());
- DCHECK(!state_.get());
- if (!done_callback_.is_null() || state_.get()) {
- LOG(ERROR) << "Extraction in progress, missing call to "
- << "CancelPendingExtraction";
- }
-}
-
void PhishingTermFeatureExtractor::RunCallback(bool success) {
// Record some timing stats that we can use to evaluate feature extraction
// performance. These include both successful and failed extractions.
@@ -277,7 +264,7 @@ void PhishingTermFeatureExtractor::RunCallback(bool success) {
UMA_HISTOGRAM_COUNTS_1M("SBClientPhishing.TermFeatureIterations",
state_->num_iterations);
UMA_HISTOGRAM_TIMES("SBClientPhishing.TermFeatureTotalTime",
- clock_->Now() - state_->start_time);
+ clock_->NowTicks() - state_->start_time);
DCHECK(!done_callback_.is_null());
std::move(done_callback_).Run(success);
@@ -285,11 +272,11 @@ void PhishingTermFeatureExtractor::RunCallback(bool success) {
}
void PhishingTermFeatureExtractor::Clear() {
- page_text_ = NULL;
- features_ = NULL;
- shingle_hashes_ = NULL;
+ page_text_ = nullptr;
+ features_ = nullptr;
+ shingle_hashes_ = nullptr;
done_callback_.Reset();
- state_.reset(NULL);
+ state_.reset(nullptr);
}
} // namespace safe_browsing
diff --git a/chromium/chrome/renderer/safe_browsing/phishing_term_feature_extractor.h b/chromium/chrome/renderer/safe_browsing/phishing_term_feature_extractor.h
index d0cc48d7033..341f60704a2 100644
--- a/chromium/chrome/renderer/safe_browsing/phishing_term_feature_extractor.h
+++ b/chromium/chrome/renderer/safe_browsing/phishing_term_feature_extractor.h
@@ -29,9 +29,9 @@
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "base/strings/string_piece.h"
+#include "base/time/tick_clock.h"
namespace safe_browsing {
-class FeatureExtractorClock;
class FeatureMap;
class PhishingTermFeatureExtractor {
@@ -63,8 +63,7 @@ class PhishingTermFeatureExtractor {
size_t max_words_per_term,
uint32_t murmurhash3_seed,
size_t max_shingles_per_page,
- size_t shingle_size,
- FeatureExtractorClock* clock);
+ size_t shingle_size);
~PhishingTermFeatureExtractor();
// Begins extracting features from |page_text| into the given FeatureMap.
@@ -90,6 +89,8 @@ class PhishingTermFeatureExtractor {
// is unloaded or the PhishingTermFeatureExtractor is destroyed.
void CancelPendingExtraction();
+ void SetTickClockForTesting(const base::TickClock* clock) { clock_ = clock; }
+
private:
struct ExtractionState;
@@ -115,11 +116,6 @@ class PhishingTermFeatureExtractor {
// Handles a single word in the page text.
void HandleWord(const base::StringPiece16& word);
- // Helper to verify that there is no pending feature extraction. Dies in
- // debug builds if the state is not as expected. This is a no-op in release
- // builds.
- void CheckNoPendingExtraction();
-
// Runs |done_callback_| and then clears all internal state.
void RunCallback(bool success);
@@ -149,7 +145,7 @@ class PhishingTermFeatureExtractor {
const size_t shingle_size_;
// Non-owned pointer to our clock.
- FeatureExtractorClock* clock_;
+ const base::TickClock* clock_;
// The output parameters from the most recent call to ExtractFeatures().
const base::string16* page_text_; // The caller keeps ownership of this.
diff --git a/chromium/chrome/renderer/safe_browsing/phishing_term_feature_extractor_unittest.cc b/chromium/chrome/renderer/safe_browsing/phishing_term_feature_extractor_unittest.cc
index c1b38303cbd..53fc9a643fb 100644
--- a/chromium/chrome/renderer/safe_browsing/phishing_term_feature_extractor_unittest.cc
+++ b/chromium/chrome/renderer/safe_browsing/phishing_term_feature_extractor_unittest.cc
@@ -24,7 +24,6 @@
#include "base/time/time.h"
#include "build/build_config.h"
#include "chrome/renderer/safe_browsing/features.h"
-#include "chrome/renderer/safe_browsing/mock_feature_extractor_clock.h"
#include "chrome/renderer/safe_browsing/murmurhash3_util.h"
#include "chrome/renderer/safe_browsing/test_utils.h"
#include "crypto/sha2.h"
@@ -33,11 +32,20 @@
using base::ASCIIToUTF16;
using ::testing::Return;
+using ::testing::StrictMock;
static const uint32_t kMurmurHash3Seed = 2777808611U;
namespace safe_browsing {
+class MockTickClock : public base::TickClock {
+ public:
+ MockTickClock() = default;
+ ~MockTickClock() override = default;
+
+ MOCK_CONST_METHOD0(NowTicks, base::TimeTicks());
+};
+
class PhishingTermFeatureExtractorTest : public ::testing::Test {
protected:
void SetUp() override {
@@ -80,14 +88,9 @@ class PhishingTermFeatureExtractorTest : public ::testing::Test {
}
void ResetExtractor(size_t max_shingles_per_page) {
- extractor_.reset(new PhishingTermFeatureExtractor(
- &term_hashes_,
- &word_hashes_,
- 3 /* max_words_per_term */,
- kMurmurHash3Seed,
- max_shingles_per_page,
- 4 /* shingle_size */,
- &clock_));
+ extractor_ = std::make_unique<PhishingTermFeatureExtractor>(
+ &term_hashes_, &word_hashes_, 3 /* max_words_per_term */,
+ kMurmurHash3Seed, max_shingles_per_page, 4 /* shingle_size */);
}
// Runs the TermFeatureExtractor on |page_text|, waiting for the
@@ -133,7 +136,6 @@ class PhishingTermFeatureExtractorTest : public ::testing::Test {
base::test::SingleThreadTaskEnvironment task_environment_;
std::unique_ptr<base::RunLoop> active_run_loop_;
- MockFeatureExtractorClock clock_;
std::unique_ptr<PhishingTermFeatureExtractor> extractor_;
std::unordered_set<std::string> term_hashes_;
std::unordered_set<uint32_t> word_hashes_;
@@ -141,9 +143,6 @@ class PhishingTermFeatureExtractorTest : public ::testing::Test {
};
TEST_F(PhishingTermFeatureExtractorTest, ExtractFeatures) {
- // This test doesn't exercise the extraction timing.
- EXPECT_CALL(clock_, Now()).WillRepeatedly(Return(base::TimeTicks::Now()));
-
base::string16 page_text = ASCIIToUTF16("blah");
FeatureMap expected_features; // initially empty
std::set<uint32_t> expected_shingle_hashes;
@@ -306,7 +305,8 @@ TEST_F(PhishingTermFeatureExtractorTest, Continuation) {
// Note that this assumes kClockCheckGranularity = 5 and
// kMaxTimePerChunkMs = 10.
base::TimeTicks now = base::TimeTicks::Now();
- EXPECT_CALL(clock_, Now())
+ StrictMock<MockTickClock> tick_clock;
+ EXPECT_CALL(tick_clock, NowTicks())
// Time check at the start of extraction.
.WillOnce(Return(now))
// Time check at the start of the first chunk of work.
@@ -328,6 +328,7 @@ TEST_F(PhishingTermFeatureExtractorTest, Continuation) {
.WillOnce(Return(now + base::TimeDelta::FromMilliseconds(28)))
// A final check for the histograms.
.WillOnce(Return(now + base::TimeDelta::FromMilliseconds(30)));
+ extractor_->SetTickClockForTesting(&tick_clock);
FeatureMap expected_features;
expected_features.AddBooleanFeature(features::kPageTerm +
@@ -396,13 +397,13 @@ TEST_F(PhishingTermFeatureExtractorTest, Continuation) {
ExpectFeatureMapsAreEqual(features, expected_features);
EXPECT_THAT(expected_shingle_hashes, testing::ContainerEq(shingle_hashes));
// Make sure none of the mock expectations carry over to the next test.
- ::testing::Mock::VerifyAndClearExpectations(&clock_);
+ ::testing::Mock::VerifyAndClearExpectations(&tick_clock);
// Now repeat the test with the same text, but advance the clock faster so
// that the extraction time exceeds the maximum total time for the feature
// extractor. Extraction should fail. Note that this assumes
// kMaxTotalTimeMs = 500.
- EXPECT_CALL(clock_, Now())
+ EXPECT_CALL(tick_clock, NowTicks())
// Time check at the start of extraction.
.WillOnce(Return(now))
// Time check at the start of the first chunk of work.
@@ -429,7 +430,8 @@ TEST_F(PhishingTermFeatureExtractorTest, PartialExtractionTest) {
}
base::TimeTicks now = base::TimeTicks::Now();
- EXPECT_CALL(clock_, Now())
+ StrictMock<MockTickClock> tick_clock;
+ EXPECT_CALL(tick_clock, NowTicks())
// Time check at the start of extraction.
.WillOnce(Return(now))
// Time check at the start of the first chunk of work.
@@ -439,6 +441,7 @@ TEST_F(PhishingTermFeatureExtractorTest, PartialExtractionTest) {
// Time check after the next 5 words. This should be greater than
// kMaxTimePerChunkMs so that we stop and schedule extraction for later.
.WillOnce(Return(now + base::TimeDelta::FromMilliseconds(14)));
+ extractor_->SetTickClockForTesting(&tick_clock);
FeatureMap features;
std::set<uint32_t> shingle_hashes;
@@ -454,7 +457,8 @@ TEST_F(PhishingTermFeatureExtractorTest, PartialExtractionTest) {
shingle_hashes.clear();
// This part doesn't exercise the extraction timing.
- EXPECT_CALL(clock_, Now()).WillRepeatedly(Return(base::TimeTicks::Now()));
+ EXPECT_CALL(tick_clock, NowTicks())
+ .WillRepeatedly(Return(base::TimeTicks::Now()));
// Now extract normally and make sure nothing breaks.
EXPECT_TRUE(ExtractFeatures(page_text.get(), &features, &shingle_hashes));
diff --git a/chromium/chrome/renderer/safe_browsing/phishing_url_feature_extractor.cc b/chromium/chrome/renderer/safe_browsing/phishing_url_feature_extractor.cc
index 931c5203edd..403d1d060f7 100644
--- a/chromium/chrome/renderer/safe_browsing/phishing_url_feature_extractor.cc
+++ b/chromium/chrome/renderer/safe_browsing/phishing_url_feature_extractor.cc
@@ -8,7 +8,6 @@
#include <string>
#include <vector>
-#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
@@ -44,8 +43,8 @@ bool PhishingUrlFeatureExtractor::ExtractFeatures(const GURL& url,
host, net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES,
net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES);
+ // Check if TLD exists for host.
if (registry_length == 0 || registry_length == std::string::npos) {
- DVLOG(1) << "Could not find TLD for host: " << host;
return false;
}
DCHECK_LT(registry_length, host.size()) << "Non-zero registry length, but "
@@ -59,8 +58,8 @@ bool PhishingUrlFeatureExtractor::ExtractFeatures(const GURL& url,
host.erase(tld_start - 1);
std::vector<std::string> host_tokens = base::SplitString(
host, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
+ // Check if domain exists for host.
if (host_tokens.empty()) {
- DVLOG(1) << "Could not find domain for host: " << host;
return false;
}
if (!features->AddBooleanFeature(features::kUrlDomainToken +
diff --git a/chromium/chrome/renderer/safe_browsing/phishing_url_feature_extractor_unittest.cc b/chromium/chrome/renderer/safe_browsing/phishing_url_feature_extractor_unittest.cc
index e5412a7bd4e..c87ab3daf88 100644
--- a/chromium/chrome/renderer/safe_browsing/phishing_url_feature_extractor_unittest.cc
+++ b/chromium/chrome/renderer/safe_browsing/phishing_url_feature_extractor_unittest.cc
@@ -6,6 +6,8 @@
#include <string>
#include <vector>
+#include "base/format_macros.h"
+#include "base/strings/stringprintf.h"
#include "chrome/renderer/safe_browsing/features.h"
#include "chrome/renderer/safe_browsing/test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -25,10 +27,24 @@ class PhishingUrlFeatureExtractorTest : public ::testing::Test {
PhishingUrlFeatureExtractor::SplitStringIntoLongAlphanumTokens(full,
tokens);
}
+
+ void FillFeatureMap(size_t count, FeatureMap* features) {
+ for (size_t i = 0; i < count; ++i) {
+ EXPECT_TRUE(
+ features->AddBooleanFeature(base::StringPrintf("Feature%" PRIuS, i)));
+ }
+ }
};
TEST_F(PhishingUrlFeatureExtractorTest, ExtractFeatures) {
std::string url = "http://123.0.0.1/mydocuments/a.file.html";
+ FeatureMap features;
+
+ // If feature map is already full, features cannot be extracted.
+ FillFeatureMap(FeatureMap::kMaxFeatureMapSize, &features);
+ ASSERT_FALSE(extractor_.ExtractFeatures(GURL(url), &features));
+ features.Clear();
+
FeatureMap expected_features;
expected_features.AddBooleanFeature(features::kUrlHostIsIpAddress);
expected_features.AddBooleanFeature(features::kUrlPathToken +
@@ -38,9 +54,13 @@ TEST_F(PhishingUrlFeatureExtractorTest, ExtractFeatures) {
expected_features.AddBooleanFeature(features::kUrlPathToken +
std::string("html"));
- FeatureMap features;
ASSERT_TRUE(extractor_.ExtractFeatures(GURL(url), &features));
ExpectFeatureMapsAreEqual(features, expected_features);
+ // If feature map is already full, features cannot be extracted.
+ features.Clear();
+ FillFeatureMap(FeatureMap::kMaxFeatureMapSize - 1, &features);
+ ASSERT_FALSE(extractor_.ExtractFeatures(GURL(url), &features));
+ features.Clear();
url = "http://www.www.cnn.co.uk/sports/sports/index.html?shouldnotappear";
expected_features.Clear();
@@ -61,6 +81,10 @@ TEST_F(PhishingUrlFeatureExtractorTest, ExtractFeatures) {
features.Clear();
ASSERT_TRUE(extractor_.ExtractFeatures(GURL(url), &features));
ExpectFeatureMapsAreEqual(features, expected_features);
+ features.Clear();
+ // If feature map is already full, features cannot be extracted.
+ FillFeatureMap(FeatureMap::kMaxFeatureMapSize - 5, &features);
+ ASSERT_FALSE(extractor_.ExtractFeatures(GURL(url), &features));
url = "http://justadomain.com/";
expected_features.Clear();
@@ -72,6 +96,10 @@ TEST_F(PhishingUrlFeatureExtractorTest, ExtractFeatures) {
features.Clear();
ASSERT_TRUE(extractor_.ExtractFeatures(GURL(url), &features));
ExpectFeatureMapsAreEqual(features, expected_features);
+ // If feature map is already full, features cannot be extracted.
+ features.Clear();
+ FillFeatureMap(FeatureMap::kMaxFeatureMapSize - 1, &features);
+ ASSERT_FALSE(extractor_.ExtractFeatures(GURL(url), &features));
url = "http://witharef.com/#abc";
expected_features.Clear();
@@ -96,6 +124,10 @@ TEST_F(PhishingUrlFeatureExtractorTest, ExtractFeatures) {
features.Clear();
ASSERT_TRUE(extractor_.ExtractFeatures(GURL(url), &features));
ExpectFeatureMapsAreEqual(features, expected_features);
+ // If feature map is already full, features cannot be extracted.
+ features.Clear();
+ FillFeatureMap(FeatureMap::kMaxFeatureMapSize - 2, &features);
+ ASSERT_FALSE(extractor_.ExtractFeatures(GURL(url), &features));
url = "http://unrecognized.tld/";
EXPECT_FALSE(extractor_.ExtractFeatures(GURL(url), &features));
diff --git a/chromium/chrome/renderer/safe_browsing/scorer.cc b/chromium/chrome/renderer/safe_browsing/scorer.cc
index 8e37a934f9a..fc592db98c5 100644
--- a/chromium/chrome/renderer/safe_browsing/scorer.cc
+++ b/chromium/chrome/renderer/safe_browsing/scorer.cc
@@ -10,10 +10,10 @@
#include <unordered_map>
#include <unordered_set>
-#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_piece.h"
#include "chrome/renderer/safe_browsing/features.h"
+#include "components/safe_browsing/content/password_protection/visual_utils.h"
#include "components/safe_browsing/core/proto/client_model.pb.h"
namespace {
@@ -57,14 +57,12 @@ Scorer::~Scorer() {}
Scorer* Scorer::Create(const base::StringPiece& model_str) {
std::unique_ptr<Scorer> scorer(new Scorer());
ClientSideModel& model = scorer->model_;
+ // Parse the phishing model.
if (!model.ParseFromArray(model_str.data(), model_str.size())) {
- DLOG(ERROR) << "Unable to parse phishing model. This Scorer object is "
- << "invalid.";
RecordScorerCreationStatus(SCORER_FAIL_MODEL_PARSE_ERROR);
return NULL;
} else if (!model.IsInitialized()) {
- DLOG(ERROR) << "Unable to parse phishing model. The model is missing "
- << "some required fields. Maybe the .proto file changed?";
+ // The model may be missing some required fields.
RecordScorerCreationStatus(SCORER_FAIL_MODEL_MISSING_FIELDS);
return NULL;
}
@@ -86,6 +84,32 @@ double Scorer::ComputeScore(const FeatureMap& features) const {
return LogOdds2Prob(logodds);
}
+bool Scorer::GetMatchingVisualTargets(const SkBitmap& bitmap,
+ ClientPhishingRequest* request) const {
+ bool has_match = false;
+ for (const VisualTarget& target : model_.vision_model().targets()) {
+ base::Optional<VisionMatchResult> result =
+ visual_utils::IsVisualMatch(bitmap, target);
+ if (result.has_value()) {
+ *request->add_vision_match() = result.value();
+ has_match = true;
+ }
+ }
+
+ if (model_.has_vision_model()) {
+ // Populate these fields for telementry purposes. They will be filtered in
+ // the browser process if they are not needed.
+ VisualFeatures::BlurredImage blurred_image;
+ if (visual_utils::GetBlurredImage(bitmap, &blurred_image)) {
+ request->set_screenshot_phash(
+ visual_utils::GetHashFromBlurredImage(blurred_image));
+ request->set_phash_dimension_size(48);
+ }
+ }
+
+ return has_match;
+}
+
int Scorer::model_version() const {
return model_.version();
}
diff --git a/chromium/chrome/renderer/safe_browsing/scorer.h b/chromium/chrome/renderer/safe_browsing/scorer.h
index 5fda83d4817..597b4cf047b 100644
--- a/chromium/chrome/renderer/safe_browsing/scorer.h
+++ b/chromium/chrome/renderer/safe_browsing/scorer.h
@@ -23,6 +23,7 @@
#include "base/macros.h"
#include "base/strings/string_piece.h"
#include "components/safe_browsing/core/proto/client_model.pb.h"
+#include "third_party/skia/include/core/SkBitmap.h"
namespace safe_browsing {
class FeatureMap;
@@ -41,6 +42,11 @@ class Scorer {
// (range is inclusive on both ends).
virtual double ComputeScore(const FeatureMap& features) const;
+ // This method matches the given |bitmap| against the visual model. It returns
+ // true if any visual target matches, and populates |request| appropriately.
+ virtual bool GetMatchingVisualTargets(const SkBitmap& bitmap,
+ ClientPhishingRequest* request) const;
+
// Returns the version number of the loaded client model.
int model_version() const;
diff --git a/chromium/chrome/renderer/safe_browsing/scorer_unittest.cc b/chromium/chrome/renderer/safe_browsing/scorer_unittest.cc
index 9ea41fd1ccc..9083eca05a9 100644
--- a/chromium/chrome/renderer/safe_browsing/scorer_unittest.cc
+++ b/chromium/chrome/renderer/safe_browsing/scorer_unittest.cc
@@ -59,9 +59,39 @@ class PhishingScorerTest : public ::testing::Test {
model_.set_murmur_hash_seed(12345U);
model_.set_max_shingles_per_page(10);
model_.set_shingle_size(3);
+
+ // The first target hash is all 1-bits, except the first 8.
+ std::vector<unsigned char> target_hash;
+ target_hash.push_back('\x30');
+ for (int i = 0; i < 288; i++)
+ target_hash.push_back('\xff');
+ target_hash[1] = '\x00';
+ VisualTarget* target1 = model_.mutable_vision_model()->add_targets();
+ target1->set_digest("target1");
+ target1->set_hash(target_hash.data(), target_hash.size());
+ target1->mutable_match_config()->add_match_rule()->set_hash_distance(8.0);
+
+ // The second target hash is all 1-bits, except the second 8.
+ target_hash[1] = '\xff';
+ target_hash[2] = '\x00';
+ VisualTarget* target2 = model_.mutable_vision_model()->add_targets();
+ target2->set_digest("target2");
+ target2->set_hash(target_hash.data(), target_hash.size());
+ target2->mutable_match_config()->add_match_rule()->set_hash_distance(8.0);
+
+ // Allocate a bitmap for testing visual scoring
+ sk_sp<SkColorSpace> rec2020 = SkColorSpace::MakeRGB(
+ {2.22222f, 0.909672f, 0.0903276f, 0.222222f, 0.0812429f, 0, 0},
+ SkNamedGamut::kRec2020);
+ SkImageInfo bitmap_info =
+ SkImageInfo::Make(1000, 1000, SkColorType::kRGBA_8888_SkColorType,
+ SkAlphaType::kUnpremul_SkAlphaType, rec2020);
+
+ ASSERT_TRUE(bitmap_.tryAllocPixels(bitmap_info));
}
ClientSideModel model_;
+ SkBitmap bitmap_;
};
TEST_F(PhishingScorerTest, HasValidModel) {
@@ -145,4 +175,48 @@ TEST_F(PhishingScorerTest, ComputeScore) {
EXPECT_TRUE(features.AddBooleanFeature("feature2"));
EXPECT_DOUBLE_EQ(0.77729986117469119, scorer->ComputeScore(features));
}
+
+TEST_F(PhishingScorerTest, GetMatchingVisualTargetsMatchOne) {
+ std::unique_ptr<Scorer> scorer(Scorer::Create(model_.SerializeAsString()));
+
+ // Make the whole image white
+ for (int x = 0; x < 1000; x++)
+ for (int y = 0; y < 1000; y++)
+ *bitmap_.getAddr32(x, y) = 0xffffffff;
+
+ // Make the first 164 pixels black. This will make the first 8 bits of the
+ // hash 0.
+ for (int x = 0; x < 164; x++)
+ *bitmap_.getAddr32(x, 0) = 0xff000000;
+
+ ClientPhishingRequest request;
+ scorer->GetMatchingVisualTargets(bitmap_, &request);
+ ASSERT_EQ(request.vision_match_size(), 1);
+ EXPECT_EQ(request.vision_match(0).matched_target_digest(), "target1");
+}
+
+TEST_F(PhishingScorerTest, GetMatchingVisualTargetsMatchBoth) {
+ std::unique_ptr<Scorer> scorer(Scorer::Create(model_.SerializeAsString()));
+
+ // Make the whole image white
+ for (int x = 0; x < 1000; x++)
+ for (int y = 0; y < 1000; y++)
+ *bitmap_.getAddr32(x, y) = 0xffffffff;
+
+ // Create an alternating black/white pattern to match both targets. The
+ // pattern is 84 black pixels, then 84 white, then 84 black, then 84 white.
+ // This causes the hash to start 0F0F, for a distance of 8 from both targets.
+ for (int x = 0; x < 84; x++)
+ *bitmap_.getAddr32(x, 0) = 0xff000000;
+
+ for (int x = 168; x < 248; x++)
+ *bitmap_.getAddr32(x, 0) = 0xff000000;
+
+ ClientPhishingRequest request;
+ scorer->GetMatchingVisualTargets(bitmap_, &request);
+ ASSERT_EQ(request.vision_match_size(), 2);
+ EXPECT_EQ(request.vision_match(0).matched_target_digest(), "target1");
+ EXPECT_EQ(request.vision_match(1).matched_target_digest(), "target2");
+}
+
} // namespace safe_browsing
diff --git a/chromium/chrome/renderer/searchbox/searchbox.cc b/chromium/chrome/renderer/searchbox/searchbox.cc
index 1690ac1dd92..7439d1f0d1e 100644
--- a/chromium/chrome/renderer/searchbox/searchbox.cc
+++ b/chromium/chrome/renderer/searchbox/searchbox.cc
@@ -622,8 +622,7 @@ GURL SearchBox::GetURLForMostVisitedItem(InstantRestrictedID item_id) const {
return GetMostVisitedItemWithID(item_id, &item) ? item.url : GURL();
}
-void SearchBox::DidCommitProvisionalLoad(bool is_same_document_navigation,
- ui::PageTransition transition) {
+void SearchBox::DidCommitProvisionalLoad(ui::PageTransition transition) {
can_run_js_in_renderframe_ = true;
}
diff --git a/chromium/chrome/renderer/searchbox/searchbox.h b/chromium/chrome/renderer/searchbox/searchbox.h
index c1a8c92c8df..cf274ef90ad 100644
--- a/chromium/chrome/renderer/searchbox/searchbox.h
+++ b/chromium/chrome/renderer/searchbox/searchbox.h
@@ -242,8 +242,7 @@ class SearchBox : public content::RenderFrameObserver,
private:
// Overridden from content::RenderFrameObserver:
- void DidCommitProvisionalLoad(bool is_same_document_navigation,
- ui::PageTransition transition) override;
+ void DidCommitProvisionalLoad(ui::PageTransition transition) override;
void OnDestruct() override;
// Overridden from search::mojom::EmbeddedSearchClient:
diff --git a/chromium/chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.cc b/chromium/chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.cc
index 9af76f69eeb..bde390d6af5 100644
--- a/chromium/chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.cc
+++ b/chromium/chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.cc
@@ -92,6 +92,10 @@ void SubresourceRedirectHintsAgent::RecordMetricsOnLoadFinished(
RecordMetrics(content_length, redirect_result);
}
+void SubresourceRedirectHintsAgent::ClearImageHints() {
+ public_image_urls_.clear();
+}
+
void SubresourceRedirectHintsAgent::RecordMetrics(
int64_t content_length,
RedirectResult redirect_result) const {
diff --git a/chromium/chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.h b/chromium/chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.h
index b38d98d599a..76448440f3a 100644
--- a/chromium/chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.h
+++ b/chromium/chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.h
@@ -8,6 +8,7 @@
#include "base/containers/flat_set.h"
#include "base/macros.h"
#include "base/timer/timer.h"
+#include "chrome/common/subresource_redirect_service.mojom.h"
#include "third_party/blink/public/mojom/loader/previews_resource_loading_hints.mojom.h"
#include "url/gurl.h"
@@ -68,6 +69,9 @@ class SubresourceRedirectHintsAgent {
int64_t content_length,
RedirectResult redirect_result);
+ // Clears the image hint urls.
+ void ClearImageHints();
+
private:
void OnHintsReceiveTimeout();
void RecordMetrics(int64_t content_length,
diff --git a/chromium/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.cc b/chromium/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.cc
index f4c808f42c2..8ce4ae827f9 100644
--- a/chromium/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.cc
+++ b/chromium/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.cc
@@ -7,6 +7,7 @@
#include "base/memory/ptr_util.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
+#include "base/time/time.h"
#include "chrome/renderer/previews/resource_loading_hints_agent.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_params.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_util.h"
@@ -16,6 +17,7 @@
#include "net/base/escape.h"
#include "net/base/load_flags.h"
#include "net/http/http_status_code.h"
+#include "net/http/http_util.h"
#include "services/network/public/mojom/fetch_api.mojom-shared.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "third_party/blink/public/common/features.h"
@@ -44,6 +46,13 @@ bool ShouldCompressionServerRedirectSubresource() {
"enable_subresource_server_redirect", false);
}
+base::TimeDelta GetCompressionRedirectTimeout() {
+ return base::TimeDelta::FromMilliseconds(
+ base::GetFieldTrialParamByFeatureAsInt(
+ blink::features::kSubresourceRedirect, "subresource_redirect_timeout",
+ 5000));
+}
+
} // namespace
// static
@@ -117,16 +126,29 @@ void SubresourceRedirectURLLoaderThrottle::WillStartRequest(
request->url = GetSubresourceURLForURL(request->url);
did_redirect_compressed_origin_ = true;
*defer = false;
+
+ DCHECK(!redirect_timeout_timer_);
+ redirect_timeout_timer_ = std::make_unique<base::OneShotTimer>();
+ redirect_timeout_timer_->Start(
+ FROM_HERE, GetCompressionRedirectTimeout(),
+ base::BindOnce(&SubresourceRedirectURLLoaderThrottle::OnRedirectTimeout,
+ base::Unretained(this)));
}
-SubresourceRedirectHintsAgent*
-SubresourceRedirectURLLoaderThrottle::GetSubresourceRedirectHintsAgent() {
+previews::ResourceLoadingHintsAgent*
+SubresourceRedirectURLLoaderThrottle::GetResourceLoadingHintsAgent() {
+ // The ResourceLoadingHintsAgent is main-frame only.
if (content::RenderFrame* render_frame =
content::RenderFrame::FromRoutingID(render_frame_id_)) {
- if (auto* resource_loading_hints_agent =
- previews::ResourceLoadingHintsAgent::Get(render_frame)) {
- return &resource_loading_hints_agent->subresource_redirect_hints_agent();
- }
+ return previews::ResourceLoadingHintsAgent::Get(render_frame);
+ }
+ return nullptr;
+}
+
+SubresourceRedirectHintsAgent*
+SubresourceRedirectURLLoaderThrottle::GetSubresourceRedirectHintsAgent() {
+ if (auto* resource_loading_hints_agent = GetResourceLoadingHintsAgent()) {
+ return &resource_loading_hints_agent->subresource_redirect_hints_agent();
}
return nullptr;
}
@@ -138,6 +160,12 @@ void SubresourceRedirectURLLoaderThrottle::WillRedirectRequest(
std::vector<std::string>* to_be_removed_request_headers,
net::HttpRequestHeaders* modified_request_headers,
net::HttpRequestHeaders* modified_cors_exempt_request_headers) {
+ if (did_redirect_compressed_origin_ && redirect_timeout_timer_) {
+ redirect_timeout_timer_->Start(
+ FROM_HERE, GetCompressionRedirectTimeout(),
+ base::BindOnce(&SubresourceRedirectURLLoaderThrottle::OnRedirectTimeout,
+ base::Unretained(this)));
+ }
UMA_HISTOGRAM_ENUMERATION(
"SubresourceRedirect.CompressionAttempt.ResponseCode",
static_cast<net::HttpStatusCode>(response_head.headers->response_code()),
@@ -160,6 +188,7 @@ void SubresourceRedirectURLLoaderThrottle::BeforeWillProcessResponse(
"SubresourceRedirect.CompressionAttempt.ResponseCode",
static_cast<net::HttpStatusCode>(response_head.headers->response_code()),
net::HTTP_VERSION_NOT_SUPPORTED);
+ redirect_timeout_timer_.reset();
// Do nothing with 2XX responses, as these requests were handled
// correctly by the compression server.
@@ -171,6 +200,24 @@ void SubresourceRedirectURLLoaderThrottle::BeforeWillProcessResponse(
redirect_result_ =
SubresourceRedirectHintsAgent::RedirectResult::kIneligibleOtherImage;
+ // 503 response code indicates loadshed from the compression server. Notify
+ // the browser process which will bypass subresource redirect for subsequent
+ // page loads. Retry-After response header may mention the bypass duration,
+ // otherwise the browser will choose a random duration.
+ if (response_head.headers->response_code() == 503) {
+ std::string retry_after_string;
+ base::TimeDelta retry_after;
+ if (response_head.headers->EnumerateHeader(nullptr, "Retry-After",
+ &retry_after_string)) {
+ net::HttpUtil::ParseRetryAfterHeader(retry_after_string,
+ base::Time::Now(), &retry_after);
+ }
+ if (auto* resource_loading_hints_agent = GetResourceLoadingHintsAgent()) {
+ resource_loading_hints_agent->NotifyHttpsImageCompressionFetchFailed(
+ retry_after);
+ }
+ }
+
// Non 2XX responses from the compression server need to have unaltered
// requests sent to the original resource.
did_redirect_compressed_origin_ = false;
@@ -236,11 +283,25 @@ void SubresourceRedirectURLLoaderThrottle::WillOnCompleteWithError(
// If the server fails, restart the request to the original resource, and
// record it.
did_redirect_compressed_origin_ = false;
+ redirect_timeout_timer_.reset();
delegate_->RestartWithURLResetAndFlags(net::LOAD_NORMAL);
UMA_HISTOGRAM_BOOLEAN(
"SubresourceRedirect.CompressionAttempt.ServerResponded", false);
}
+void SubresourceRedirectURLLoaderThrottle::OnRedirectTimeout() {
+ DCHECK(did_redirect_compressed_origin_);
+ did_redirect_compressed_origin_ = false;
+ delegate_->RestartWithURLResetAndFlagsNow(net::LOAD_NORMAL);
+ if (auto* resource_loading_hints_agent = GetResourceLoadingHintsAgent()) {
+ resource_loading_hints_agent->NotifyHttpsImageCompressionFetchFailed(
+ base::TimeDelta());
+ resource_loading_hints_agent->subresource_redirect_hints_agent()
+ .ClearImageHints();
+ }
+ UMA_HISTOGRAM_BOOLEAN("SubresourceRedirect.CompressionFetchTimeout", true);
+}
+
void SubresourceRedirectURLLoaderThrottle::DetachFromCurrentSequence() {}
} // namespace subresource_redirect
diff --git a/chromium/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.h b/chromium/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.h
index 3c02b9595df..e5f8a1d0db6 100644
--- a/chromium/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.h
+++ b/chromium/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.h
@@ -6,6 +6,7 @@
#define CHROME_RENDERER_SUBRESOURCE_REDIRECT_SUBRESOURCE_REDIRECT_URL_LOADER_THROTTLE_H_
#include "base/macros.h"
+#include "base/timer/timer.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.h"
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
@@ -13,6 +14,10 @@ namespace blink {
class WebURLRequest;
} // namespace blink
+namespace previews {
+class ResourceLoadingHintsAgent;
+} // namespace previews
+
namespace subresource_redirect {
class SubresourceRedirectHintsAgent;
@@ -27,6 +32,8 @@ class SubresourceRedirectURLLoaderThrottle : public blink::URLLoaderThrottle {
~SubresourceRedirectURLLoaderThrottle() override;
+ previews::ResourceLoadingHintsAgent* GetResourceLoadingHintsAgent();
+
// virtual for testing.
virtual SubresourceRedirectHintsAgent* GetSubresourceRedirectHintsAgent();
@@ -58,6 +65,9 @@ class SubresourceRedirectURLLoaderThrottle : public blink::URLLoaderThrottle {
SubresourceRedirectURLLoaderThrottle(int render_frame_id,
bool allowed_to_redirect);
+ // Callback invoked when the redirect fetch times out.
+ void OnRedirectTimeout();
+
// Render frame id to get the hints agent of the render frame.
const int render_frame_id_;
@@ -72,6 +82,9 @@ class SubresourceRedirectURLLoaderThrottle : public blink::URLLoaderThrottle {
// itself is compressed origin.
bool did_redirect_compressed_origin_ = false;
+ // Timer to detect whether the response from compression server has timed out.
+ std::unique_ptr<base::OneShotTimer> redirect_timeout_timer_;
+
DISALLOW_COPY_AND_ASSIGN(SubresourceRedirectURLLoaderThrottle);
};
diff --git a/chromium/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle_unittest.cc b/chromium/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle_unittest.cc
index 8c476608f2f..7d4b7278a25 100644
--- a/chromium/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle_unittest.cc
+++ b/chromium/chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle_unittest.cc
@@ -5,6 +5,7 @@
#include "chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.h"
#include "base/test/scoped_feature_list.h"
+#include "base/test/task_environment.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_hints_agent.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_util.h"
#include "content/public/common/previews_state.h"
@@ -36,6 +37,7 @@ class TestSubresourceRedirectURLLoaderThrottle
}
private:
+ base::test::SingleThreadTaskEnvironment task_environment_;
SubresourceRedirectHintsAgent subresource_redirect_hints_agent_;
};
diff --git a/chromium/chrome/renderer/url_loader_throttle_provider_impl.cc b/chromium/chrome/renderer/url_loader_throttle_provider_impl.cc
index e7dc7dc02e2..8a4536d5f7c 100644
--- a/chromium/chrome/renderer/url_loader_throttle_provider_impl.cc
+++ b/chromium/chrome/renderer/url_loader_throttle_provider_impl.cc
@@ -16,6 +16,7 @@
#include "chrome/renderer/chrome_content_renderer_client.h"
#include "chrome/renderer/chrome_render_frame_observer.h"
#include "chrome/renderer/chrome_render_thread_observer.h"
+#include "chrome/renderer/lite_video/lite_video_url_loader_throttle.h"
#include "chrome/renderer/prerender/prerender_helper.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_params.h"
#include "chrome/renderer/subresource_redirect/subresource_redirect_url_loader_throttle.h"
@@ -200,6 +201,7 @@ URLLoaderThrottleProviderImpl::CreateThrottles(
throttles.push_back(std::make_unique<GoogleURLLoaderThrottle>(
#if defined(OS_ANDROID)
client_data_header,
+ /* night_mode_enabled= */ false,
#endif
ChromeRenderThreadObserver::GetDynamicParams()));
@@ -214,6 +216,13 @@ URLLoaderThrottleProviderImpl::CreateThrottles(
if (throttle)
throttles.push_back(std::move(throttle));
+ if (render_frame_id != MSG_ROUTING_NONE) {
+ auto throttle = lite_video::LiteVideoURLLoaderThrottle::MaybeCreateThrottle(
+ request, render_frame_id);
+ if (throttle)
+ throttles.push_back(std::move(throttle));
+ }
+
return throttles;
}