diff --git a/BUILD.gn b/BUILD.gn index 6e48a19..edeb047 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -1184,10 +1184,7 @@ ] } if (enable_ipc_fuzzer && !is_component_build) { - deps += [ - "//chrome/app:service_manifests", - "//tools/ipc_fuzzer:ipc_fuzzer_all", - ] + deps += [ "//tools/ipc_fuzzer:ipc_fuzzer_all" ] } if (!is_chromeos) { deps += [
diff --git a/DEPS b/DEPS index 8d30236..455c8e7b 100644 --- a/DEPS +++ b/DEPS
@@ -121,11 +121,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '2a0967383087e8753246e0cfc95f90bc8eed0059', + 'skia_revision': 'f16825ed3c715131489ed574ddd40533e7f0277f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': 'cdef3415a2805f926e6da2d5da25da678867c821', + 'v8_revision': 'f6f84c97a6497408eedc6e4fa6877c9239d5c473', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -133,7 +133,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '52f5da43184e62123d9327e2b4ebf4cc67a6a96f', + 'angle_revision': '8441286093152097eda821869d2743a85759ff7b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -145,7 +145,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. - 'pdfium_revision': '25bc9a92b33868ebc8ca333935da8af837e1266d', + 'pdfium_revision': '92770e8072cd3a38597966116045147c78b5a359', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling openmax_dl # and whatever else without interference from each other. @@ -181,7 +181,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '442e7b2731071e114fd7382afdcd6d5dc1248795', + 'catapult_revision': '7c1d51b169edfb62a3e2f88730f1182240cfe981', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -245,7 +245,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '300eec0f82c3c086e2c472d157594dff8fa81feb', + 'dawn_revision': 'cb71ba7b3a42849b5e15794426cb9fe55cba8b13', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -679,7 +679,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '89e50af847ea000405fae5955f4f8399af20d784', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '2c70338572204ba8c265f015b3097d1e60a699c1', 'condition': 'checkout_linux', }, @@ -826,7 +826,7 @@ }, 'src/third_party/arcore-android-sdk/src': { - 'url': Var('chromium_git') + '/external/github.com/google-ar/arcore-android-sdk.git' + '@' + '25b4589b55c02344cee5fd5722b06202c8b8776d', + 'url': Var('chromium_git') + '/external/github.com/google-ar/arcore-android-sdk.git' + '@' + '772bed8e2e1bc525a0d10441fa71168a9a87eb69', 'condition': 'checkout_android', }, @@ -1199,7 +1199,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'a2b35635aaef3e9301d69f77f9a0a3fd99291b08', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'd375f1c8d19f64cdeb64dd38d94316586efa4cac', + Var('webrtc_git') + '/src.git' + '@' + '35a9c6df44461580966b6f6d725db493ff764bce', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1230,7 +1230,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@896defe03d0b160467ff8392ee2ab4fef27abd6d', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@ff16c5b02fa501739c85ae01e5b8a931b08def76', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/system_webview_apk_tmpl.gni b/android_webview/system_webview_apk_tmpl.gni index c848ea3..84c47e0 100644 --- a/android_webview/system_webview_apk_tmpl.gni +++ b/android_webview/system_webview_apk_tmpl.gni
@@ -31,7 +31,10 @@ shared_resources = true - if (!defined(use_trichrome_library) || !use_trichrome_library) { + _use_trichrome_library = + defined(use_trichrome_library) && use_trichrome_library + + if (!_use_trichrome_library) { shared_libraries = [ "//android_webview:libwebviewchromium" ] if (build_apk_secondary_abi && android_64bit_target_cpu) { secondary_abi_shared_libraries = [ "//android_webview:libwebviewchromium($android_secondary_abi_toolchain)" ] @@ -64,8 +67,7 @@ } } - if (!defined(use_trichrome_library) || !use_trichrome_library || - android_64bit_target_cpu) { + if (!_use_trichrome_library || android_64bit_target_cpu) { # 32-bit TrichromeWebView doesn't have a native library, so only do this # for other configs. native_lib_version_rule = "//build/util:chrome_version_json" @@ -74,9 +76,6 @@ native_lib_version_arg = "@FileArg($_native_lib_file:full-quoted)" } - if (!defined(version_name)) { - version_name = chrome_version_name - } aapt_locale_whitelist = locales resource_blacklist_regex = "[/-]xxxhdpi[/-]" @@ -112,5 +111,16 @@ png_to_webp = true } command_line_flags_file = "webview-command-line" + + if (!defined(version_code)) { + if (_use_trichrome_library) { + version_code = trichrome_version_code + } else { + version_code = webview_version_code + } + } + if (!defined(version_name)) { + version_name = chrome_version_name + } } }
diff --git a/android_webview/tools/apk_merger.py b/android_webview/tools/apk_merger.py index 14ef0d6d..c23187a6 100755 --- a/android_webview/tools/apk_merger.py +++ b/android_webview/tools/apk_merger.py
@@ -121,7 +121,7 @@ # TODO(crbug.com/839191): Remove this once we're plumbing the lib correctly. missing_file_set = set( f for f in missing_file_set if not os.path.basename(f) == - 'libarcore_sdk_c.so') + 'libarcore_sdk_c_minimal.so') errors = [] if unexpected_file_set: @@ -189,7 +189,7 @@ # TODO(crbug.com/839191): we should pass this in via script arguments. if not args.loadable_module_32: - args.loadable_module_32.append('libarcore_sdk_c.so') + args.loadable_module_32.append('libarcore_sdk_c_minimal.so') for f in args.loadable_module_32: expected_files[f] = not args.uncompress_shared_libraries
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 01a39a8..a877e3396 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -1772,8 +1772,8 @@ <message name="IDS_ASSISTANT_TIMER_NOTIFICATION_TITLE" desc="Title for Assistant timer notification."> Time's up </message> - <message name="IDS_ASSISTANT_TIMER_NOTIFICATION_CONTENT" desc="Content for Assistant timer notification."> - 00:00s + <message name="IDS_ASSISTANT_TIMER_NOTIFICATION_MESSAGE" desc="Message for Assistant timer notification. Example: -01:23s. [ICU Syntax]"> + <ph name="SIGN">{0}<ex>-</ex></ph><ph name="MINUTES_REMAINING">{1,number,00}<ex>01</ex></ph>:<ph name="SECONDS_REMAINING">{2,number,00}<ex>02</ex></ph>s </message> <message name="IDS_ASSISTANT_TIMER_NOTIFICATION_ADD_1_MIN_BUTTON" desc="Label for button to add 1 minute to timer in Assistant timer notification."> Add 1 min
diff --git a/ash/assistant/assistant_alarm_timer_controller.cc b/ash/assistant/assistant_alarm_timer_controller.cc index f014d18f..7f5cde3 100644 --- a/ash/assistant/assistant_alarm_timer_controller.cc +++ b/ash/assistant/assistant_alarm_timer_controller.cc
@@ -8,6 +8,8 @@ #include "ash/assistant/assistant_notification_controller.h" #include "ash/assistant/util/deep_link_util.h" #include "ash/strings/grit/ash_strings.h" +#include "base/i18n/message_formatter.h" +#include "base/strings/utf_string_conversions.h" #include "chromeos/services/assistant/public/features.h" #include "chromeos/services/assistant/public/mojom/assistant.mojom.h" #include "ui/base/l10n/l10n_util.h" @@ -22,8 +24,64 @@ // Interval at which alarms/timers are ticked. constexpr base::TimeDelta kTickInterval = base::TimeDelta::FromSeconds(1); +// Helpers --------------------------------------------------------------------- + +std::string CreateTimerNotificationMessage(const AlarmTimer& alarm_timer, + base::TimeDelta time_remaining) { + const int minutes_remaining = time_remaining.InMinutes(); + const int seconds_remaining = + (time_remaining - base::TimeDelta::FromMinutes(minutes_remaining)) + .InSeconds(); + return base::UTF16ToUTF8(base::i18n::MessageFormatter::FormatWithNumberedArgs( + l10n_util::GetStringUTF16(IDS_ASSISTANT_TIMER_NOTIFICATION_MESSAGE), + alarm_timer.expired() ? "-" : "", minutes_remaining, seconds_remaining)); +} + +// TODO(llin): Migrate to use the AlarmManager API to better support multiple +// timers when the API is available. +chromeos::assistant::mojom::AssistantNotificationPtr CreateTimerNotification( + const AlarmTimer& alarm_timer, + base::TimeDelta time_remaining) { + using chromeos::assistant::mojom::AssistantNotification; + using chromeos::assistant::mojom::AssistantNotificationButton; + using chromeos::assistant::mojom::AssistantNotificationPtr; + + const std::string title = + l10n_util::GetStringUTF8(IDS_ASSISTANT_TIMER_NOTIFICATION_TITLE); + const std::string message = + CreateTimerNotificationMessage(alarm_timer, time_remaining); + const GURL action_url = assistant::util::CreateAssistantQueryDeepLink( + l10n_util::GetStringUTF8(IDS_ASSISTANT_TIMER_NOTIFICATION_STOP_QUERY)); + + AssistantNotificationPtr notification = AssistantNotification::New(); + + notification->title = title; + notification->message = message; + notification->action_url = action_url; + notification->client_id = alarm_timer.id; + notification->grouping_key = kTimerNotificationGroupingKey; + + // "STOP" button. + notification->buttons.push_back(AssistantNotificationButton::New( + l10n_util::GetStringUTF8(IDS_ASSISTANT_TIMER_NOTIFICATION_STOP_BUTTON), + action_url)); + + // "ADD 1 MIN" button. + notification->buttons.push_back( + chromeos::assistant::mojom::AssistantNotificationButton::New( + l10n_util::GetStringUTF8( + IDS_ASSISTANT_TIMER_NOTIFICATION_ADD_1_MIN_BUTTON), + assistant::util::CreateAssistantQueryDeepLink( + l10n_util::GetStringUTF8( + IDS_ASSISTANT_TIMER_NOTIFICATION_ADD_1_MIN_QUERY)))); + + return notification; +} + } // namespace +// AssistantAlarmTimerController ----------------------------------------------- + AssistantAlarmTimerController::AssistantAlarmTimerController( AssistantController* assistant_controller) : assistant_controller_(assistant_controller), binding_(this) { @@ -70,55 +128,48 @@ const AlarmTimer& alarm_timer, const base::TimeDelta& time_remaining) { // Schedule a repeating timer to tick the tracked alarms/timers. - if (!timer_.IsRunning()) { + if (chromeos::assistant::features::IsTimerTicksEnabled() && + !timer_.IsRunning()) { timer_.Start(FROM_HERE, kTickInterval, &model_, &AssistantAlarmTimerModel::Tick); } - const std::string title = - l10n_util::GetStringUTF8(IDS_ASSISTANT_TIMER_NOTIFICATION_TITLE); - const std::string message = - l10n_util::GetStringUTF8(IDS_ASSISTANT_TIMER_NOTIFICATION_CONTENT); - const GURL action_url = assistant::util::CreateAssistantQueryDeepLink( - l10n_util::GetStringUTF8(IDS_ASSISTANT_TIMER_NOTIFICATION_STOP_QUERY)); - - chromeos::assistant::mojom::AssistantNotificationPtr notification = - chromeos::assistant::mojom::AssistantNotification::New(); - - notification->title = title; - notification->message = message; - notification->action_url = action_url; - notification->client_id = alarm_timer.id; - notification->grouping_key = kTimerNotificationGroupingKey; - - // "STOP" button. - notification->buttons.push_back( - chromeos::assistant::mojom::AssistantNotificationButton::New( - l10n_util::GetStringUTF8( - IDS_ASSISTANT_TIMER_NOTIFICATION_STOP_BUTTON), - action_url)); - - // "ADD 1 MIN" button. - notification->buttons.push_back( - chromeos::assistant::mojom::AssistantNotificationButton::New( - l10n_util::GetStringUTF8( - IDS_ASSISTANT_TIMER_NOTIFICATION_ADD_1_MIN_BUTTON), - assistant::util::CreateAssistantQueryDeepLink( - l10n_util::GetStringUTF8( - IDS_ASSISTANT_TIMER_NOTIFICATION_ADD_1_MIN_QUERY)))); - + // Create a notification for the added alarm/timer. DCHECK(chromeos::assistant::features::IsTimerNotificationEnabled()); - assistant_controller_->notification_controller()->AddNotification( - std::move(notification)); + if (chromeos::assistant::features::IsTimerNotificationEnabled()) { + assistant_controller_->notification_controller()->AddOrUpdateNotification( + CreateTimerNotification(alarm_timer, time_remaining)); + } +} + +void AssistantAlarmTimerController::OnAlarmsTimersTicked( + const std::map<std::string, base::TimeDelta>& times_remaining) { + // This code should only be called when timer notifications/ticks are enabled. + DCHECK(chromeos::assistant::features::IsTimerNotificationEnabled()); + DCHECK(chromeos::assistant::features::IsTimerTicksEnabled()); + + // Update any existing notifications associated w/ our alarms/timers. + for (auto& pair : times_remaining) { + auto* notification_controller = + assistant_controller_->notification_controller(); + if (notification_controller->model()->HasNotificationForId(pair.first)) { + notification_controller->AddOrUpdateNotification(CreateTimerNotification( + *model_.GetAlarmTimerById(pair.first), pair.second)); + } + } } void AssistantAlarmTimerController::OnAllAlarmsTimersRemoved() { - timer_.Stop(); + if (chromeos::assistant::features::IsTimerTicksEnabled()) + timer_.Stop(); + // Remove any notifications associated w/ alarms/timers. DCHECK(chromeos::assistant::features::IsTimerNotificationEnabled()); - assistant_controller_->notification_controller() - ->RemoveNotificationByGroupingKey(kTimerNotificationGroupingKey, - /*from_server=*/false); + if (chromeos::assistant::features::IsTimerNotificationEnabled()) { + assistant_controller_->notification_controller() + ->RemoveNotificationByGroupingKey(kTimerNotificationGroupingKey, + /*from_server=*/false); + } } } // namespace ash
diff --git a/ash/assistant/assistant_alarm_timer_controller.h b/ash/assistant/assistant_alarm_timer_controller.h index abe601c..ac3a1b7 100644 --- a/ash/assistant/assistant_alarm_timer_controller.h +++ b/ash/assistant/assistant_alarm_timer_controller.h
@@ -42,6 +42,8 @@ // AssistantAlarmTimerModelObserver: void OnAlarmTimerAdded(const AlarmTimer& alarm_timer, const base::TimeDelta& time_remaining) override; + void OnAlarmsTimersTicked( + const std::map<std::string, base::TimeDelta>& times_remaining) override; void OnAllAlarmsTimersRemoved() override; private:
diff --git a/ash/assistant/assistant_notification_controller.cc b/ash/assistant/assistant_notification_controller.cc index c8bca90..489e1e7 100644 --- a/ash/assistant/assistant_notification_controller.cc +++ b/ash/assistant/assistant_notification_controller.cc
@@ -27,6 +27,32 @@ // Helpers --------------------------------------------------------------------- +std::unique_ptr<message_center::Notification> CreateSystemNotification( + const message_center::NotifierId& notifier_id, + const chromeos::assistant::mojom::AssistantNotification* notification) { + const base::string16 title = base::UTF8ToUTF16(notification->title); + const base::string16 message = base::UTF8ToUTF16(notification->message); + const base::string16 display_source = + l10n_util::GetStringUTF16(IDS_ASH_ASSISTANT_NOTIFICATION_DISPLAY_SOURCE); + + message_center::RichNotificationData data; + for (const auto& button : notification->buttons) { + data.buttons.push_back( + message_center::ButtonInfo(base::UTF8ToUTF16(button->label))); + } + + std::unique_ptr<message_center::Notification> system_notification = + ash::CreateSystemNotification( + message_center::NOTIFICATION_TYPE_SIMPLE, notification->client_id, + title, message, display_source, GURL(), notifier_id, data, + /*delegate=*/nullptr, kNotificationAssistantIcon, + message_center::SystemNotificationWarningLevel::NORMAL); + + system_notification->set_priority(message_center::DEFAULT_PRIORITY); + + return system_notification; +} + message_center::NotifierId GetNotifierId() { return message_center::NotifierId( message_center::NotifierType::SYSTEM_COMPONENT, kNotifierId); @@ -77,9 +103,9 @@ // mojom::AssistantNotificationController -------------------------------------- -void AssistantNotificationController::AddNotification( +void AssistantNotificationController::AddOrUpdateNotification( AssistantNotificationPtr notification) { - model_.AddNotification(std::move(notification)); + model_.AddOrUpdateNotification(std::move(notification)); } void AssistantNotificationController::RemoveNotificationById( @@ -102,35 +128,23 @@ void AssistantNotificationController::OnNotificationAdded( const AssistantNotification* notification) { - DCHECK(assistant_); - - // Do not show system notification if the setting is false. + // Do not show system notifications if the setting is disabled. if (!Shell::Get()->voice_interaction_controller()->notification_enabled()) return; - // Create the specified system |notification|. - const base::string16 title = base::UTF8ToUTF16(notification->title); - const base::string16 message = base::UTF8ToUTF16(notification->message); - const base::string16 display_source = - l10n_util::GetStringUTF16(IDS_ASH_ASSISTANT_NOTIFICATION_DISPLAY_SOURCE); - - message_center::RichNotificationData data; - for (const auto& button : notification->buttons) { - data.buttons.push_back( - message_center::ButtonInfo(base::UTF8ToUTF16(button->label))); - } - - std::unique_ptr<message_center::Notification> system_notification = - ash::CreateSystemNotification( - message_center::NOTIFICATION_TYPE_SIMPLE, notification->client_id, - title, message, display_source, GURL(), notifier_id_, data, - /*delegate=*/nullptr, kNotificationAssistantIcon, - message_center::SystemNotificationWarningLevel::NORMAL); - - system_notification->set_priority(message_center::DEFAULT_PRIORITY); - message_center::MessageCenter::Get()->AddNotification( - std::move(system_notification)); + CreateSystemNotification(notifier_id_, notification)); +} + +void AssistantNotificationController::OnNotificationUpdated( + const AssistantNotification* notification) { + // Do not show system notifications if the setting is disabled. + if (!Shell::Get()->voice_interaction_controller()->notification_enabled()) + return; + + message_center::MessageCenter::Get()->UpdateNotification( + notification->client_id, + CreateSystemNotification(notifier_id_, notification)); } void AssistantNotificationController::OnNotificationRemoved(
diff --git a/ash/assistant/assistant_notification_controller.h b/ash/assistant/assistant_notification_controller.h index dad592ff..69cf45a7 100644 --- a/ash/assistant/assistant_notification_controller.h +++ b/ash/assistant/assistant_notification_controller.h
@@ -49,7 +49,7 @@ void SetAssistant(chromeos::assistant::mojom::Assistant* assistant); // mojom::AssistantNotificationController: - void AddNotification(AssistantNotificationPtr notification) override; + void AddOrUpdateNotification(AssistantNotificationPtr notification) override; void RemoveNotificationById(const std::string& id, bool from_server) override; void RemoveNotificationByGroupingKey(const std::string& grouping_id, bool from_server) override; @@ -57,6 +57,8 @@ // AssistantNotificationModelObserver: void OnNotificationAdded(const AssistantNotification* notification) override; + void OnNotificationUpdated( + const AssistantNotification* notification) override; void OnNotificationRemoved(const AssistantNotification* notification, bool from_server) override; void OnAllNotificationsRemoved(bool from_server) override; @@ -67,6 +69,7 @@ const std::string& id, const base::Optional<int>& button_index, const base::Optional<base::string16>& reply) override; + void OnNotificationUpdated(const std::string& notification) override {} void OnNotificationRemoved(const std::string& notification_id, bool by_user) override;
diff --git a/ash/assistant/model/assistant_alarm_timer_model.cc b/ash/assistant/model/assistant_alarm_timer_model.cc index bfa6403..00efbd92 100644 --- a/ash/assistant/model/assistant_alarm_timer_model.cc +++ b/ash/assistant/model/assistant_alarm_timer_model.cc
@@ -38,6 +38,12 @@ NotifyAllAlarmsTimersRemoved(); } +const AlarmTimer* AssistantAlarmTimerModel::GetAlarmTimerById( + const std::string& id) const { + auto it = alarms_timers_.find(id); + return it != alarms_timers_.end() ? &it->second : nullptr; +} + void AssistantAlarmTimerModel::Tick() { const base::TimeTicks now = base::TimeTicks::Now();
diff --git a/ash/assistant/model/assistant_alarm_timer_model.h b/ash/assistant/model/assistant_alarm_timer_model.h index bf2e064..1ee7cb8 100644 --- a/ash/assistant/model/assistant_alarm_timer_model.h +++ b/ash/assistant/model/assistant_alarm_timer_model.h
@@ -24,6 +24,9 @@ std::string id; AlarmTimerType type; base::TimeTicks end_time; + + // Returns true if this alarm/timer has expired. + bool expired() const { return base::TimeTicks::Now() >= end_time; } }; // The model belonging to AssistantAlarmTimerController which tracks alarm/timer @@ -43,6 +46,9 @@ // Remove all alarms/timers from the model. void RemoveAllAlarmsTimers(); + // Returns the alarm/timer uniquely identified by |id|. + const AlarmTimer* GetAlarmTimerById(const std::string& id) const; + // Invoke to tick any alarms/timers and to notify observers of time remaining. void Tick();
diff --git a/ash/assistant/model/assistant_notification_model.cc b/ash/assistant/model/assistant_notification_model.cc index 9bc1d3d6..eae1924 100644 --- a/ash/assistant/model/assistant_notification_model.cc +++ b/ash/assistant/model/assistant_notification_model.cc
@@ -23,15 +23,19 @@ observers_.RemoveObserver(observer); } -void AssistantNotificationModel::AddNotification( +void AssistantNotificationModel::AddOrUpdateNotification( AssistantNotificationPtr notification) { AssistantNotification* ptr = notification.get(); DCHECK(!ptr->client_id.empty()); - DCHECK(!base::ContainsKey(notifications_, ptr->client_id)); + bool is_update = HasNotificationForId(ptr->client_id); notifications_[ptr->client_id] = std::move(notification); - NotifyNotificationAdded(ptr); + + if (is_update) + NotifyNotificationUpdated(ptr); + else + NotifyNotificationAdded(ptr); } void AssistantNotificationModel::RemoveNotificationById(const std::string& id, @@ -74,12 +78,23 @@ return it != notifications_.end() ? it->second.get() : nullptr; } +bool AssistantNotificationModel::HasNotificationForId( + const std::string& id) const { + return base::ContainsKey(notifications_, id); +} + void AssistantNotificationModel::NotifyNotificationAdded( const AssistantNotification* notification) { for (auto& observer : observers_) observer.OnNotificationAdded(notification); } +void AssistantNotificationModel::NotifyNotificationUpdated( + const AssistantNotification* notification) { + for (auto& observer : observers_) + observer.OnNotificationUpdated(notification); +} + void AssistantNotificationModel::NotifyNotificationRemoved( const AssistantNotification* notification, bool from_server) {
diff --git a/ash/assistant/model/assistant_notification_model.h b/ash/assistant/model/assistant_notification_model.h index 06c21003..566f104f 100644 --- a/ash/assistant/model/assistant_notification_model.h +++ b/ash/assistant/model/assistant_notification_model.h
@@ -32,8 +32,10 @@ void AddObserver(AssistantNotificationModelObserver* observer); void RemoveObserver(AssistantNotificationModelObserver* observer); - // Adds the specified |notification| to the model. - void AddNotification(AssistantNotificationPtr notification); + // Adds or updates the specified |notification| in the model. If there is an + // existing notification with the same |client_id|, an update will occur. + // Otherwise a new notification will be added. + void AddOrUpdateNotification(AssistantNotificationPtr notification); // Removes the notification uniquely identified by |id|. If |from_server| is // true the request to remove was initiated by the server. @@ -51,8 +53,13 @@ // Returns the notification uniquely identified by |id|. const AssistantNotification* GetNotificationById(const std::string& id) const; + // Returns true if the model contains a notification uniquely identified by + // |id|, otherwise false. + bool HasNotificationForId(const std::string& id) const; + private: void NotifyNotificationAdded(const AssistantNotification* notification); + void NotifyNotificationUpdated(const AssistantNotification* notification); void NotifyNotificationRemoved(const AssistantNotification* notification, bool from_server); void NotifyAllNotificationsRemoved(bool from_server);
diff --git a/ash/assistant/model/assistant_notification_model_observer.h b/ash/assistant/model/assistant_notification_model_observer.h index a49a39b2..e98a11c 100644 --- a/ash/assistant/model/assistant_notification_model_observer.h +++ b/ash/assistant/model/assistant_notification_model_observer.h
@@ -27,6 +27,10 @@ // Invoked when the specified |notification| has been added. virtual void OnNotificationAdded(const AssistantNotification* notification) {} + // Invoked when the specified |notification| has been updated. + virtual void OnNotificationUpdated( + const AssistantNotification* notification) {} + // Invoked when the specified |notification| has been removed. If // |from_server| is true the request to remove was initiated by the server. virtual void OnNotificationRemoved(const AssistantNotification* notification,
diff --git a/ash/public/interfaces/assistant_controller.mojom b/ash/public/interfaces/assistant_controller.mojom index 47bef27..dba5eb9 100644 --- a/ash/public/interfaces/assistant_controller.mojom +++ b/ash/public/interfaces/assistant_controller.mojom
@@ -44,13 +44,14 @@ // AssistantController. Currently used by the Assistant service to modify // Assistant notification state in Ash in response to LibAssistant events. interface AssistantNotificationController { - // Requests that the specified |notification| be added. - AddNotification(chromeos.assistant.mojom.AssistantNotification notification); + // Requests that the specified |notification| be added or updated. If the + // |client_id| for |notification| matches that of an existing notification, + // an update will occur. Otherwise, a new notification will be added. + AddOrUpdateNotification( + chromeos.assistant.mojom.AssistantNotification notification); - // Requests that the notification uniquely identified by |id| be removed. - // Note that |id| refers to the notification's client id which may or may not - // be the same as its server id. If |from_server| is true the request to - // remove was initiated by the server. + // Requests that the notification uniquely identified by |id| be removed. If + // |from_server| is true the request to remove was initiated by the server. RemoveNotificationById(string id, bool from_server); // Requests that all notifications associated with the given |grouping_key|
diff --git a/base/threading/thread_restrictions.h b/base/threading/thread_restrictions.h index 33f359b..8f5b37e8 100644 --- a/base/threading/thread_restrictions.h +++ b/base/threading/thread_restrictions.h
@@ -234,6 +234,10 @@ class VrShell; } +namespace web { +class WebSubThread; +} + namespace webrtc { class DesktopConfigurationMonitor; } @@ -317,6 +321,7 @@ friend class mojo::CoreLibraryInitializer; friend class resource_coordinator::TabManagerDelegate; // crbug.com/778703 friend class ui::MaterialDesignController; + friend class web::WebSubThread; friend class StackSamplingProfiler; ScopedAllowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF;
diff --git a/build/android/gyp/assert_static_initializers.py b/build/android/gyp/assert_static_initializers.py index 717861b7..59ab6f49 100755 --- a/build/android/gyp/assert_static_initializers.py +++ b/build/android/gyp/assert_static_initializers.py
@@ -28,7 +28,7 @@ args = parser.parse_args() #TODO(crbug.com/838414): add support for files included via loadable_modules. - ignored_libs = ['libarcore_sdk_c.so'] + ignored_libs = ['libarcore_sdk_c_minimal.so'] si_count = resource_sizes.AnalyzeStaticInitializers( args.apk, args.tool_prefix, False, '.', ignored_libs)
diff --git a/build/config/android/chrome_version.gni b/build/config/android/chrome_version.gni index 1531bf2..966a9abc 100644 --- a/build/config/android/chrome_version.gni +++ b/build/config/android/chrome_version.gni
@@ -14,3 +14,51 @@ # builders (which currently set the version number with this GN arg). chrome_version_name = chrome_version_full } + +_version_code = chrome_version_id + +# The architecture preference is encoded into the version_code for devices +# that support multiple architectures +if (target_cpu == "arm") { + _arch_preference = 0 +} else if (target_cpu == "x86") { + _arch_preference = 10 +} else if (target_cpu == "mipsel") { + _arch_preference = 20 +} else if (target_cpu == "arm64") { + _arch_preference = 50 +} else if (target_cpu == "x64") { + _arch_preference = 60 +} else { + assert(false, "Error: Unrecognized target_cpu: " + target_cpu) +} +_version_code += _arch_preference + +if (!public_android_sdk) { + # Match downstream logic for next builds + _version_code += 5 +} + +webview_version_code = "$_version_code" +chrome_version_code = "$_version_code" + +_version_code += 1 +chrome_modern_version_code = "$_version_code" + +_version_code += 1 +monochrome_version_code = "$_version_code" + +_version_code += 1 +trichrome_version_code = "$_version_code" + +if (android_override_version_code != "") { + webview_version_code = android_override_version_code + chrome_version_code = android_override_version_code + chrome_modern_version_code = android_override_version_code + monochrome_version_code = android_override_version_code + trichrome_version_code = android_override_version_code +} + +if (android_override_version_name != "") { + chrome_version_name = android_override_version_name +}
diff --git a/build/config/android/config.gni b/build/config/android/config.gni index af4c3f5..7a02ba5 100644 --- a/build/config/android/config.gni +++ b/build/config/android/config.gni
@@ -159,6 +159,12 @@ # Android versionName for android_apk()s that don't explicitly set one. android_default_version_name = "Developer Build" + # Forced Android versionCode + android_override_version_code = "" + + # Forced Android versionName + android_override_version_name = "" + # The path to the keystore to use for signing builds. android_keystore_path = default_android_keystore_path
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni index 8789e9f..bcb3d717 100644 --- a/build/config/android/rules.gni +++ b/build/config/android/rules.gni
@@ -2006,14 +2006,20 @@ rebase_path(_final_apk_path_no_ext, root_build_dir) + ".ap_" } - _version_code = android_default_version_code - if (defined(invoker.version_code)) { + if (android_override_version_code != "") { + _version_code = android_override_version_code + } else if (defined(invoker.version_code)) { _version_code = invoker.version_code + } else { + _version_code = android_default_version_code } - _version_name = android_default_version_name - if (defined(invoker.version_name)) { + if (android_override_version_name != "") { + _version_name = android_override_version_name + } else if (defined(invoker.version_name)) { _version_name = invoker.version_name + } else { + _version_name = android_default_version_name } _deps = []
diff --git a/build/config/clang/BUILD.gn b/build/config/clang/BUILD.gn index 11dba35..522efa7 100644 --- a/build/config/clang/BUILD.gn +++ b/build/config/clang/BUILD.gn
@@ -35,21 +35,6 @@ "find-bad-constructs", ] - cflags += [ - "-Xclang", - "-plugin-arg-find-bad-constructs", - "-Xclang", - "enforce-in-thirdparty-webkit", - ] - - # TODO(dcheng): remove this once the plugin is updated and rolled again. - cflags += [ - "-Xclang", - "-plugin-arg-find-bad-constructs", - "-Xclang", - "check-enum-max-value", - ] - if (is_linux || is_android || is_fuchsia) { cflags += [ "-Xclang",
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 470de44..07d8efa 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn
@@ -126,7 +126,7 @@ # Turn this on to use ghash feature of lld for faster debug link on Windows. # http://blog.llvm.org/2018/01/improving-link-time-on-windows-with.html - use_ghash = true + use_ghash = false # Whether to enable ThinLTO optimizations. Turning ThinLTO optimizations on # can substantially increase link time and binary size, but they generally @@ -2230,7 +2230,10 @@ # it all. This flag is incompatible with /PROFILE ldflags = [ "/DEBUG:FASTLINK" ] } else if (is_clang && use_lld && use_ghash) { - cflags += [ "-gcodeview-ghash" ] + cflags += [ + "-mllvm", + "-emit-codeview-ghash-section", + ] ldflags = [ "/DEBUG:GHASH" ] } else { ldflags = [ "/DEBUG" ]
diff --git a/build/util/version.gni b/build/util/version.gni index 01e3807..189d109f1 100644 --- a/build/util/version.gni +++ b/build/util/version.gni
@@ -15,9 +15,11 @@ # Give version.py a pattern that will expand to a GN scope consisting of # all values we need at once. -_version_dictionary_template = "full = \"@MAJOR@.@MINOR@.@BUILD@.@PATCH@\" " + - "major = \"@MAJOR@\" minor = \"@MINOR@\" " + - "build = \"@BUILD@\" patch = \"@PATCH@\" " +_version_dictionary_template = + "full = \"@MAJOR@.@MINOR@.@BUILD@.@PATCH@\" " + + "major = \"@MAJOR@\" minor = \"@MINOR@\" " + + "build = \"@BUILD@\" patch = \"@PATCH@\" " + "version_id = @VERSION_ID@ " + + "patch_hi = @PATCH_HI@ " + "patch_lo = @PATCH_LO@ " # The file containing the Chrome version number. chrome_version_file = "//chrome/VERSION" @@ -28,6 +30,12 @@ rebase_path(chrome_version_file, root_build_dir), "-t", _version_dictionary_template, + "-e", + "VERSION_ID='%s%03d00' % (BUILD, int(PATCH))", + "-e", + "PATCH_HI=int(PATCH)/256", + "-e", + "PATCH_LO=int(PATCH)%256", ], "scope", [ chrome_version_file ]) @@ -40,20 +48,11 @@ chrome_version_minor = _result.minor chrome_version_build = _result.build chrome_version_patch = _result.patch +chrome_version_id = _result.version_id +chrome_version_patch_hi = _result.patch_hi +chrome_version_patch_lo = _result.patch_lo if (is_mac) { - _result = exec_script("version.py", - [ - "-f", - rebase_path(chrome_version_file, root_build_dir), - "-t", - "@BUILD@.@PATCH_HI@.@PATCH_LO@", - "-e", - "PATCH_HI=int(PATCH)/256", - "-e", - "PATCH_LO=int(PATCH)%256", - ], - "trim string", - [ chrome_version_file ]) - chrome_dylib_version = _result + chrome_dylib_version = "$chrome_version_build.$chrome_version_patch_hi" + + ".$chrome_version_patch_lo" }
diff --git a/cc/base/switches.cc b/cc/base/switches.cc index d363fe84b..22db5dd 100644 --- a/cc/base/switches.cc +++ b/cc/base/switches.cc
@@ -48,10 +48,6 @@ // Enables the GPU benchmarking extension const char kEnableGpuBenchmarking[] = "enable-gpu-benchmarking"; -// Always asks the display compositor to send back presentation times. -const char kAlwaysRequestPresentationTime[] = - "always-request-presentation-time"; - // Renders a border around compositor layers to help debug and study // layer compositing. const char kShowCompositedLayerBorders[] = "show-composited-layer-borders";
diff --git a/cc/base/switches.h b/cc/base/switches.h index fe8de281..cde4700 100644 --- a/cc/base/switches.h +++ b/cc/base/switches.h
@@ -29,7 +29,6 @@ // Switches for both the renderer and ui compositors. CC_BASE_EXPORT extern const char kEnableGpuBenchmarking[]; -CC_BASE_EXPORT extern const char kAlwaysRequestPresentationTime[]; // Debug visualizations. CC_BASE_EXPORT extern const char kShowCompositedLayerBorders[];
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index 3116354..7a34b6eb 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc
@@ -305,14 +305,11 @@ } sync_tree->set_source_frame_number(SourceFrameNumber()); - bool request_presentation_time = - settings_.always_request_presentation_time || - !pending_presentation_time_callbacks_.empty(); - if (request_presentation_time && pending_presentation_time_callbacks_.empty()) - pending_presentation_time_callbacks_.push_back(base::DoNothing()); - sync_tree->AddPresentationCallbacks( - std::move(pending_presentation_time_callbacks_)); - pending_presentation_time_callbacks_.clear(); + if (!pending_presentation_time_callbacks_.empty()) { + sync_tree->AddPresentationCallbacks( + std::move(pending_presentation_time_callbacks_)); + pending_presentation_time_callbacks_.clear(); + } if (needs_full_tree_sync_) TreeSynchronizer::SynchronizeTrees(root_layer(), sync_tree);
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index 93b6eb9..537d6a2b 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc
@@ -1928,9 +1928,7 @@ metadata.root_background_color = active_tree_->background_color(); metadata.content_source_id = active_tree_->content_source_id(); - metadata.request_presentation_feedback = true; - if (active_tree_->has_presentation_callbacks() || - settings_.always_request_presentation_time) { + if (active_tree_->has_presentation_callbacks()) { frame_token_infos_.emplace_back(metadata.frame_token, CurrentBeginFrameArgs().frame_time, active_tree_->TakePresentationCallbacks());
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index cf20f63..cde6927 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -7849,55 +7849,15 @@ }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPaintedDeviceScaleFactor); -// Makes sure that presentation-time requests are correctly propagated to the -// frame's metadata. -class LayerTreeHostTestPresentationTimeRequest : public LayerTreeHostTest { +// Tests that a presentation-timestamps are received for a frame. +class LayerTreeHostTestPresentationTime : public LayerTreeHostTest { protected: void BeginTest() override { - layer_tree_host()->RequestPresentationTimeForNextFrame(base::DoNothing()); PostSetNeedsCommitToMainThread(); } void DisplayReceivedCompositorFrameOnThread( const viz::CompositorFrame& frame) override { - EXPECT_TRUE(frame.metadata.request_presentation_feedback); - EndTest(); - } - - void AfterTest() override {} -}; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPresentationTimeRequest); - -// A SwapPromise that turns on |request_presentation_feedback| during -// WillSwap(). -class RequestPresentationFeedbackSwapPromise : public SwapPromise { - public: - RequestPresentationFeedbackSwapPromise() = default; - ~RequestPresentationFeedbackSwapPromise() override = default; - - // SwapPromise: - void DidActivate() override {} - void WillSwap(viz::CompositorFrameMetadata* metadata) override { - metadata->request_presentation_feedback = true; - } - void DidSwap() override {} - void DidNotSwap(DidNotSwapReason reason) override {} - int64_t TraceId() const override { return 0; } -}; - -// Tests that a presentation-token can be requested during swap. -class LayerTreeHostTestPresentationTimeRequestDuringSwap - : public LayerTreeHostTest { - protected: - void BeginTest() override { - layer_tree_host()->QueueSwapPromise( - std::make_unique<RequestPresentationFeedbackSwapPromise>()); - PostSetNeedsCommitToMainThread(); - } - - void DisplayReceivedCompositorFrameOnThread( - const viz::CompositorFrame& frame) override { - EXPECT_TRUE(frame.metadata.request_presentation_feedback); frame_token_ = frame.metadata.frame_token; } @@ -7914,8 +7874,7 @@ private: uint32_t frame_token_ = 0; }; -SINGLE_AND_MULTI_THREAD_TEST_F( - LayerTreeHostTestPresentationTimeRequestDuringSwap); +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPresentationTime); // Makes sure that viz::LocalSurfaceId is propagated to the LayerTreeFrameSink. class LayerTreeHostTestLocalSurfaceId : public LayerTreeHostTest {
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc index d50a4cc..dd854fb 100644 --- a/cc/trees/layer_tree_host_unittest_animation.cc +++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -1061,8 +1061,7 @@ void DisplayReceivedCompositorFrameOnThread( const viz::CompositorFrame& frame) override { - if (frame.metadata.request_presentation_feedback) - received_token_ = frame.metadata.frame_token; + received_token_ = frame.metadata.frame_token; } void AfterTest() override {
diff --git a/cc/trees/layer_tree_settings.h b/cc/trees/layer_tree_settings.h index 7f074dd9..9de6c5f5 100644 --- a/cc/trees/layer_tree_settings.h +++ b/cc/trees/layer_tree_settings.h
@@ -145,10 +145,6 @@ // Whether to use edge anti-aliasing for all layer types that supports it. bool enable_edge_anti_aliasing = true; - // Whether to request presentation time regardless if existence of - // presentation time callbacks. - bool always_request_presentation_time = false; - // Whether SetViewportSizeAndScale should update the painted scale factor or // the device scale factor. bool use_painted_device_scale_factor = false;
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index 2ff0f55..dcbe126 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -123,9 +123,6 @@ public_deps += [ ":reorder_imports" ] data_deps += [ ":reorder_imports" ] } - if (use_aura && (is_win || is_linux)) { - data_deps += [ "//chrome/app:service_manifests" ] - } if (is_chromeos) { data_deps += [ "//sandbox/linux:chrome_sandbox" ] } @@ -1228,13 +1225,9 @@ ] if (is_chrome_branded) { - framework_contents += [ - "Default Apps", - ] + framework_contents += [ "Default Apps" ] if (enable_keystone_registration_framework) { - framework_contents += [ - "Frameworks", # For KeystoneRegistration.framework. - ] + framework_contents += [ "Frameworks" ] # For KeystoneRegistration.framework. } }
diff --git a/chrome/VERSION b/chrome/VERSION index 8d2e027f..85d7f51 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=73 MINOR=0 -BUILD=3648 +BUILD=3650 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 51d36ede..4a1c252 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -1802,6 +1802,8 @@ manifest_package = manifest_package module_name = "ArPublic" base_module_target = ":monochrome_public_base_module" + version_code = monochrome_version_code + version_name = chrome_version_name } } @@ -1810,6 +1812,8 @@ manifest_package = manifest_package module_name = "VrPublic" base_module_target = ":chrome_modern_public_base_module" + version_code = chrome_modern_version_code + version_name = chrome_version_name } }
diff --git a/chrome/android/chrome_public_apk_tmpl.gni b/chrome/android/chrome_public_apk_tmpl.gni index fd2a07a..1a4685c 100644 --- a/chrome/android/chrome_public_apk_tmpl.gni +++ b/chrome/android/chrome_public_apk_tmpl.gni
@@ -4,6 +4,7 @@ import("//base/android/linker/config.gni") import("//base/android/proguard/proguard.gni") +import("//build/config/android/chrome_version.gni") import("//build/config/android/extract_unwind_tables.gni") import("//build/config/android/rules.gni") import("//build/config/compiler/compiler.gni") @@ -109,6 +110,10 @@ _is_monochrome = defined(invoker.is_monochrome) && invoker.is_monochrome + _use_trichrome_library = + defined(invoker.use_trichrome_library) && invoker.use_trichrome_library + assert(_use_trichrome_library || !_use_trichrome_library) # Mark as used. + if (defined(invoker.enable_multidex)) { _enable_multidex = invoker.enable_multidex } else { @@ -230,6 +235,19 @@ if (enable_vr && (_target_type == "android_apk" || !modularize_vr)) { deps += [ "//chrome/browser/android/vr:java" ] } + + if (!defined(version_code)) { + if (_use_trichrome_library) { + version_code = trichrome_version_code + } else if (_is_monochrome) { + version_code = monochrome_version_code + } else if (_is_modern) { + version_code = chrome_modern_version_code + } else { + # For chrome without the modern design, used on pre-L devices + version_code = chrome_version_code + } + } } } @@ -243,9 +261,10 @@ } chrome_public_common_apk_or_module_tmpl(target_name) { is_monochrome = true + use_trichrome_library = + defined(invoker.use_trichrome_library) && invoker.use_trichrome_library - if (!defined(invoker.use_trichrome_library) || - !invoker.use_trichrome_library) { + if (!use_trichrome_library) { if (invoker.target_type == "android_app_bundle_module") { _suffix = bundle_library_suffix } else { @@ -357,19 +376,19 @@ deps += [ "//chrome/browser/android/vr:java" ] } - if ((invoker.target_type == "android_apk" || !modularize_ar) && - package_arcore) { - deps += [ "//third_party/android_deps:com_google_ar_core_java" ] - - # We store this as a separate .so in the APK and only load as needed. - if (android_64bit_target_cpu) { - if (android_64bit_browser) { - loadable_modules = [ "$root_gen_dir/third_party/android_deps/com_google_ar_core_java/jni/arm64-v8a/libarcore_sdk_c.so" ] - } else if (build_apk_secondary_abi) { - secondary_abi_loadable_modules = [ "$root_gen_dir/third_party/android_deps/com_google_ar_core_java/jni/armeabi-v7a/libarcore_sdk_c.so" ] + if (invoker.target_type == "android_apk" || !modularize_ar) { + if (enable_arcore) { + deps += [ "//third_party/arcore-android-sdk:libdynamite_client_java" ] + } + if (package_arcore) { + # We store this as a separate .so in the APK and only load as needed. + if (android_64bit_target_cpu && build_apk_secondary_abi) { + secondary_abi_loadable_modules = [ "//third_party/arcore-android-sdk/libraries/android_arm/libarcore_sdk_c_minimal.so" ] + } else if (android_64bit_target_cpu && !build_apk_secondary_abi) { + loadable_modules = [ "//third_party/arcore-android-sdk/libraries/android_arm64/libarcore_sdk_c_minimal.so" ] + } else { + loadable_modules = [ "//third_party/arcore-android-sdk/libraries/android_arm/libarcore_sdk_c_minimal.so" ] } - } else { - loadable_modules = [ "$root_gen_dir/third_party/android_deps/com_google_ar_core_java/jni/armeabi-v7a/libarcore_sdk_c.so" ] } } }
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml index 6a0f1e6..17c4693 100644 --- a/chrome/android/java/AndroidManifest.xml +++ b/chrome/android/java/AndroidManifest.xml
@@ -169,10 +169,11 @@ <!-- ARCore APK integration --> <!-- This tag indicates that this application optionally uses ARCore. --> <meta-data android:name="com.google.ar.core" android:value="optional" /> - <!-- TODO(crbug.com/917406): We should pull this flag in from the ArCore AAR. It's added here - because it doesn't get added properly for bundle base modules. --> + <!-- This value referes to ARCore 1.1. + This value should be updated when ARCore features require + a newer version of the ARCore SDK. --> <meta-data android:name="com.google.ar.core.min_apk_version" - android:value="180815000"/> + android:value="180226000"/> {% endif %} <!-- Cast support -->
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr/ArCoreJavaUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/vr/ArCoreJavaUtils.java index aac33c1..593ff30 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr/ArCoreJavaUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr/ArCoreJavaUtils.java
@@ -90,7 +90,7 @@ private static String getArCoreShimLibraryPath() { try (StrictModeContext unused = StrictModeContext.allowDiskReads()) { return ((BaseDexClassLoader) ContextUtils.getApplicationContext().getClassLoader()) - .findLibrary("arcore_sdk_c"); + .findLibrary("arcore_sdk_c_minimal"); } } @@ -203,7 +203,6 @@ break; } - // TODO(https://crbug.com/916651) - use ARCore SDK's InstallActivity to install ARCore SimpleConfirmInfoBarBuilder.Listener listener = new SimpleConfirmInfoBarBuilder.Listener() { @Override public void onInfoBarDismissed() { @@ -229,7 +228,7 @@ private boolean shouldRequestInstallArModule() { try { // Try to find class in AR module that has not been obfuscated. - Class.forName("com.google.ar.core.ArCoreApk"); + Class.forName("com.google.vr.dynamite.client.UsedByNative"); return false; } catch (ClassNotFoundException e) { return true;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedSchedulerBridgeConformanceTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedSchedulerBridgeConformanceTest.java index 6e016d0..2b9581b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedSchedulerBridgeConformanceTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedSchedulerBridgeConformanceTest.java
@@ -4,8 +4,6 @@ package org.chromium.chrome.browser.feed; -import static org.mockito.Mockito.mock; - import android.support.test.filters.SmallTest; import android.support.test.rule.UiThreadTestRule; @@ -19,6 +17,7 @@ import org.junit.rules.RuleChain; import org.junit.runner.Description; import org.junit.runner.RunWith; +import org.mockito.Mock; import org.chromium.base.test.params.ParameterAnnotations.ClassParameter; import org.chromium.base.test.params.ParameterAnnotations.UseRunnerDelegate; @@ -57,6 +56,10 @@ } }); + @Mock + private RequestManager mRequestManager; + @Mock + private SessionManager mSessionManager; private boolean mUseRequestManager; public FeedSchedulerBridgeConformanceTest(boolean useRequestManager) { @@ -69,8 +72,7 @@ scheduler = new FeedSchedulerBridge(Profile.getLastUsedProfile()); if (mUseRequestManager) { ((FeedSchedulerBridge) scheduler) - .initializeFeedDependencies( - mock(RequestManager.class), mock(SessionManager.class)); + .initializeFeedDependencies(mRequestManager, mSessionManager); } }
diff --git a/chrome/android/modules/ar/ar_module_tmpl.gni b/chrome/android/modules/ar/ar_module_tmpl.gni index 9fae827..8c156b9 100644 --- a/chrome/android/modules/ar/ar_module_tmpl.gni +++ b/chrome/android/modules/ar/ar_module_tmpl.gni
@@ -30,27 +30,28 @@ "base_module_target", "module_name", "version_code", + "version_name", ]) android_manifest = _manifest android_manifest_dep = ":$_manifest_target" deps = [ - "//third_party/android_deps:com_google_ar_core_java", + "//third_party/arcore-android-sdk:libdynamite_client_java", ] # We only want to add the 32 bit arcore shim even for 64 bit monochrome # builds. AR is never used in 64 bit mode. We store the arcore shim as a # separate .so in the bundle module and only load as needed. if (android_64bit_target_cpu && build_apk_secondary_abi) { - secondary_abi_loadable_modules = [ "$root_gen_dir/third_party/android_deps/com_google_ar_core_java/jni/armeabi-v7a/libarcore_sdk_c.so" ] + secondary_abi_loadable_modules = [ "//third_party/arcore-android-sdk/libraries/android_arm/libarcore_sdk_c_minimal.so" ] # Disguise 32 bit library as 64 bit. This works around a Play Core bug where only 64 bit # libraries are extracted on 64 bit devices. # TODO(crbug.com/902859): Remove once bug is fixed. - loadable_modules = [ "$root_gen_dir/third_party/android_deps/com_google_ar_core_java/jni/armeabi-v7a/libarcore_sdk_c.so" ] + loadable_modules = [ "//third_party/arcore-android-sdk/libraries/android_arm/libarcore_sdk_c_minimal.so" ] } else if (android_64bit_target_cpu && !build_apk_secondary_abi) { - loadable_modules = [ "$root_gen_dir/third_party/android_deps/com_google_ar_core_java/jni/armeabi-v7a/libarcore_sdk_c.so" ] + loadable_modules = [ "//third_party/arcore-android-sdk/libraries/android_arm64/libarcore_sdk_c_minimal.so" ] } else { - loadable_modules = [ "$root_gen_dir/third_party/android_deps/com_google_ar_core_java/jni/armeabi-v7a/libarcore_sdk_c.so" ] + loadable_modules = [ "//third_party/arcore-android-sdk/libraries/android_arm/libarcore_sdk_c_minimal.so" ] } uncompress_shared_libraries = true
diff --git a/chrome/android/modules/vr/vr_module_tmpl.gni b/chrome/android/modules/vr/vr_module_tmpl.gni index 01596969..9ff046a 100644 --- a/chrome/android/modules/vr/vr_module_tmpl.gni +++ b/chrome/android/modules/vr/vr_module_tmpl.gni
@@ -31,6 +31,7 @@ "base_module_target", "module_name", "version_code", + "version_name", ]) android_manifest = _manifest android_manifest_dep = ":${_manifest_target}"
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index 8c90db5..8e1b7a2 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-73.0.3647.0_rc-r1.afdo.bz2 \ No newline at end of file +chromeos-chrome-amd64-73.0.3649.0_rc-r1.afdo.bz2 \ No newline at end of file
diff --git a/chrome/android/trichrome.gni b/chrome/android/trichrome.gni index 3b76a89..fe21a31b 100644 --- a/chrome/android/trichrome.gni +++ b/chrome/android/trichrome.gni
@@ -16,7 +16,7 @@ "min_sdk_version=28", "target_sdk_version=$android_sdk_version", "trichrome_library=$trichrome_library_package", - "trichrome_version=$android_default_version_code", + "trichrome_version=$trichrome_version_code", "trichrome_certdigest=$trichrome_certdigest", ] @@ -44,6 +44,7 @@ use_chromium_linker = false uncompress_shared_libraries = true version_name = chrome_version_name + version_code = trichrome_version_code # Only try to generate the native library version in configurations that # include a native library.
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn index 016b0ba2..39bd9e5c 100644 --- a/chrome/app/BUILD.gn +++ b/chrome/app/BUILD.gn
@@ -519,70 +519,3 @@ ":chrome_content_utility_manifest_overlay", ] } - -if (use_aura || enable_ipc_fuzzer) { - # NOTE: These rules generate compiled versions of the content service - # manifests with Chrome's overlays applied. These are only used at run-time, - # and only when running Chrome inside the Mash environment. In production - # Chrome, the content manifests and Chrome's overlays are baked into browser - # resources and merged at runtime. - - service_manifest("chrome_content_packaged_services_manifest") { - source_manifest = "//content/public/app:packaged_services_manifest" - overlays = [ ":chrome_content_packaged_services_manifest_overlay" ] - } - - service_manifest("chrome_content_browser_manifest") { - source_manifest = "//content/public/app:browser_manifest" - overlays = [ ":chrome_content_browser_manifest_overlay" ] - } - - service_manifest("chrome_test_browser_manifest") { - source_manifest = ":chrome_content_browser_manifest" - overlays = [ ":chrome_test_browser_overlay" ] - } - - service_manifest("chrome_content_gpu_manifest") { - source_manifest = "//content/public/app:gpu_manifest" - overlays = [ ":chrome_content_gpu_manifest_overlay" ] - } - - service_manifest("chrome_content_plugin_manifest") { - source_manifest = "//content/public/app:plugin_manifest" - overlays = [ ":chrome_content_plugin_manifest_overlay" ] - } - - service_manifest("chrome_content_renderer_manifest") { - source_manifest = "//content/public/app:renderer_manifest" - overlays = [ ":chrome_content_renderer_manifest_overlay" ] - } - - service_manifest("chrome_content_utility_manifest") { - source_manifest = "//content/public/app:utility_manifest" - overlays = [ ":chrome_content_utility_manifest_overlay" ] - } - - group("service_manifests") { - deps = [ - ":chrome_content_browser_manifest", - ":chrome_content_gpu_manifest", - ":chrome_content_plugin_manifest", - ":chrome_content_renderer_manifest", - ":chrome_content_utility_manifest", - ] - } - - chrome_embedded_services = [ - ":chrome_content_browser_manifest", - ":chrome_content_gpu_manifest", - ":chrome_content_plugin_manifest", - ":chrome_content_renderer_manifest", - ":chrome_content_utility_manifest", - ":chrome_renderer_manifest", - ] - - catalog("catalog") { - embedded_services = chrome_embedded_services + - [ ":chrome_content_packaged_services_manifest" ] - } -}
diff --git a/chrome/browser/android/vr/arcore_device/arcore.h b/chrome/browser/android/vr/arcore_device/arcore.h index cd57addb..9b0b0cf 100644 --- a/chrome/browser/android/vr/arcore_device/arcore.h +++ b/chrome/browser/android/vr/arcore_device/arcore.h
@@ -45,6 +45,7 @@ virtual bool RequestHitTest( const mojom::XRRayPtr& ray, + const gfx::Size& image_size, std::vector<mojom::XRHitResultPtr>* hit_results) = 0; virtual void Pause() = 0;
diff --git a/chrome/browser/android/vr/arcore_device/arcore_gl.cc b/chrome/browser/android/vr/arcore_device/arcore_gl.cc index 1f6a024..370b03a 100644 --- a/chrome/browser/android/vr/arcore_device/arcore_gl.cc +++ b/chrome/browser/android/vr/arcore_device/arcore_gl.cc
@@ -265,7 +265,8 @@ gl_thread_task_runner_->PostTask( FROM_HERE, base::BindOnce(&ArCoreGl::ProcessFrame, weak_ptr_factory_.GetWeakPtr(), - base::Passed(&frame_data), base::Passed(&callback))); + base::Passed(&frame_data), frame_size, + base::Passed(&callback))); } void ArCoreGl::RequestHitTest( @@ -283,6 +284,7 @@ void ArCoreGl::ProcessFrame( mojom::XRFrameDataPtr frame_data, + const gfx::Size& frame_size, mojom::XRFrameDataProvider::GetFrameDataCallback callback) { DCHECK(IsOnGlThread()); DCHECK(is_initialized_); @@ -302,7 +304,7 @@ // obvious how the timing between the results and the frame should go. for (auto& request : hit_test_requests_) { std::vector<mojom::XRHitResultPtr> results; - if (arcore_->RequestHitTest(request->ray, &results)) { + if (arcore_->RequestHitTest(request->ray, frame_size, &results)) { std::move(request->callback).Run(std::move(results)); } else { // Hit test failed, i.e. unprojected location was offscreen.
diff --git a/chrome/browser/android/vr/arcore_device/arcore_gl.h b/chrome/browser/android/vr/arcore_device/arcore_gl.h index e12f33a..1dd2d82 100644 --- a/chrome/browser/android/vr/arcore_device/arcore_gl.h +++ b/chrome/browser/android/vr/arcore_device/arcore_gl.h
@@ -67,7 +67,9 @@ base::WeakPtr<ArCoreGl> GetWeakPtr(); private: + // TODO(https://crbug/835948): remove frame_size. void ProcessFrame(mojom::XRFrameDataPtr frame_data, + const gfx::Size& frame_size, mojom::XRFrameDataProvider::GetFrameDataCallback callback); bool InitializeGl();
diff --git a/chrome/browser/android/vr/arcore_device/arcore_impl.cc b/chrome/browser/android/vr/arcore_device/arcore_impl.cc index 3fd89bd..9d9a1d3a 100644 --- a/chrome/browser/android/vr/arcore_device/arcore_impl.cc +++ b/chrome/browser/android/vr/arcore_device/arcore_impl.cc
@@ -62,6 +62,13 @@ return false; } + // We just use the default config. + status = ArSession_checkSupported(session.get(), arcore_config.get()); + if (status != AR_SUCCESS) { + DLOG(ERROR) << "ArSession_checkSupported failed: " << status; + return false; + } + status = ArSession_configure(session.get(), arcore_config.get()); if (status != AR_SUCCESS) { DLOG(ERROR) << "ArSession_configure failed: " << status; @@ -207,8 +214,10 @@ return result; } +// TODO(835948): remove image-size bool ArCoreImpl::RequestHitTest( const mojom::XRRayPtr& ray, + const gfx::Size& image_size, std::vector<mojom::XRHitResultPtr>* hit_results) { DCHECK(IsOnGlThread()); DCHECK(arcore_session_.is_valid()); @@ -225,14 +234,17 @@ return false; } + gfx::PointF screen_point; + if (!TransformRayToScreenSpace(ray, image_size, &screen_point)) { + return false; + } + // ArCore returns hit-results in sorted order, thus providing the guarantee // of sorted results promised by the WebXR spec for requestHitTest(). - float origin[3] = {ray->origin.x(), ray->origin.y(), ray->origin.z()}; - float direction[3] = {ray->direction.x(), ray->direction.y(), - ray->direction.z()}; - - ArFrame_hitTestRay(arcore_session_.get(), arcore_frame_.get(), origin, - direction, arcore_hit_result_list.get()); + ArFrame_hitTest(arcore_session_.get(), arcore_frame_.get(), + screen_point.x() * image_size.width(), + screen_point.y() * image_size.height(), + arcore_hit_result_list.get()); int arcore_hit_result_list_size = 0; ArHitResultList_getSize(arcore_session_.get(), arcore_hit_result_list.get(), @@ -310,6 +322,61 @@ return true; } +// TODO(835948): remove this method. +bool ArCoreImpl::TransformRayToScreenSpace(const mojom::XRRayPtr& ray, + const gfx::Size& image_size, + gfx::PointF* screen_point) { + DCHECK(IsOnGlThread()); + DCHECK(arcore_session_.is_valid()); + DCHECK(arcore_frame_.is_valid()); + + internal::ScopedArCoreObject<ArCamera*> arcore_camera; + ArFrame_acquireCamera( + arcore_session_.get(), arcore_frame_.get(), + internal::ScopedArCoreObject<ArCamera*>::Receiver(arcore_camera).get()); + DCHECK(arcore_camera.is_valid()) + << "ArFrame_acquireCamera failed despite documentation saying it cannot"; + + // Get the projection matrix. + float projection_matrix[16]; + ArCamera_getProjectionMatrix(arcore_session_.get(), arcore_camera.get(), 0.1, + 1000, projection_matrix); + SkMatrix44 projection44; + projection44.setColMajorf(projection_matrix); + gfx::Transform projection_transform(projection44); + + // Get the view matrix. + float view_matrix[16]; + ArCamera_getViewMatrix(arcore_session_.get(), arcore_camera.get(), + view_matrix); + SkMatrix44 view44; + view44.setColMajorf(view_matrix); + gfx::Transform view_transform(view44); + + // Create the combined matrix. + gfx::Transform proj_view_transform = projection_transform * view_transform; + + // Transform the ray into screen space. + gfx::Point3F screen_point_3d = ray->origin + ray->direction; + + proj_view_transform.TransformPoint(&screen_point_3d); + if (screen_point_3d.x() < -1 || screen_point_3d.x() > 1 || + screen_point_3d.y() < -1 || screen_point_3d.y() > 1) { + // The point does not project back into screen space, so this won't + // work with the screen-space-based hit-test API. + DLOG(ERROR) << "Invalid ray - does not originate from device screen."; + return false; + } + + screen_point->set_x((screen_point_3d.x() + 1) / 2); + // The calculated point in GL's normalized device coordinates (NDC) ranges + // from -1..1, with -1, -1 at the bottom left of the screen, +1 at the top. + // The output screen space coordinates range from 0..1, with 0, 0 at the + // top left. + screen_point->set_y((-screen_point_3d.y() + 1) / 2); + return true; +} + bool ArCoreImpl::IsOnGlThread() { return gl_thread_task_runner_->BelongsToCurrentThread(); }
diff --git a/chrome/browser/android/vr/arcore_device/arcore_impl.h b/chrome/browser/android/vr/arcore_device/arcore_impl.h index 344d7fa..2561e08 100644 --- a/chrome/browser/android/vr/arcore_device/arcore_impl.h +++ b/chrome/browser/android/vr/arcore_device/arcore_impl.h
@@ -82,9 +82,14 @@ void Pause() override; void Resume() override; bool RequestHitTest(const mojom::XRRayPtr& ray, + const gfx::Size& image_size, std::vector<mojom::XRHitResultPtr>* hit_results) override; private: + bool TransformRayToScreenSpace(const mojom::XRRayPtr& ray, + const gfx::Size& image_size, + gfx::PointF* screen_point); + bool IsOnGlThread(); base::WeakPtr<ArCoreImpl> GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr();
diff --git a/chrome/browser/android/vr/arcore_device/arcore_shim.cc b/chrome/browser/android/vr/arcore_device/arcore_shim.cc index 9b9fabff..76edce51 100644 --- a/chrome/browser/android/vr/arcore_device/arcore_shim.cc +++ b/chrome/browser/android/vr/arcore_device/arcore_shim.cc
@@ -22,7 +22,7 @@ CALL(ArFrame_acquireCamera) \ CALL(ArFrame_create) \ CALL(ArFrame_destroy) \ - CALL(ArFrame_hitTestRay) \ + CALL(ArFrame_hitTest) \ CALL(ArFrame_transformDisplayUvCoords) \ CALL(ArHitResult_create) \ CALL(ArHitResult_destroy) \ @@ -35,6 +35,7 @@ CALL(ArPose_destroy) \ CALL(ArPose_getMatrix) \ CALL(ArPose_getPoseRaw) \ + CALL(ArSession_checkSupported) \ CALL(ArSession_configure) \ CALL(ArSession_create) \ CALL(ArSession_destroy) \ @@ -78,13 +79,13 @@ if (!sdk_handle) { char* error_string = nullptr; error_string = dlerror(); - LOG(ERROR) << "Could not open libarcore_sdk_c.so: " << error_string; + LOG(ERROR) << "Could not open libarcore_sdk_c_minimal.so: " << error_string; return false; } else { VLOG(2) << "Opened shim shared library."; } - // TODO(https://crbug.com/914999): check SDK version. + // TODO(vollick): check SDK version. arcore_api = new ArCoreApi(); #define CALL(fn) LoadFunction(sdk_handle, #fn, &arcore_api->impl_##fn); @@ -152,13 +153,13 @@ arcore_api->impl_ArFrame_destroy(frame); } -void ArFrame_hitTestRay(const ArSession* session, - const ArFrame* frame, - const float* ray_origin_3, - const float* ray_direction_3, - ArHitResultList* out_hit_results) { - arcore_api->impl_ArFrame_hitTestRay(session, frame, ray_origin_3, - ray_direction_3, out_hit_results); +void ArFrame_hitTest(const ArSession* session, + const ArFrame* frame, + float pixel_x, + float pixel_y, + ArHitResultList* out_hit_results) { + arcore_api->impl_ArFrame_hitTest(session, frame, pixel_x, pixel_y, + out_hit_results); } void ArFrame_transformDisplayUvCoords(const ArSession* session, @@ -255,6 +256,11 @@ arcore_api->impl_ArPose_getPoseRaw(session, pose, out_pose_raw); } +ArStatus ArSession_checkSupported(const ArSession* session, + const ArConfig* config) { + return arcore_api->impl_ArSession_checkSupported(session, config); +} + ArStatus ArSession_configure(ArSession* session, const ArConfig* config) { return arcore_api->impl_ArSession_configure(session, config); }
diff --git a/chrome/browser/android/vr/arcore_device/fake_arcore.cc b/chrome/browser/android/vr/arcore_device/fake_arcore.cc index 1205748..b4bdfc19 100644 --- a/chrome/browser/android/vr/arcore_device/fake_arcore.cc +++ b/chrome/browser/android/vr/arcore_device/fake_arcore.cc
@@ -203,6 +203,7 @@ bool FakeArCore::RequestHitTest( const mojom::XRRayPtr& ray, + const gfx::Size& image_size, std::vector<mojom::XRHitResultPtr>* hit_results) { mojom::XRHitResultPtr hit = mojom::XRHitResult::New(); hit->hit_matrix.resize(16);
diff --git a/chrome/browser/android/vr/arcore_device/fake_arcore.h b/chrome/browser/android/vr/arcore_device/fake_arcore.h index 12b560d8..d78672a 100644 --- a/chrome/browser/android/vr/arcore_device/fake_arcore.h +++ b/chrome/browser/android/vr/arcore_device/fake_arcore.h
@@ -35,6 +35,7 @@ void Resume() override; bool RequestHitTest(const mojom::XRRayPtr& ray, + const gfx::Size& image_size, std::vector<mojom::XRHitResultPtr>* hit_results) override; void SetCameraAspect(float aspect) { camera_aspect_ = aspect; }
diff --git a/chrome/browser/apps/platform_apps/app_browsertest.cc b/chrome/browser/apps/platform_apps/app_browsertest.cc index d54bee5..14db9cd 100644 --- a/chrome/browser/apps/platform_apps/app_browsertest.cc +++ b/chrome/browser/apps/platform_apps/app_browsertest.cc
@@ -123,14 +123,14 @@ }; #if BUILDFLAG(ENABLE_PRINT_PREVIEW) -class ScopedPreviewTestingDelegate : PrintPreviewUI::TestingDelegate { +class ScopedPreviewTestingDelegate : printing::PrintPreviewUI::TestingDelegate { public: ScopedPreviewTestingDelegate() { - PrintPreviewUI::SetDelegateForTesting(this); + printing::PrintPreviewUI::SetDelegateForTesting(this); } ~ScopedPreviewTestingDelegate() { - PrintPreviewUI::SetDelegateForTesting(NULL); + printing::PrintPreviewUI::SetDelegateForTesting(NULL); } // PrintPreviewUI::TestingDelegate implementation.
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 83e0983..fdbf81e 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -105,6 +105,7 @@ #include "chrome/browser/safe_browsing/certificate_reporting_service.h" #include "chrome/browser/safe_browsing/certificate_reporting_service_factory.h" #include "chrome/browser/safe_browsing/chrome_password_protection_service.h" +#include "chrome/browser/safe_browsing/safe_browsing_navigation_throttle.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "chrome/browser/safe_browsing/ui_manager.h" #include "chrome/browser/safe_browsing/url_checker_delegate_impl.h" @@ -4238,6 +4239,11 @@ PreviewsLitePageDecider::MaybeCreateThrottleFor(handle); if (previews_lite_page_throttle) throttles.push_back(std::move(previews_lite_page_throttle)); + if (base::FeatureList::IsEnabled(safe_browsing::kCommittedSBInterstitials)) { + throttles.push_back( + std::make_unique<safe_browsing::SafeBrowsingNavigationThrottle>( + handle)); + } #if defined(OS_WIN) || defined(OS_MACOSX) || \ (defined(OS_LINUX) && !defined(OS_CHROMEOS))
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc index 2670ce4..443158fa 100644 --- a/chrome/browser/chromeos/login/chrome_restart_request.cc +++ b/chrome/browser/chromeos/login/chrome_restart_request.cc
@@ -178,7 +178,6 @@ // Please keep these in alphabetical order. Non-UI Compositor switches // here should also be added to // content/browser/renderer_host/render_process_host_impl.cc. - cc::switches::kAlwaysRequestPresentationTime, cc::switches::kCheckDamageEarly, cc::switches::kDisableCompositedAntialiasing, cc::switches::kDisableMainFrameBeforeActivation,
diff --git a/chrome/browser/devtools/devtools_file_watcher.cc b/chrome/browser/devtools/devtools_file_watcher.cc index 3ea1d41d6..559af7c 100644 --- a/chrome/browser/devtools/devtools_file_watcher.cc +++ b/chrome/browser/devtools/devtools_file_watcher.cc
@@ -8,6 +8,7 @@ #include <map> #include <memory> #include <set> +#include <unordered_map> #include "base/bind.h" #include "base/files/file_enumerator.h" @@ -42,9 +43,8 @@ DevToolsFileWatcher::SharedFileWatcher>; ~SharedFileWatcher(); - using FilePathTimesMap = std::map<base::FilePath, base::Time>; - void GetModificationTimes(const base::FilePath& path, - FilePathTimesMap* file_path_times); + using FilePathTimesMap = std::unordered_map<base::FilePath, base::Time>; + FilePathTimesMap GetModificationTimes(const base::FilePath& path); void DirectoryChanged(const base::FilePath& path, bool error); void DispatchNotifications(); @@ -99,25 +99,28 @@ if (!success) return; - GetModificationTimes(path, &file_path_times_[path]); + file_path_times_[path] = GetModificationTimes(path); } -void DevToolsFileWatcher::SharedFileWatcher::GetModificationTimes( - const base::FilePath& path, - FilePathTimesMap* times_map) { +DevToolsFileWatcher::SharedFileWatcher::FilePathTimesMap +DevToolsFileWatcher::SharedFileWatcher::GetModificationTimes( + const base::FilePath& path) { + FilePathTimesMap times_map; base::FileEnumerator enumerator(path, true, base::FileEnumerator::FILES); base::FilePath file_path = enumerator.Next(); while (!file_path.empty()) { base::FileEnumerator::FileInfo file_info = enumerator.GetInfo(); - (*times_map)[file_path] = file_info.GetLastModifiedTime(); + times_map[std::move(file_path)] = file_info.GetLastModifiedTime(); file_path = enumerator.Next(); } + return times_map; } void DevToolsFileWatcher::SharedFileWatcher::RemoveWatch( const base::FilePath& path) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); watchers_.erase(path); + file_path_times_.erase(path); } void DevToolsFileWatcher::SharedFileWatcher::DirectoryChanged( @@ -154,8 +157,7 @@ for (const auto& path : pending_paths_) { FilePathTimesMap& old_times = file_path_times_[path]; - FilePathTimesMap current_times; - GetModificationTimes(path, ¤t_times); + FilePathTimesMap current_times = GetModificationTimes(path); for (const auto& path_time : current_times) { const base::FilePath& path = path_time.first; auto old_timestamp = old_times.find(path);
diff --git a/chrome/browser/printing/print_preview_message_handler.h b/chrome/browser/printing/print_preview_message_handler.h index d5d9823..8b57c48 100644 --- a/chrome/browser/printing/print_preview_message_handler.h +++ b/chrome/browser/printing/print_preview_message_handler.h
@@ -13,7 +13,6 @@ #include "content/public/browser/web_contents_observer.h" #include "content/public/browser/web_contents_user_data.h" -class PrintPreviewUI; struct PrintHostMsg_DidPreviewDocument_Params; struct PrintHostMsg_DidPreviewPage_Params; struct PrintHostMsg_DidStartPreview_Params; @@ -36,6 +35,7 @@ namespace printing { +class PrintPreviewUI; struct PageSizeMargins; // Manages the print preview handling for a WebContents.
diff --git a/chrome/browser/resource_coordinator/tab_manager.cc b/chrome/browser/resource_coordinator/tab_manager.cc index 673928c..7cf3e07 100644 --- a/chrome/browser/resource_coordinator/tab_manager.cc +++ b/chrome/browser/resource_coordinator/tab_manager.cc
@@ -326,7 +326,7 @@ // Discard immediately without waiting for LogMemory() (https://crbug/850545). // Consider removing LogMemory() at all if nobody cares about the log. LogMemory("Tab Discards Memory details"); - PurgeMemoryAndDiscardTab(reason); + DiscardTab(reason); } void TabManager::LogMemory(const std::string& title) { @@ -397,13 +397,6 @@ // TabManager, private: // static -void TabManager::PurgeMemoryAndDiscardTab(LifecycleUnitDiscardReason reason) { - TabManager* manager = g_browser_process->GetTabManager(); - manager->PurgeBrowserMemory(); - manager->DiscardTab(reason); -} - -// static bool TabManager::IsInternalPage(const GURL& url) { // There are many chrome:// UI URLs, but only look for the ones that users // are likely to have open. Most of the benefit is the from NTP URL. @@ -420,20 +413,6 @@ return false; } -void TabManager::PurgeBrowserMemory() { - // Based on experimental evidence, attempts to free memory from renderers - // have been too slow to use in OOM situations (V8 garbage collection) or - // do not lead to persistent decreased usage (image/bitmap caches). This - // function therefore only targets large blocks of memory in the browser. - // Note that other objects will listen to MemoryPressureListener events - // to release memory. - for (auto* web_contents : AllTabContentses()) { - // Screenshots can consume ~5 MB per web contents for platforms that do - // touch back/forward. - web_contents->GetController().ClearAllScreenshots(); - } -} - // This function is called when |update_timer_| fires. It will adjust the clock // if needed (if it detects that the machine was asleep) and will fire the stats // updating on ChromeOS via the delegate. This function also tries to purge @@ -547,8 +526,6 @@ return; } NOTREACHED(); - // TODO(skuhne): If more memory pressure levels are introduced, consider - // calling PurgeBrowserMemory() before CRITICAL is reached. } void TabManager::OnActiveTabChanged(content::WebContents* old_contents,
diff --git a/chrome/browser/resource_coordinator/tab_manager.h b/chrome/browser/resource_coordinator/tab_manager.h index f562d3f1..b7bea32 100644 --- a/chrome/browser/resource_coordinator/tab_manager.h +++ b/chrome/browser/resource_coordinator/tab_manager.h
@@ -269,15 +269,10 @@ // min time to purge times this value. const int kDefaultMinMaxTimeToPurgeRatio = 4; - static void PurgeMemoryAndDiscardTab(LifecycleUnitDiscardReason reason); - // Returns true if the |url| represents an internal Chrome web UI page that // can be easily reloaded and hence makes a good choice to discard. static bool IsInternalPage(const GURL& url); - // Purges data structures in the browser that can be easily recomputed. - void PurgeBrowserMemory(); - // Callback for when |update_timer_| fires. Takes care of executing the tasks // that need to be run periodically (see comment in implementation). void UpdateTimerCallback();
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/set_as_default/nux_set_as_default.html b/chrome/browser/resources/welcome/onboarding_welcome/set_as_default/nux_set_as_default.html index 499f1cfb..08aed1e70 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/set_as_default/nux_set_as_default.html +++ b/chrome/browser/resources/welcome/onboarding_welcome/set_as_default/nux_set_as_default.html
@@ -77,7 +77,7 @@ <h2>$i18n{setDefaultSubHeader}</h2> <div class="illustration"></div> <div class="button-bar"> - <paper-button on-click="onDeclineClick_"> + <paper-button id="decline-button" on-click="onDeclineClick_"> $i18n{setDefaultSkip} </paper-button> <step-indicator model="[[indicatorModel]]"></step-indicator>
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/set_as_default/nux_set_as_default.js b/chrome/browser/resources/welcome/onboarding_welcome/set_as_default/nux_set_as_default.js index 68795f4..7e0c674 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/set_as_default/nux_set_as_default.js +++ b/chrome/browser/resources/welcome/onboarding_welcome/set_as_default/nux_set_as_default.js
@@ -60,7 +60,7 @@ onDeclineClick_: function() { if (this.finalized_) return; - this.finalized_ = true; + this.browserProxy_.recordSkip(); this.finished_(); }, @@ -69,7 +69,7 @@ onSetDefaultClick_: function() { if (this.finalized_) return; - this.finalized_ = true; + this.browserProxy_.recordBeginSetDefault(); this.browserProxy_.setAsDefault(); }, @@ -88,6 +88,8 @@ /** @private */ finished_: function() { + this.finalized_ = true; + welcome.navigateToNextStep(); }, });
diff --git a/chrome/browser/safe_browsing/BUILD.gn b/chrome/browser/safe_browsing/BUILD.gn index 1d1d47c..5fdc5156 100644 --- a/chrome/browser/safe_browsing/BUILD.gn +++ b/chrome/browser/safe_browsing/BUILD.gn
@@ -94,6 +94,8 @@ "safe_browsing_navigation_observer.h", "safe_browsing_navigation_observer_manager.cc", "safe_browsing_navigation_observer_manager.h", + "safe_browsing_navigation_throttle.cc", + "safe_browsing_navigation_throttle.h", "safe_browsing_service.cc", "safe_browsing_service.h", "services_delegate.h",
diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc index 2fbcf07..6ac4a14 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page_test.cc
@@ -13,6 +13,7 @@ #include "base/bind.h" #include "base/command_line.h" +#include "base/feature_list.h" #include "base/macros.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" @@ -52,6 +53,7 @@ #include "components/safe_browsing/renderer/threat_dom_details.h" #include "components/safe_browsing/web_ui/constants.h" #include "components/security_interstitials/content/security_interstitial_controller_client.h" +#include "components/security_interstitials/content/security_interstitial_tab_helper.h" #include "components/security_interstitials/core/controller_client.h" #include "components/security_interstitials/core/metrics_helper.h" #include "components/security_interstitials/core/urls.h" @@ -101,6 +103,10 @@ const char kMaliciousIframe[] = "/safe_browsing/malware_iframe.html"; const char kUnrelatedUrl[] = "https://www.google.com"; +bool AreCommittedMainFrameInterstitialsEnabled() { + return base::FeatureList::IsEnabled(kCommittedSBInterstitials); +} + // A SafeBrowsingDatabaseManager class that allows us to inject the malicious // URLs. class FakeSafeBrowsingDatabaseManager : public TestSafeBrowsingDatabaseManager { @@ -548,12 +554,19 @@ ASSERT_FALSE(contents->ShowingInterstitialPage()); } - bool YesInterstitial() { + bool IsShowingInterstitial() { WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); - InterstitialPage* interstitial_page = InterstitialPage::GetInterstitialPage( - contents); - return interstitial_page != NULL; + if (AreCommittedMainFrameInterstitialsEnabled()) { + security_interstitials::SecurityInterstitialTabHelper* helper = + security_interstitials::SecurityInterstitialTabHelper:: + FromWebContents(contents); + return helper && + (helper + ->GetBlockingPageForCurrentlyCommittedNavigationForTesting() != + nullptr); + } + return InterstitialPage::GetInterstitialPage(contents) != nullptr; } void SetReportSentCallback(const base::Closure& callback) { @@ -607,6 +620,11 @@ bool WaitForReady(Browser* browser) { WebContents* contents = browser->tab_strip_model()->GetActiveWebContents(); + if (AreCommittedMainFrameInterstitialsEnabled()) { + if (!content::WaitForRenderFrameReady(contents->GetMainFrame())) + return false; + return IsShowingInterstitial(); + } content::WaitForInterstitialAttach(contents); InterstitialPage* interstitial = contents->GetInterstitialPage(); if (!interstitial) @@ -840,7 +858,7 @@ MalwareRedirectCancelAndProceed("openWin"); // Clicking proceed won't do anything if the main request is cancelled // already. See crbug.com/76460. - EXPECT_TRUE(YesInterstitial()); + EXPECT_TRUE(IsShowingInterstitial()); } IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, HardcodedUrls) { @@ -917,7 +935,7 @@ EXPECT_EQ(0, browser()->tab_strip_model()->active_index()); EXPECT_EQ(interstitial_tab, browser()->tab_strip_model()->GetActiveWebContents()); - EXPECT_TRUE(YesInterstitial()); + EXPECT_TRUE(IsShowingInterstitial()); } IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, Proceed) { @@ -1272,7 +1290,7 @@ EXPECT_EQ(0, browser()->tab_strip_model()->active_index()); EXPECT_EQ(interstitial_tab, browser()->tab_strip_model()->GetActiveWebContents()); - EXPECT_TRUE(YesInterstitial()); + EXPECT_TRUE(IsShowingInterstitial()); } IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, @@ -1705,7 +1723,23 @@ base::RunLoop().RunUntilIdle(); WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); EXPECT_TRUE(content::WaitForRenderFrameReady(contents->GetMainFrame())); - EXPECT_FALSE(YesInterstitial()); + EXPECT_FALSE(IsShowingInterstitial()); +} + +// TODO(crbug.com/916683): Once interstitial bindings are hooked with committed +// interstitials, all other tests should run with committed interstitials +// enabled. At that point this test will become redundant and should be removed. +// Test that an main frame interstitial is displayed with committed +// interstitials enabled. +IN_PROC_BROWSER_TEST_P(SafeBrowsingBlockingPageBrowserTest, + CommittedInterstitialShows) { + base::test::ScopedFeatureList feature_list; + std::vector<base::Feature> enable; + enable.push_back(kCommittedSBInterstitials); + enable.push_back(kCheckByURLLoaderThrottle); + feature_list.InitWithFeatures(enable, std::vector<base::Feature>()); + SetupWarningAndNavigate(browser()); + EXPECT_TRUE(IsShowingInterstitial()); } INSTANTIATE_TEST_CASE_P(
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_throttle.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_throttle.cc new file mode 100644 index 0000000..850a5aa --- /dev/null +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_throttle.cc
@@ -0,0 +1,58 @@ +// Copyright 2018 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/browser/safe_browsing/safe_browsing_navigation_throttle.h" + +#include "chrome/browser/browser_process.h" +#include "chrome/browser/safe_browsing/safe_browsing_blocking_page.h" +#include "chrome/browser/safe_browsing/safe_browsing_service.h" +#include "chrome/browser/safe_browsing/ui_manager.h" +#include "components/security_interstitials/content/security_interstitial_tab_helper.h" +#include "components/security_interstitials/content/unsafe_resource.h" +#include "content/public/browser/navigation_handle.h" + +namespace safe_browsing { + +SafeBrowsingNavigationThrottle::SafeBrowsingNavigationThrottle( + content::NavigationHandle* handle) + : content::NavigationThrottle(handle) {} + +const char* SafeBrowsingNavigationThrottle::GetNameForLogging() { + return "SafeBrowsingNavigationThrottle"; +} + +content::NavigationThrottle::ThrottleCheckResult +SafeBrowsingNavigationThrottle::WillFailRequest() { + SafeBrowsingService* service = g_browser_process->safe_browsing_service(); + if (!service) { + return content::NavigationThrottle::PROCEED; + } + + security_interstitials::UnsafeResource resource; + content::NavigationHandle* handle = navigation_handle(); + scoped_refptr<SafeBrowsingUIManager> manager = service->ui_manager(); + + if (manager->PopUnsafeResourceForURL(handle->GetURL(), &resource)) { + SafeBrowsingBlockingPage* blocking_page = + SafeBrowsingBlockingPage::CreateBlockingPage( + manager.get(), handle->GetWebContents(), handle->GetURL(), + resource); + std::string error_page_content = blocking_page->GetHTMLContents(); + security_interstitials::SecurityInterstitialTabHelper:: + AssociateBlockingPage(handle->GetWebContents(), + handle->GetNavigationId(), + base::WrapUnique(blocking_page)); + + manager->AddToWhitelistUrlSet(handle->GetURL().GetWithEmptyPath(), + handle->GetWebContents(), true /* pending */, + resource.threat_type); + + return content::NavigationThrottle::ThrottleCheckResult( + CANCEL, net::ERR_BLOCKED_BY_CLIENT, error_page_content); + } + + return content::NavigationThrottle::PROCEED; +} + +} // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_throttle.h b/chrome/browser/safe_browsing/safe_browsing_navigation_throttle.h new file mode 100644 index 0000000..d3edcc2 --- /dev/null +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_throttle.h
@@ -0,0 +1,31 @@ +// Copyright 2018 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_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_THROTTLE_H_ +#define CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_THROTTLE_H_ + +#include "content/public/browser/navigation_throttle.h" + +namespace content { +class NavigationHandle; +} // namespace content + +namespace safe_browsing { + +// This throttle monitors failed requests, and if a request failed due to it +// being blocked by Safe Browsing, it creates and displays an interstitial. +// This throttle is only created when Safe Browsing committed interstitials are +// enabled. +class SafeBrowsingNavigationThrottle : public content::NavigationThrottle { + public: + explicit SafeBrowsingNavigationThrottle(content::NavigationHandle* handle); + ~SafeBrowsingNavigationThrottle() override {} + const char* GetNameForLogging() override; + + content::NavigationThrottle::ThrottleCheckResult WillFailRequest() override; +}; + +} // namespace safe_browsing + +#endif // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_NAVIGATION_THROTTLE_H_
diff --git a/chrome/browser/safe_browsing/ui_manager.cc b/chrome/browser/safe_browsing/ui_manager.cc index 606bd95..9b3104d 100644 --- a/chrome/browser/safe_browsing/ui_manager.cc +++ b/chrome/browser/safe_browsing/ui_manager.cc
@@ -152,6 +152,26 @@ observer_list_.RemoveObserver(observer); } +void SafeBrowsingUIManager::AddUnsafeResource( + GURL url, + security_interstitials::UnsafeResource resource) { + unsafe_resources_.push_back(std::make_pair(url, resource)); +} + +bool SafeBrowsingUIManager::PopUnsafeResourceForURL( + GURL url, + security_interstitials::UnsafeResource* resource) { + for (auto it = unsafe_resources_.begin(); it != unsafe_resources_.end(); + it++) { + if (it->first == url) { + *resource = it->second; + unsafe_resources_.erase(it); + return true; + } + } + return false; +} + const std::string SafeBrowsingUIManager::app_locale() const { DCHECK_CURRENTLY_ON(BrowserThread::UI); return g_browser_process->GetApplicationLocale();
diff --git a/chrome/browser/safe_browsing/ui_manager.h b/chrome/browser/safe_browsing/ui_manager.h index 073567a..4adf5d4 100644 --- a/chrome/browser/safe_browsing/ui_manager.h +++ b/chrome/browser/safe_browsing/ui_manager.h
@@ -17,6 +17,7 @@ #include "base/time/time.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "components/safe_browsing/base_ui_manager.h" +#include "components/security_interstitials/content/unsafe_resource.h" class GURL; @@ -88,6 +89,20 @@ void AddObserver(Observer* observer); void RemoveObserver(Observer* remove); + // Adds an UnsafeResource |resource| for |url| to unsafe_resources_, + // this should be called by the UrlCheckerDelegate whenever a resource load + // is blocked due to a SB hit. + void AddUnsafeResource(GURL url, + security_interstitials::UnsafeResource resource); + + // Checks if an UnsafeResource |resource| exists for |url|, if so, it is + // removed from the vector, assigned to |resource| and the function returns + // true. Otherwise the function returns false and nothing gets assigned to + // |resource|. + bool PopUnsafeResourceForURL( + GURL url, + security_interstitials::UnsafeResource* resource); + const std::string app_locale() const override; history::HistoryService* history_service( content::WebContents* web_contents) override; @@ -119,6 +134,12 @@ // Safebrowsing service. scoped_refptr<SafeBrowsingService> sb_service_; + // Stores unsafe resources so they can be fetched from a navigation throttle + // in the committed interstitials flow. Implemented as a pair vector since + // most of the time it will be empty or contain a single element. + std::vector<std::pair<GURL, security_interstitials::UnsafeResource>> + unsafe_resources_; + base::ObserverList<Observer>::Unchecked observer_list_; DISALLOW_COPY_AND_ASSIGN(SafeBrowsingUIManager);
diff --git a/chrome/browser/safe_browsing/url_checker_delegate_impl.cc b/chrome/browser/safe_browsing/url_checker_delegate_impl.cc index fd0bba50..77207ca 100644 --- a/chrome/browser/safe_browsing/url_checker_delegate_impl.cc +++ b/chrome/browser/safe_browsing/url_checker_delegate_impl.cc
@@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/feature_list.h" #include "base/task/post_task.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/data_reduction_proxy_util.h" #include "chrome/browser/prerender/prerender_contents.h" #include "chrome/browser/prerender/prerender_final_status.h" @@ -99,6 +100,7 @@ bool has_user_gesture) { if (base::FeatureList::IsEnabled(kCommittedSBInterstitials) && is_main_frame) { + ui_manager_->AddUnsafeResource(resource.url, resource); // With committed interstitials we just cancel the load from here, the // actual interstitial will be shown from the // SafeBrowsingNavigationThrottle.
diff --git a/chrome/browser/ui/views/autofill/migratable_card_view.cc b/chrome/browser/ui/views/autofill/migratable_card_view.cc index 97e7e4b..bd89dde 100644 --- a/chrome/browser/ui/views/autofill/migratable_card_view.cc +++ b/chrome/browser/ui/views/autofill/migratable_card_view.cc
@@ -126,7 +126,7 @@ case MigratableCreditCard::MigrationStatus::FAILURE_ON_UPLOAD: { auto* migration_failed_image = new views::ImageView(); migration_failed_image->SetImage( - gfx::CreateVectorIcon(kBrowserToolsErrorIcon, + gfx::CreateVectorIcon(vector_icons::kErrorIcon, kMigrationResultImageSize, gfx::kGoogleRed700)); migratable_card_description_view->AddChildView(migration_failed_image); break;
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index dbebf5d4..f62f7be 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -610,7 +610,7 @@ #if BUILDFLAG(ENABLE_PRINT_PREVIEW) if (url.host_piece() == chrome::kChromeUIPrintHost && !profile->GetPrefs()->GetBoolean(prefs::kPrintPreviewDisabled)) { - return &NewWebUI<PrintPreviewUI>; + return &NewWebUI<printing::PrintPreviewUI>; } #endif #if BUILDFLAG(ENABLE_SERVICE_DISCOVERY)
diff --git a/chrome/browser/ui/webui/print_preview/cloud_printer_handler.cc b/chrome/browser/ui/webui/print_preview/cloud_printer_handler.cc index 97763541..d3a513c 100644 --- a/chrome/browser/ui/webui/print_preview/cloud_printer_handler.cc +++ b/chrome/browser/ui/webui/print_preview/cloud_printer_handler.cc
@@ -4,12 +4,14 @@ #include "chrome/browser/ui/webui/print_preview/cloud_printer_handler.h" -#include <memory> +#include <utility> #include "base/bind.h" #include "base/callback.h" #include "base/values.h" +namespace printing { + CloudPrinterHandler::CloudPrinterHandler() {} CloudPrinterHandler::~CloudPrinterHandler() {} @@ -40,3 +42,5 @@ // TODO(https://crbug.com/829414): Print to cloud print NOTIMPLEMENTED(); } + +} // namespace printing
diff --git a/chrome/browser/ui/webui/print_preview/cloud_printer_handler.h b/chrome/browser/ui/webui/print_preview/cloud_printer_handler.h index 64d469a..381b913c 100644 --- a/chrome/browser/ui/webui/print_preview/cloud_printer_handler.h +++ b/chrome/browser/ui/webui/print_preview/cloud_printer_handler.h
@@ -11,6 +11,8 @@ #include "base/macros.h" #include "chrome/browser/ui/webui/print_preview/printer_handler.h" +namespace printing { + // Implementation of PrinterHandler interface class CloudPrinterHandler : public PrinterHandler { public: @@ -35,4 +37,7 @@ private: DISALLOW_COPY_AND_ASSIGN(CloudPrinterHandler); }; + +} // namespace printing + #endif // CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_CLOUD_PRINTER_HANDLER_H_
diff --git a/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc b/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc index a852ea25..c293f55 100644 --- a/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc +++ b/chrome/browser/ui/webui/print_preview/extension_printer_handler.cc
@@ -42,7 +42,8 @@ using extensions::ExtensionRegistry; using extensions::ListBuilder; using extensions::UsbPrinterManifestData; -using printing::PwgRasterConverter; + +namespace printing { namespace { @@ -241,7 +242,7 @@ if (!pwg_raster_converter_) pwg_raster_converter_ = PwgRasterConverter::CreateDefault(); - printing::PwgRasterSettings bitmap_settings = + PwgRasterSettings bitmap_settings = PwgRasterConverter::GetBitmapSettings(printer_description, ticket); pwg_raster_converter_->Start( data.get(), @@ -286,10 +287,10 @@ const base::DictionaryValue& capability) { base::Value capabilities(base::Value::Type::DICTIONARY); std::unique_ptr<base::DictionaryValue> cdd = - printing::ValidateCddForPrintPreview(capability); + ValidateCddForPrintPreview(capability); // Leave |capabilities| empty if |cdd| is empty. if (!cdd->empty()) { - capabilities.SetKey(printing::kSettingCapabilities, + capabilities.SetKey(kSettingCapabilities, base::Value::FromUniquePtrValue(std::move(cdd))); } std::move(callback).Run(std::move(capabilities)); @@ -360,3 +361,5 @@ if (pending_enumeration_count_ == 0) std::move(done_callback_).Run(); } + +} // namespace printing
diff --git a/chrome/browser/ui/webui/print_preview/extension_printer_handler.h b/chrome/browser/ui/webui/print_preview/extension_printer_handler.h index 6259a19..7485fff 100644 --- a/chrome/browser/ui/webui/print_preview/extension_printer_handler.h +++ b/chrome/browser/ui/webui/print_preview/extension_printer_handler.h
@@ -21,8 +21,6 @@ class RefCountedMemory; } -class Profile; - namespace cloud_devices { class CloudDeviceDescription; } @@ -35,9 +33,11 @@ class Size; } +class Profile; + namespace printing { + class PwgRasterConverter; -} // Implementation of PrinterHandler interface backed by printerProvider // extension API. @@ -70,7 +70,7 @@ friend class ExtensionPrinterHandlerTest; void SetPwgRasterConverterForTesting( - std::unique_ptr<printing::PwgRasterConverter> pwg_raster_converter); + std::unique_ptr<PwgRasterConverter> pwg_raster_converter); // Converts |data| to PWG raster format (from PDF) for a printer described // by |printer_description|. @@ -107,7 +107,7 @@ Profile* const profile_; GetPrintersDoneCallback done_callback_; PrintJobCallback print_job_callback_; - std::unique_ptr<printing::PwgRasterConverter> pwg_raster_converter_; + std::unique_ptr<PwgRasterConverter> pwg_raster_converter_; int pending_enumeration_count_ = 0; base::WeakPtrFactory<ExtensionPrinterHandler> weak_ptr_factory_; @@ -115,4 +115,6 @@ DISALLOW_COPY_AND_ASSIGN(ExtensionPrinterHandler); }; +} // namespace printing + #endif // CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_EXTENSION_PRINTER_HANDLER_H_
diff --git a/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc b/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc index 9768d56b..586847c0 100644 --- a/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc +++ b/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc
@@ -50,7 +50,8 @@ using extensions::PrinterProviderAPI; using extensions::PrinterProviderPrintJob; using extensions::TestExtensionEnvironment; -using printing::PwgRasterConverter; + +namespace printing { namespace { @@ -214,7 +215,7 @@ ++(*call_count); const base::Value* capabilities = nullptr; if (capability.is_dict()) { - capabilities = capability.FindKeyOfType(printing::kSettingCapabilities, + capabilities = capability.FindKeyOfType(kSettingCapabilities, base::Value::Type::DICTIONARY); } *capability_out = @@ -282,8 +283,8 @@ // PwgRasterConverter implementation. It writes |data| to shared memory. // Also, remembers conversion and bitmap settings passed into the method. void Start(const base::RefCountedMemory* data, - const printing::PdfRenderSettings& conversion_settings, - const printing::PwgRasterSettings& bitmap_settings, + const PdfRenderSettings& conversion_settings, + const PwgRasterSettings& bitmap_settings, ResultCallback callback) override { base::ReadOnlySharedMemoryRegion invalid_pwg_region; if (fail_conversion_) { @@ -308,17 +309,15 @@ // Makes |Start| method always return an error. void FailConversion() { fail_conversion_ = true; } - const printing::PdfRenderSettings& conversion_settings() const { + const PdfRenderSettings& conversion_settings() const { return conversion_settings_; } - const printing::PwgRasterSettings& bitmap_settings() const { - return bitmap_settings_; - } + const PwgRasterSettings& bitmap_settings() const { return bitmap_settings_; } private: - printing::PdfRenderSettings conversion_settings_; - printing::PwgRasterSettings bitmap_settings_; + PdfRenderSettings conversion_settings_; + PwgRasterSettings bitmap_settings_; bool fail_conversion_ = false; DISALLOW_COPY_AND_ASSIGN(FakePwgRasterConverter); @@ -778,13 +777,13 @@ ASSERT_TRUE(fake_api); ASSERT_EQ(1u, fake_api->pending_print_count()); - EXPECT_EQ(printing::TRANSFORM_NORMAL, + EXPECT_EQ(TRANSFORM_NORMAL, pwg_raster_converter_->bitmap_settings().odd_page_transform); EXPECT_FALSE(pwg_raster_converter_->bitmap_settings().rotate_all_pages); EXPECT_FALSE(pwg_raster_converter_->bitmap_settings().reverse_page_order); EXPECT_TRUE(pwg_raster_converter_->bitmap_settings().use_color); - EXPECT_EQ(gfx::Size(printing::kDefaultPdfDpi, printing::kDefaultPdfDpi), + EXPECT_EQ(gfx::Size(kDefaultPdfDpi, kDefaultPdfDpi), pwg_raster_converter_->conversion_settings().dpi); EXPECT_TRUE(pwg_raster_converter_->conversion_settings().autorotate); // size = vertically_oriented_size * vertical_dpi / points_per_inch x @@ -832,7 +831,7 @@ ASSERT_TRUE(fake_api); ASSERT_EQ(1u, fake_api->pending_print_count()); - EXPECT_EQ(printing::TRANSFORM_FLIP_VERTICAL, + EXPECT_EQ(TRANSFORM_FLIP_VERTICAL, pwg_raster_converter_->bitmap_settings().odd_page_transform); EXPECT_TRUE(pwg_raster_converter_->bitmap_settings().rotate_all_pages); EXPECT_TRUE(pwg_raster_converter_->bitmap_settings().reverse_page_order); @@ -998,3 +997,5 @@ EXPECT_EQ(0u, call_count); EXPECT_FALSE(printer_info.get()); } + +} // namespace printing
diff --git a/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos.cc b/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos.cc index 4408032..b759de476 100644 --- a/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos.cc +++ b/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos.cc
@@ -32,6 +32,8 @@ #include "printing/backend/print_backend_consts.h" #include "printing/backend/printing_restrictions.h" +namespace printing { + namespace { using chromeos::CupsPrintersManager; @@ -41,8 +43,8 @@ // as the system_driverinfo option value, and the Printer#display_name in // the |printer_description| field. This will match how Mac OS X presents // printer information. -printing::PrinterBasicInfo ToBasicInfo(const chromeos::Printer& printer) { - printing::PrinterBasicInfo basic_info; +PrinterBasicInfo ToBasicInfo(const chromeos::Printer& printer) { + PrinterBasicInfo basic_info; // TODO(skau): Unify Mac with the other platforms for display name // presentation so I can remove this strange code. @@ -56,7 +58,7 @@ } void AddPrintersToList(const std::vector<chromeos::Printer>& printers, - printing::PrinterList* list) { + PrinterList* list) { for (const auto& printer : printers) { list->push_back(ToBasicInfo(printer)); } @@ -65,8 +67,8 @@ void CapabilitiesFetched(base::DictionaryValue policies, LocalPrinterHandlerChromeos::GetCapabilityCallback cb, std::unique_ptr<base::DictionaryValue> printer_info) { - printer_info->FindKey(printing::kPrinter) - ->SetKey(printing::kSettingPolicies, std::move(policies)); + printer_info->FindKey(kPrinter)->SetKey(kSettingPolicies, + std::move(policies)); std::move(cb).Run(std::move(*printer_info)); } @@ -75,13 +77,12 @@ LocalPrinterHandlerChromeos::GetCapabilityCallback cb) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - printing::PrinterBasicInfo basic_info = ToBasicInfo(*printer); + PrinterBasicInfo basic_info = ToBasicInfo(*printer); base::PostTaskWithTraitsAndReplyWithResult( FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, - base::BindOnce( - &printing::GetSettingsOnBlockingPool, printer->id(), basic_info, - printing::PrinterSemanticCapsAndDefaults::Papers(), nullptr), + base::BindOnce(&GetSettingsOnBlockingPool, printer->id(), basic_info, + PrinterSemanticCapsAndDefaults::Papers(), nullptr), base::BindOnce(&CapabilitiesFetched, std::move(policies), std::move(cb))); } @@ -123,7 +124,7 @@ // thread. DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - printing::PrinterList printer_list; + PrinterList printer_list; AddPrintersToList( printers_manager_->GetPrinters(CupsPrintersManager::kConfigured), &printer_list); @@ -134,8 +135,8 @@ printers_manager_->GetPrinters(CupsPrintersManager::kAutomatic), &printer_list); - printing::ConvertPrinterListForCallback( - added_printers_callback, std::move(done_callback), printer_list); + ConvertPrinterListForCallback(added_printers_callback, + std::move(done_callback), printer_list); } void LocalPrinterHandlerChromeos::StartGetCapability( @@ -184,19 +185,17 @@ printers_manager_->PrinterInstalled(*printer, true /*is_automatic*/); // populate |policies| with policies for native printers. + auto* prefs = profile_->GetPrefs(); base::DictionaryValue policies; + policies.SetInteger(kAllowedColorModes, + prefs->GetInteger(prefs::kPrintingAllowedColorModes)); policies.SetInteger( - printing::kAllowedColorModes, - profile_->GetPrefs()->GetInteger(prefs::kPrintingAllowedColorModes)); - policies.SetInteger( - printing::kAllowedDuplexModes, - profile_->GetPrefs()->GetInteger(prefs::kPrintingAllowedDuplexModes)); - policies.SetInteger( - printing::kDefaultColorMode, - profile_->GetPrefs()->GetInteger(prefs::kPrintingColorDefault)); - policies.SetInteger( - printing::kDefaultDuplexMode, - profile_->GetPrefs()->GetInteger(prefs::kPrintingDuplexDefault)); + kAllowedDuplexModes, + prefs->GetInteger(prefs::kPrintingAllowedDuplexModes)); + policies.SetInteger(kDefaultColorMode, + prefs->GetInteger(prefs::kPrintingColorDefault)); + policies.SetInteger(kDefaultDuplexMode, + prefs->GetInteger(prefs::kPrintingDuplexDefault)); // fetch settings on the blocking pool and invoke callback. FetchCapabilities(std::move(printer), std::move(policies), std::move(cb)); return; @@ -241,6 +240,8 @@ size_t size_in_kb = print_data->size() / 1024; UMA_HISTOGRAM_MEMORY_KB("Printing.CUPS.PrintDocumentSize", size_in_kb); - printing::StartLocalPrint(ticket_json, print_data, preview_web_contents_, - std::move(callback)); + StartLocalPrint(ticket_json, print_data, preview_web_contents_, + std::move(callback)); } + +} // namespace printing
diff --git a/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos.h b/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos.h index 07ec869..0658c38 100644 --- a/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos.h +++ b/chrome/browser/ui/webui/print_preview/local_printer_handler_chromeos.h
@@ -23,6 +23,8 @@ class Profile; +namespace printing { + class LocalPrinterHandlerChromeos : public PrinterHandler { public: LocalPrinterHandlerChromeos(Profile* profile, @@ -59,4 +61,6 @@ DISALLOW_COPY_AND_ASSIGN(LocalPrinterHandlerChromeos); }; +} // namespace printing + #endif // CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_LOCAL_PRINTER_HANDLER_CHROMEOS_H_
diff --git a/chrome/browser/ui/webui/print_preview/local_printer_handler_default.cc b/chrome/browser/ui/webui/print_preview/local_printer_handler_default.cc index c80280b48..d7b287c 100644 --- a/chrome/browser/ui/webui/print_preview/local_printer_handler_default.cc +++ b/chrome/browser/ui/webui/print_preview/local_printer_handler_default.cc
@@ -22,30 +22,30 @@ #include "components/printing/common/printer_capabilities_mac.h" #endif +namespace printing { + namespace { -printing::PrinterList EnumeratePrintersAsync() { +PrinterList EnumeratePrintersAsync() { base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK); - scoped_refptr<printing::PrintBackend> print_backend( - printing::PrintBackend::CreateInstance(nullptr)); + scoped_refptr<PrintBackend> print_backend( + PrintBackend::CreateInstance(nullptr)); - printing::PrinterList printer_list; + PrinterList printer_list; print_backend->EnumeratePrinters(&printer_list); return printer_list; } base::Value FetchCapabilitiesAsync(const std::string& device_name) { - printing::PrinterSemanticCapsAndDefaults::Papers additional_papers; + PrinterSemanticCapsAndDefaults::Papers additional_papers; #if defined(OS_MACOSX) - if (base::FeatureList::IsEnabled( - printing::features::kEnableCustomMacPaperSizes)) { - additional_papers = printing::GetMacCustomPaperSizes(); - } + if (base::FeatureList::IsEnabled(features::kEnableCustomMacPaperSizes)) + additional_papers = GetMacCustomPaperSizes(); #endif base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK); - scoped_refptr<printing::PrintBackend> print_backend( - printing::PrintBackend::CreateInstance(nullptr)); + scoped_refptr<PrintBackend> print_backend( + PrintBackend::CreateInstance(nullptr)); VLOG(1) << "Get printer capabilities start for " << device_name; @@ -54,18 +54,18 @@ return base::Value(); } - printing::PrinterBasicInfo basic_info; + PrinterBasicInfo basic_info; if (!print_backend->GetPrinterBasicInfo(device_name, &basic_info)) return base::Value(); - return std::move(*printing::GetSettingsOnBlockingPool( + return std::move(*GetSettingsOnBlockingPool( device_name, basic_info, additional_papers, print_backend)); } std::string GetDefaultPrinterAsync() { base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK); - scoped_refptr<printing::PrintBackend> print_backend( - printing::PrintBackend::CreateInstance(nullptr)); + scoped_refptr<PrintBackend> print_backend( + PrintBackend::CreateInstance(nullptr)); std::string default_printer = print_backend->GetDefaultPrinterName(); VLOG(1) << "Default Printer: " << default_printer; @@ -101,7 +101,7 @@ base::PostTaskWithTraitsAndReplyWithResult( FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE}, base::BindOnce(&EnumeratePrintersAsync), - base::BindOnce(&printing::ConvertPrinterListForCallback, callback, + base::BindOnce(&ConvertPrinterListForCallback, callback, std::move(done_callback))); } @@ -124,6 +124,8 @@ const gfx::Size& page_size, const scoped_refptr<base::RefCountedMemory>& print_data, PrintCallback callback) { - printing::StartLocalPrint(ticket_json, print_data, preview_web_contents_, - std::move(callback)); + StartLocalPrint(ticket_json, print_data, preview_web_contents_, + std::move(callback)); } + +} // namespace printing
diff --git a/chrome/browser/ui/webui/print_preview/local_printer_handler_default.h b/chrome/browser/ui/webui/print_preview/local_printer_handler_default.h index a9da375..aaa992d 100644 --- a/chrome/browser/ui/webui/print_preview/local_printer_handler_default.h +++ b/chrome/browser/ui/webui/print_preview/local_printer_handler_default.h
@@ -18,6 +18,8 @@ class WebContents; } +namespace printing { + class LocalPrinterHandlerDefault : public PrinterHandler { public: explicit LocalPrinterHandlerDefault( @@ -45,4 +47,6 @@ DISALLOW_COPY_AND_ASSIGN(LocalPrinterHandlerDefault); }; +} // namespace printing + #endif // CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_LOCAL_PRINTER_HANDLER_DEFAULT_H_
diff --git a/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc b/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc index c71f8bc..393aa21 100644 --- a/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc +++ b/chrome/browser/ui/webui/print_preview/pdf_printer_handler.cc
@@ -39,11 +39,13 @@ #include "ui/gfx/geometry/size.h" #include "url/gurl.h" +namespace printing { + namespace { constexpr base::FilePath::CharType kPdfExtension[] = FILE_PATH_LITERAL("pdf"); -class PrintingContextDelegate : public printing::PrintingContext::Delegate { +class PrintingContextDelegate : public PrintingContext::Delegate { public: // PrintingContext::Delegate methods. gfx::NativeView GetParentView() override { return NULL; } @@ -54,15 +56,14 @@ gfx::Size GetDefaultPdfMediaSizeMicrons() { PrintingContextDelegate delegate; - std::unique_ptr<printing::PrintingContext> printing_context( - printing::PrintingContext::Create(&delegate)); - if (printing::PrintingContext::OK != printing_context->UsePdfSettings() || + auto printing_context(PrintingContext::Create(&delegate)); + if (PrintingContext::OK != printing_context->UsePdfSettings() || printing_context->settings().device_units_per_inch() <= 0) { return gfx::Size(); } gfx::Size pdf_media_size = printing_context->GetPdfPaperSizeDeviceUnits(); float device_microns_per_device_unit = - static_cast<float>(printing::kMicronsPerInch) / + static_cast<float>(kMicronsPerInch) / printing_context->settings().device_units_per_inch(); return gfx::Size(pdf_media_size.width() * device_microns_per_device_unit, pdf_media_size.height() * device_microns_per_device_unit); @@ -82,7 +83,7 @@ ColorCapability color; { Color standard_color(STANDARD_COLOR); - standard_color.vendor_id = base::IntToString(printing::COLOR); + standard_color.vendor_id = base::IntToString(COLOR); color.AddDefaultOption(standard_color, true); } color.SaveTo(&description); @@ -145,7 +146,7 @@ PdfPrinterHandler::PdfPrinterHandler(Profile* profile, content::WebContents* preview_web_contents, - printing::StickySettings* sticky_settings) + StickySettings* sticky_settings) : preview_web_contents_(preview_web_contents), profile_(profile), sticky_settings_(sticky_settings), @@ -169,9 +170,8 @@ void PdfPrinterHandler::StartGetCapability(const std::string& destination_id, GetCapabilityCallback callback) { base::Value printer_info(base::Value::Type::DICTIONARY); - printer_info.SetKey(printing::kSettingDeviceName, - base::Value(destination_id)); - printer_info.SetKey(printing::kSettingCapabilities, + printer_info.SetKey(kSettingDeviceName, base::Value(destination_id)); + printer_info.SetKey(kSettingCapabilities, std::move(*GetPdfCapabilities( g_browser_process->GetApplicationLocale()))); std::move(callback).Run(std::move(printer_info)); @@ -202,8 +202,8 @@ DCHECK(!print_callback_); print_callback_ = std::move(callback); - printing::PrintPreviewDialogController* dialog_controller = - printing::PrintPreviewDialogController::GetInstance(); + PrintPreviewDialogController* dialog_controller = + PrintPreviewDialogController::GetInstance(); content::WebContents* initiator = dialog_controller ? dialog_controller->GetInitiator(preview_web_contents_) : nullptr; @@ -387,3 +387,5 @@ &file_type_info, 0, base::FilePath::StringType(), platform_util::GetTopLevel(preview_web_contents_->GetNativeView()), NULL); } + +} // namespace printing
diff --git a/chrome/browser/ui/webui/print_preview/pdf_printer_handler.h b/chrome/browser/ui/webui/print_preview/pdf_printer_handler.h index 0fb1a7b..7bb8bc97 100644 --- a/chrome/browser/ui/webui/print_preview/pdf_printer_handler.h +++ b/chrome/browser/ui/webui/print_preview/pdf_printer_handler.h
@@ -34,12 +34,14 @@ class GURL; class Profile; +namespace printing { + class PdfPrinterHandler : public PrinterHandler, public ui::SelectFileDialog::Listener { public: PdfPrinterHandler(Profile* profile, content::WebContents* preview_web_contents, - printing::StickySettings* sticky_settings); + StickySettings* sticky_settings); ~PdfPrinterHandler() override; @@ -96,7 +98,7 @@ const base::FilePath& directory); Profile* const profile_; - printing::StickySettings* const sticky_settings_; + StickySettings* const sticky_settings_; // Holds the path to the print to pdf request. It is empty if no such request // exists. @@ -117,4 +119,6 @@ DISALLOW_COPY_AND_ASSIGN(PdfPrinterHandler); }; +} // namespace printing + #endif // CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PDF_PRINTER_HANDLER_H_
diff --git a/chrome/browser/ui/webui/print_preview/pdf_printer_handler_unittest.cc b/chrome/browser/ui/webui/print_preview/pdf_printer_handler_unittest.cc index 4393bc3..3272c55 100644 --- a/chrome/browser/ui/webui/print_preview/pdf_printer_handler_unittest.cc +++ b/chrome/browser/ui/webui/print_preview/pdf_printer_handler_unittest.cc
@@ -11,6 +11,8 @@ #define FPL(x) FILE_PATH_LITERAL(x) +namespace printing { + using PdfPrinterHandlerTest = testing::Test; TEST_F(PdfPrinterHandlerTest, GetFileNameForPrintJobTitle) { @@ -102,3 +104,5 @@ EXPECT_EQ(data.expected_output, path.value()); } } + +} // namespace printing
diff --git a/chrome/browser/ui/webui/print_preview/pdf_printer_handler_win_unittest.cc b/chrome/browser/ui/webui/print_preview/pdf_printer_handler_win_unittest.cc index 03e57126..6038b4a9 100644 --- a/chrome/browser/ui/webui/print_preview/pdf_printer_handler_win_unittest.cc +++ b/chrome/browser/ui/webui/print_preview/pdf_printer_handler_win_unittest.cc
@@ -20,6 +20,8 @@ using content::WebContents; +namespace printing { + namespace { void ExecuteCancelledSelectFileDialog( @@ -39,7 +41,7 @@ public: FakePdfPrinterHandler(Profile* profile, content::WebContents* contents, - printing::StickySettings* sticky_settings) + StickySettings* sticky_settings) : PdfPrinterHandler(profile, contents, sticky_settings), save_failed_(false) {} @@ -126,3 +128,5 @@ L"1111111111111111111111111111111111111111111111111.html"); EXPECT_TRUE(pdf_printer_->save_failed()); } + +} // namespace printing
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc index 4b7e70a..87977229 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_handler.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.cc
@@ -89,8 +89,8 @@ using content::RenderFrameHost; using content::WebContents; -using printing::PrintViewManager; -using printing::PrinterType; + +namespace printing { namespace { @@ -321,19 +321,16 @@ // from the print ticket, as they may have dummy values in the preview // request. const base::ListValue* page_range_array = NULL; - if (preview_settings.GetList(printing::kSettingPageRange, - &page_range_array) && + if (preview_settings.GetList(kSettingPageRange, &page_range_array) && !page_range_array->empty()) { ReportPrintSettingHistogram(PAGE_RANGE); } const base::DictionaryValue* media_size_value = NULL; - if (preview_settings.GetDictionary(printing::kSettingMediaSize, - &media_size_value) && + if (preview_settings.GetDictionary(kSettingMediaSize, &media_size_value) && !media_size_value->empty()) { bool is_default = false; - if (media_size_value->GetBoolean(printing::kSettingMediaSizeIsDefault, - &is_default) && + if (media_size_value->GetBoolean(kSettingMediaSizeIsDefault, &is_default) && is_default) { ReportPrintSettingHistogram(DEFAULT_MEDIA); } else { @@ -342,92 +339,86 @@ } bool landscape = false; - if (preview_settings.GetBoolean(printing::kSettingLandscape, &landscape)) + if (preview_settings.GetBoolean(kSettingLandscape, &landscape)) ReportPrintSettingHistogram(landscape ? LANDSCAPE : PORTRAIT); int copies = 1; - if (print_settings.GetInteger(printing::kSettingCopies, &copies) && - copies > 1) { + if (print_settings.GetInteger(kSettingCopies, &copies) && copies > 1) { ReportPrintSettingHistogram(COPIES); } int scaling = 100; - if (preview_settings.GetInteger(printing::kSettingScaleFactor, &scaling) && + if (preview_settings.GetInteger(kSettingScaleFactor, &scaling) && scaling != 100) { ReportPrintSettingHistogram(SCALING); } int pages_per_sheet = 1; - if (preview_settings.GetInteger(printing::kSettingPagesPerSheet, - &pages_per_sheet) && + if (preview_settings.GetInteger(kSettingPagesPerSheet, &pages_per_sheet) && pages_per_sheet != 1) { ReportPrintSettingHistogram(PAGES_PER_SHEET); } bool collate = false; - if (print_settings.GetBoolean(printing::kSettingCollate, &collate) && collate) + if (print_settings.GetBoolean(kSettingCollate, &collate) && collate) ReportPrintSettingHistogram(COLLATE); int duplex_mode = 0; - if (print_settings.GetInteger(printing::kSettingDuplexMode, &duplex_mode)) + if (print_settings.GetInteger(kSettingDuplexMode, &duplex_mode)) ReportPrintSettingHistogram(duplex_mode ? DUPLEX : SIMPLEX); int color_mode = 0; - if (print_settings.GetInteger(printing::kSettingColor, &color_mode)) { + if (print_settings.GetInteger(kSettingColor, &color_mode)) { ReportPrintSettingHistogram( - printing::IsColorModelSelected(color_mode) ? COLOR : BLACK_AND_WHITE); + IsColorModelSelected(color_mode) ? COLOR : BLACK_AND_WHITE); } int margins_type = 0; - if (preview_settings.GetInteger(printing::kSettingMarginsType, - &margins_type) && + if (preview_settings.GetInteger(kSettingMarginsType, &margins_type) && margins_type != 0) { ReportPrintSettingHistogram(NON_DEFAULT_MARGINS); } bool headers = false; - if (preview_settings.GetBoolean(printing::kSettingHeaderFooterEnabled, - &headers) && + if (preview_settings.GetBoolean(kSettingHeaderFooterEnabled, &headers) && headers) { ReportPrintSettingHistogram(HEADERS_AND_FOOTERS); } bool css_background = false; - if (preview_settings.GetBoolean(printing::kSettingShouldPrintBackgrounds, + if (preview_settings.GetBoolean(kSettingShouldPrintBackgrounds, &css_background) && css_background) { ReportPrintSettingHistogram(CSS_BACKGROUND); } bool selection_only = false; - if (preview_settings.GetBoolean(printing::kSettingShouldPrintSelectionOnly, + if (preview_settings.GetBoolean(kSettingShouldPrintSelectionOnly, &selection_only) && selection_only) { ReportPrintSettingHistogram(SELECTION_ONLY); } bool rasterize = false; - if (preview_settings.GetBoolean(printing::kSettingRasterizePdf, &rasterize) && + if (preview_settings.GetBoolean(kSettingRasterizePdf, &rasterize) && rasterize) { ReportPrintSettingHistogram(PRINT_AS_IMAGE); } bool fit_to_page = false; if (is_pdf && - preview_settings.GetBoolean(printing::kSettingFitToPageEnabled, - &fit_to_page) && + preview_settings.GetBoolean(kSettingFitToPageEnabled, &fit_to_page) && fit_to_page) { ReportPrintSettingHistogram(FIT_TO_PAGE); } int dpi_horizontal = 0; int dpi_vertical = 0; - if (print_settings.GetInteger(printing::kSettingDpiHorizontal, - &dpi_horizontal) && - print_settings.GetInteger(printing::kSettingDpiVertical, &dpi_vertical) && + if (print_settings.GetInteger(kSettingDpiHorizontal, &dpi_horizontal) && + print_settings.GetInteger(kSettingDpiVertical, &dpi_vertical) && dpi_horizontal > 0 && dpi_vertical > 0) { bool is_default = false; - if (print_settings.GetBoolean(printing::kSettingDpiDefault, &is_default)) + if (print_settings.GetBoolean(kSettingDpiDefault, &is_default)) ReportPrintSettingHistogram(is_default ? DEFAULT_DPI : NON_DEFAULT_DPI); } } @@ -435,36 +426,36 @@ UserActionBuckets DetermineUserAction(const base::DictionaryValue& settings) { bool value = false; #if defined(OS_MACOSX) - value = settings.HasKey(printing::kSettingOpenPDFInPreview); + value = settings.HasKey(kSettingOpenPDFInPreview); #endif if (value) return OPEN_IN_MAC_PREVIEW; // This needs to be checked before checking for a cloud print ID, since a // print ticket for printing to Drive will also contain a cloud print ID. - settings.GetBoolean(printing::kSettingPrintToGoogleDrive, &value); + settings.GetBoolean(kSettingPrintToGoogleDrive, &value); if (value) return PRINT_TO_GOOGLE_DRIVE; - if (settings.HasKey(printing::kSettingCloudPrintId)) + if (settings.HasKey(kSettingCloudPrintId)) return PRINT_WITH_CLOUD_PRINT; - settings.GetBoolean(printing::kSettingPrintWithPrivet, &value); + settings.GetBoolean(kSettingPrintWithPrivet, &value); if (value) return PRINT_WITH_PRIVET; - settings.GetBoolean(printing::kSettingPrintWithExtension, &value); + settings.GetBoolean(kSettingPrintWithExtension, &value); if (value) return PRINT_WITH_EXTENSION; - settings.GetBoolean(printing::kSettingPrintToPDF, &value); + settings.GetBoolean(kSettingPrintToPDF, &value); if (value) return PRINT_TO_PDF; - settings.GetBoolean(printing::kSettingShowSystemDialog, &value); + settings.GetBoolean(kSettingShowSystemDialog, &value); if (value) return FALLBACK_TO_ADVANCED_SETTINGS_DIALOG; return PRINT_TO_PRINTER; } -base::LazyInstance<printing::StickySettings>::DestructorAtExit - g_sticky_settings = LAZY_INSTANCE_INITIALIZER; +base::LazyInstance<StickySettings>::DestructorAtExit g_sticky_settings = + LAZY_INSTANCE_INITIALIZER; -printing::StickySettings* GetStickySettings() { +StickySettings* GetStickySettings() { return g_sticky_settings.Pointer(); } @@ -769,7 +760,7 @@ GetSettingsDictionary(json_str); CHECK(settings); int request_id = -1; - settings->GetInteger(printing::kPreviewRequestID, &request_id); + settings->GetInteger(kPreviewRequestID, &request_id); CHECK_GT(request_id, -1); CHECK(!base::ContainsKey(preview_callbacks_, request_id)); @@ -777,7 +768,7 @@ print_preview_ui()->OnPrintPreviewRequest(request_id); // Add an additional key in order to identify |print_preview_ui| later on // when calling PrintPreviewUI::ShouldCancelRequest() on the IO thread. - settings->SetInteger(printing::kPreviewUIID, + settings->SetInteger(kPreviewUIID, print_preview_ui()->GetIDForPrintPreviewUI().value()); // Increment request count. @@ -797,18 +788,17 @@ // Retrieve the page title and url and send it to the renderer process if // headers and footers are to be displayed. bool display_header_footer = false; - bool success = settings->GetBoolean(printing::kSettingHeaderFooterEnabled, - &display_header_footer); + bool success = + settings->GetBoolean(kSettingHeaderFooterEnabled, &display_header_footer); DCHECK(success); if (display_header_footer) { - settings->SetString(printing::kSettingHeaderFooterTitle, - initiator->GetTitle()); + settings->SetString(kSettingHeaderFooterTitle, initiator->GetTitle()); url::Replacements<char> url_sanitizer; url_sanitizer.ClearUsername(); url_sanitizer.ClearPassword(); const GURL& initiator_url = initiator->GetLastCommittedURL(); - settings->SetString(printing::kSettingHeaderFooterURL, + settings->SetString(kSettingHeaderFooterURL, url_formatter::FormatUrl( initiator_url.ReplaceComponents(url_sanitizer))); } @@ -840,7 +830,7 @@ const UserActionBuckets user_action = DetermineUserAction(*settings); int page_count = 0; - if (!settings->GetInteger(printing::kSettingPreviewPageCount, &page_count) || + if (!settings->GetInteger(kSettingPreviewPageCount, &page_count) || page_count <= 0) { RejectJavascriptCallback(base::Value(callback_id), GetErrorValue(user_action, "NO_PAGE_COUNT")); @@ -849,7 +839,7 @@ scoped_refptr<base::RefCountedMemory> data; print_preview_ui()->GetPrintPreviewDataForIndex( - printing::COMPLETE_PREVIEW_DOCUMENT_INDEX, &data); + COMPLETE_PREVIEW_DOCUMENT_INDEX, &data); if (!data) { // Nothing to print, no preview available. RejectJavascriptCallback(base::Value(callback_id), @@ -865,12 +855,12 @@ int width = 0; int height = 0; if (user_action == PRINT_WITH_PRIVET || user_action == PRINT_WITH_EXTENSION) { - if (!settings->GetString(printing::kSettingDeviceName, &destination_id) || - !settings->GetString(printing::kSettingTicket, &print_ticket) || - !settings->GetString(printing::kSettingCapabilities, &capabilities) || - !settings->GetInteger(printing::kSettingPageWidth, &width) || - !settings->GetInteger(printing::kSettingPageHeight, &height) || - width <= 0 || height <= 0) { + if (!settings->GetString(kSettingDeviceName, &destination_id) || + !settings->GetString(kSettingTicket, &print_ticket) || + !settings->GetString(kSettingCapabilities, &capabilities) || + !settings->GetInteger(kSettingPageWidth, &width) || + !settings->GetInteger(kSettingPageHeight, &height) || width <= 0 || + height <= 0) { NOTREACHED(); RejectJavascriptCallback(base::Value(callback_id), GetErrorValue(user_action, "FAILED")); @@ -926,7 +916,7 @@ void PrintPreviewHandler::HandleSaveAppState(const base::ListValue* args) { std::string data_to_save; - printing::StickySettings* sticky_settings = GetStickySettings(); + StickySettings* sticky_settings = GetStickySettings(); if (args->GetString(0, &data_to_save) && !data_to_save.empty()) sticky_settings->StoreAppState(data_to_save); sticky_settings->SaveInPrefs(GetPrefs()); @@ -1053,15 +1043,15 @@ base::DictionaryValue initial_settings; initial_settings.SetString(kDocumentTitle, print_preview_ui()->initiator_title()); - initial_settings.SetBoolean(printing::kSettingPreviewModifiable, + initial_settings.SetBoolean(kSettingPreviewModifiable, print_preview_ui()->source_is_modifiable()); - initial_settings.SetString(printing::kSettingPrinterName, default_printer); + initial_settings.SetString(kSettingPrinterName, default_printer); initial_settings.SetBoolean(kDocumentHasSelection, print_preview_ui()->source_has_selection()); - initial_settings.SetBoolean(printing::kSettingShouldPrintSelectionOnly, + initial_settings.SetBoolean(kSettingShouldPrintSelectionOnly, print_preview_ui()->print_selection_only()); PrefService* prefs = GetPrefs(); - printing::StickySettings* sticky_settings = GetStickySettings(); + StickySettings* sticky_settings = GetStickySettings(); sticky_settings->RestoreFromPrefs(prefs); if (sticky_settings->printer_app_state()) { initial_settings.SetString(kAppState, @@ -1113,7 +1103,7 @@ base::Value settings_info) { // Check that |settings_info| is valid. if (settings_info.is_dict() && - settings_info.FindKeyOfType(printing::kSettingCapabilities, + settings_info.FindKeyOfType(kSettingCapabilities, base::Value::Type::DICTIONARY)) { VLOG(1) << "Get printer capabilities finished"; ResolveJavascriptCallback(base::Value(callback_id), settings_info); @@ -1130,7 +1120,7 @@ base::Value response(base::Value::Type::DICTIONARY); base::Value* caps_value = destination_info.is_dict() - ? destination_info.FindKeyOfType(printing::kSettingCapabilities, + ? destination_info.FindKeyOfType(kSettingCapabilities, base::Value::Type::DICTIONARY) : nullptr; response.SetKey("printerId", base::Value(printer_name)); @@ -1139,11 +1129,11 @@ caps_value ? std::move(*caps_value) : base::Value(base::Value::Type::DICTIONARY)); if (caps_value) { - base::Value* printer = destination_info.FindKeyOfType( - printing::kPrinter, base::Value::Type::DICTIONARY); + base::Value* printer = + destination_info.FindKeyOfType(kPrinter, base::Value::Type::DICTIONARY); if (printer) { base::Value* policies_value = printer->FindKeyOfType( - printing::kSettingPolicies, base::Value::Type::DICTIONARY); + kSettingPolicies, base::Value::Type::DICTIONARY); if (policies_value) response.SetKey("policies", std::move(*policies_value)); } @@ -1181,8 +1171,8 @@ } WebContents* PrintPreviewHandler::GetInitiator() const { - printing::PrintPreviewDialogController* dialog_controller = - printing::PrintPreviewDialogController::GetInstance(); + PrintPreviewDialogController* dialog_controller = + PrintPreviewDialogController::GetInstance(); if (!dialog_controller) return NULL; return dialog_controller->GetInitiator(preview_web_contents()); @@ -1297,8 +1287,8 @@ // We no longer require the initiator details. Remove those details associated // with the preview dialog to allow the initiator to create another preview // dialog. - printing::PrintPreviewDialogController* dialog_controller = - printing::PrintPreviewDialogController::GetInstance(); + PrintPreviewDialogController* dialog_controller = + PrintPreviewDialogController::GetInstance(); if (dialog_controller) dialog_controller->EraseInitiatorInfo(preview_web_contents()); } @@ -1353,7 +1343,7 @@ GetPrinterHandler(PrinterType::kPdfPrinter)); } -void PrintPreviewHandler::OnAddedPrinters(printing::PrinterType printer_type, +void PrintPreviewHandler::OnAddedPrinters(PrinterType printer_type, const base::ListValue& printers) { DCHECK(printer_type == PrinterType::kExtensionPrinter || printer_type == PrinterType::kPrivetPrinter || @@ -1392,7 +1382,7 @@ // Remove the preview dialog from the background printing manager if it is // being stored there. Since the PDF has been sent and the callback is // resolved or rejected, it is no longer needed and can be destroyed. - printing::BackgroundPrintingManager* background_printing_manager = + BackgroundPrintingManager* background_printing_manager = g_browser_process->background_printing_manager(); if (background_printing_manager->HasPrintPreviewDialog( preview_web_contents())) { @@ -1442,3 +1432,5 @@ const base::DictionaryValue& settings) { FireWebUIListener("manipulate-settings-for-test", settings); } + +} // namespace printing
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler.h b/chrome/browser/ui/webui/print_preview/print_preview_handler.h index e340c350..35d8bca 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_handler.h +++ b/chrome/browser/ui/webui/print_preview/print_preview_handler.h
@@ -22,10 +22,6 @@ #include "printing/backend/print_backend.h" #include "printing/buildflags/buildflags.h" -class PdfPrinterHandler; -class PrinterHandler; -class PrintPreviewUI; - namespace base { class DictionaryValue; class RefCountedMemory; @@ -37,6 +33,10 @@ namespace printing { +class PdfPrinterHandler; +class PrinterHandler; +class PrintPreviewUI; + // Must match print_preview.PrinterType in // chrome/browser/resources/print_preview/native_layer.js enum PrinterType { @@ -47,8 +47,6 @@ kCloudPrinter }; -} // namespace printing - // The handler for Javascript messages related to the print preview dialog. class PrintPreviewHandler : public content::WebUIMessageHandler, @@ -126,7 +124,7 @@ protected: // Protected so unit tests can override. - virtual PrinterHandler* GetPrinterHandler(printing::PrinterType printer_type); + virtual PrinterHandler* GetPrinterHandler(PrinterType printer_type); // Shuts down the initiator renderer. Called when a bad IPC message is // received. @@ -280,7 +278,7 @@ // |printer_type|: The type of printers that were added. // |printers|: A non-empty list containing information about the printer or // printers that have been added. - void OnAddedPrinters(printing::PrinterType printer_type, + void OnAddedPrinters(PrinterType printer_type, const base::ListValue& printers); // Called when printer search is done for some destination type. @@ -355,4 +353,6 @@ DISALLOW_COPY_AND_ASSIGN(PrintPreviewHandler); }; +} // namespace printing + #endif // CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PRINT_PREVIEW_HANDLER_H_
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc b/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc index 26ebe83..c255db8e0 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_handler_unittest.cc
@@ -14,6 +14,7 @@ #include "base/json/json_writer.h" #include "base/memory/ref_counted_memory.h" #include "base/optional.h" +#include "base/stl_util.h" #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" #include "base/test/icu_test_util.h" @@ -45,10 +46,9 @@ const char kDummyInitiatorName[] = "TestInitiator"; const char kTestData[] = "abc"; -// Array of all printing::PrinterType values. -const printing::PrinterType kAllTypes[] = { - printing::kPrivetPrinter, printing::kExtensionPrinter, - printing::kPdfPrinter, printing::kLocalPrinter}; +// Array of all PrinterType values. +const PrinterType kAllTypes[] = {kPrivetPrinter, kExtensionPrinter, kPdfPrinter, + kLocalPrinter}; struct PrinterInfo { std::string id; @@ -241,8 +241,6 @@ } // namespace -} // namespace printing - class PrintPreviewHandlerTest : public testing::Test { public: PrintPreviewHandlerTest() = default; @@ -256,37 +254,35 @@ content::WebContents* initiator = initiator_web_contents_.get(); preview_web_contents_ = content::WebContents::Create( content::WebContents::CreateParams(profile_.get())); - printing::PrintViewManager::CreateForWebContents(initiator); - printing::PrintViewManager::FromWebContents(initiator)->PrintPreviewNow( + PrintViewManager::CreateForWebContents(initiator); + PrintViewManager::FromWebContents(initiator)->PrintPreviewNow( initiator->GetMainFrame(), false); web_ui_ = std::make_unique<content::TestWebUI>(); web_ui_->set_web_contents(preview_web_contents_.get()); - printers_.push_back( - printing::GetSimplePrinterInfo(printing::kDummyPrinterName, true)); + printers_.push_back(GetSimplePrinterInfo(kDummyPrinterName, true)); auto printer_handler = CreatePrinterHandler(printers_); printer_handler_ = printer_handler.get(); - auto preview_handler = std::make_unique<printing::TestPrintPreviewHandler>( + auto preview_handler = std::make_unique<TestPrintPreviewHandler>( std::move(printer_handler), initiator); preview_handler->set_web_ui(web_ui()); handler_ = preview_handler.get(); - auto preview_ui = std::make_unique<printing::FakePrintPreviewUI>( + auto preview_ui = std::make_unique<FakePrintPreviewUI>( web_ui(), std::move(preview_handler)); - preview_ui->SetInitiatorTitle( - base::ASCIIToUTF16(printing::kDummyInitiatorName)); + preview_ui->SetInitiatorTitle(base::ASCIIToUTF16(kDummyInitiatorName)); web_ui()->SetController(std::move(preview_ui)); } void TearDown() override { - printing::PrintViewManager::FromWebContents(initiator_web_contents_.get()) + PrintViewManager::FromWebContents(initiator_web_contents_.get()) ->PrintPreviewDone(); } - virtual std::unique_ptr<printing::TestPrinterHandler> CreatePrinterHandler( - const std::vector<printing::PrinterInfo>& printers) { - return std::make_unique<printing::TestPrinterHandler>(printers); + virtual std::unique_ptr<TestPrinterHandler> CreatePrinterHandler( + const std::vector<PrinterInfo>& printers) { + return std::make_unique<TestPrinterHandler>(printers); } void Initialize() { @@ -406,9 +402,9 @@ const Profile* profile() { return profile_.get(); } PrefService* prefs() { return profile_->GetPrefs(); } content::TestWebUI* web_ui() { return web_ui_.get(); } - printing::TestPrintPreviewHandler* handler() { return handler_; } - printing::TestPrinterHandler* printer_handler() { return printer_handler_; } - std::vector<printing::PrinterInfo>& printers() { return printers_; } + TestPrintPreviewHandler* handler() { return handler_; } + TestPrinterHandler* printer_handler() { return printer_handler_; } + std::vector<PrinterInfo>& printers() { return printers_; } private: content::TestBrowserThreadBundle thread_bundle_; @@ -417,9 +413,9 @@ content::RenderViewHostTestEnabler rvh_test_enabler_; std::unique_ptr<content::WebContents> preview_web_contents_; std::unique_ptr<content::WebContents> initiator_web_contents_; - std::vector<printing::PrinterInfo> printers_; - printing::TestPrinterHandler* printer_handler_; - printing::TestPrintPreviewHandler* handler_; + std::vector<PrinterInfo> printers_; + TestPrinterHandler* printer_handler_; + TestPrintPreviewHandler* handler_; DISALLOW_COPY_AND_ASSIGN(PrintPreviewHandlerTest); }; @@ -428,9 +424,8 @@ Initialize(); // Verify initial settings were sent. - ValidateInitialSettings(*web_ui()->call_data().back(), - printing::kDummyPrinterName, - printing::kDummyInitiatorName, {}); + ValidateInitialSettings(*web_ui()->call_data().back(), kDummyPrinterName, + kDummyInitiatorName, {}); // Check that the use-cloud-print event got sent AssertWebUIEventFired(*web_ui()->call_data().front(), "use-cloud-print"); @@ -440,18 +435,16 @@ // Set a pref that should take priority over StickySettings. prefs()->SetBoolean(prefs::kPrintHeaderFooter, true); Initialize(); - ValidateInitialSettings(*web_ui()->call_data().back(), - printing::kDummyPrinterName, - printing::kDummyInitiatorName, true); + ValidateInitialSettings(*web_ui()->call_data().back(), kDummyPrinterName, + kDummyInitiatorName, true); } TEST_F(PrintPreviewHandlerTest, InitialSettingsDisableHeaderFooter) { // Set a pref that should take priority over StickySettings. prefs()->SetBoolean(prefs::kPrintHeaderFooter, false); Initialize(); - ValidateInitialSettings(*web_ui()->call_data().back(), - printing::kDummyPrinterName, - printing::kDummyInitiatorName, false); + ValidateInitialSettings(*web_ui()->call_data().back(), kDummyPrinterName, + kDummyInitiatorName, false); } TEST_F(PrintPreviewHandlerTest, GetPrinters) { @@ -459,11 +452,10 @@ // Check all three printer types that implement // PrinterHandler::StartGetPrinters(). - const printing::PrinterType types[] = {printing::kPrivetPrinter, - printing::kExtensionPrinter, - printing::kLocalPrinter}; - for (size_t i = 0; i < arraysize(types); i++) { - printing::PrinterType type = types[i]; + const PrinterType types[] = {kPrivetPrinter, kExtensionPrinter, + kLocalPrinter}; + for (size_t i = 0; i < base::size(types); i++) { + PrinterType type = types[i]; handler()->reset_calls(); base::Value args(base::Value::Type::LIST); std::string callback_id_in = @@ -500,7 +492,7 @@ TEST_F(PrintPreviewHandlerTest, GetPrinterCapabilities) { // Add an empty printer to the handler. - printers().push_back(printing::GetEmptyPrinterInfo()); + printers().push_back(GetEmptyPrinterInfo()); printer_handler()->SetPrinters(printers()); // Initial settings first to enable javascript. @@ -508,14 +500,14 @@ // Check all four printer types that implement // PrinterHandler::StartGetCapability(). - for (size_t i = 0; i < arraysize(printing::kAllTypes); i++) { - printing::PrinterType type = printing::kAllTypes[i]; + for (size_t i = 0; i < base::size(kAllTypes); i++) { + PrinterType type = kAllTypes[i]; handler()->reset_calls(); base::Value args(base::Value::Type::LIST); std::string callback_id_in = "test-callback-id-" + base::UintToString(i + 1); args.GetList().emplace_back(callback_id_in); - args.GetList().emplace_back(printing::kDummyPrinterName); + args.GetList().emplace_back(kDummyPrinterName); args.GetList().emplace_back(type); std::unique_ptr<base::ListValue> list_args = base::ListValue::From(base::Value::ToUniquePtrValue(std::move(args))); @@ -531,19 +523,18 @@ CheckWebUIResponse(data, callback_id_in, true); const base::Value* settings = data.arg3(); ASSERT_TRUE(settings); - EXPECT_TRUE(settings->FindKeyOfType(printing::kSettingCapabilities, + EXPECT_TRUE(settings->FindKeyOfType(kSettingCapabilities, base::Value::Type::DICTIONARY)); } // Run through the loop again, this time with a printer that has no // capabilities. - for (size_t i = 0; i < arraysize(printing::kAllTypes); i++) { - printing::PrinterType type = printing::kAllTypes[i]; + for (size_t i = 0; i < base::size(kAllTypes); i++) { + PrinterType type = kAllTypes[i]; handler()->reset_calls(); base::Value args(base::Value::Type::LIST); std::string callback_id_in = - "test-callback-id-" + - base::UintToString(i + arraysize(printing::kAllTypes) + 1); + "test-callback-id-" + base::UintToString(i + base::size(kAllTypes) + 1); args.GetList().emplace_back(callback_id_in); args.GetList().emplace_back("EmptyPrinter"); args.GetList().emplace_back(type); @@ -552,10 +543,9 @@ handler()->HandleGetPrinterCapabilities(list_args.get()); EXPECT_TRUE(handler()->CalledOnlyForType(type)); - // Start with 2 calls from initial settings plus - // arraysize(printing::kAllTypes) from first loop, then add 1 more for each - // loop iteration. - ASSERT_EQ(2u + arraysize(printing::kAllTypes) + (i + 1), + // Start with 2 calls from initial settings plus base::size(kAllTypes) from + // first loop, then add 1 more for each loop iteration. + ASSERT_EQ(2u + base::size(kAllTypes) + (i + 1), web_ui()->call_data().size()); // Verify printer capabilities promise was rejected. @@ -568,17 +558,16 @@ Initialize(); // All four printer types can print, as well as cloud printers. - for (size_t i = 0; i <= arraysize(printing::kAllTypes); i++) { + for (size_t i = 0; i <= base::size(kAllTypes); i++) { // Also check cloud print. Use dummy type value of Privet (will be ignored). - bool cloud = i == arraysize(printing::kAllTypes); - printing::PrinterType type = - cloud ? printing::kPrivetPrinter : printing::kAllTypes[i]; + bool cloud = i == base::size(kAllTypes); + PrinterType type = cloud ? kPrivetPrinter : kAllTypes[i]; handler()->reset_calls(); base::Value args(base::Value::Type::LIST); std::string callback_id_in = "test-callback-id-" + base::UintToString(i + 1); args.GetList().emplace_back(callback_id_in); - base::Value print_ticket = printing::GetPrintTicket(type, cloud); + base::Value print_ticket = GetPrintTicket(type, cloud); std::string json; base::JSONWriter::Write(print_ticket, &json); args.GetList().emplace_back(json); @@ -603,7 +592,7 @@ std::string print_data; ASSERT_TRUE(data.arg3()->GetAsString(&print_data)); std::string expected_data; - base::Base64Encode(printing::kTestData, &expected_data); + base::Base64Encode(kTestData, &expected_data); EXPECT_EQ(print_data, expected_data); } } @@ -612,9 +601,9 @@ TEST_F(PrintPreviewHandlerTest, GetPreview) { Initialize(); - base::Value print_ticket = printing::GetPrintPreviewTicket(false); + base::Value print_ticket = GetPrintPreviewTicket(false); std::unique_ptr<base::ListValue> list_args = - printing::ConstructPreviewArgs("test-callback-id-1", print_ticket); + ConstructPreviewArgs("test-callback-id-1", print_ticket); handler()->HandleGetPreview(list_args.get()); // Verify that the preview was requested from the renderer with the @@ -622,7 +611,7 @@ base::DictionaryValue preview_params = VerifyPreviewMessage(); bool preview_id_found = false; for (const auto& it : preview_params.DictItems()) { - if (it.first == printing::kPreviewUIID) { // This is added by the handler. + if (it.first == kPreviewUIID) { // This is added by the handler. preview_id_found = true; continue; } @@ -637,20 +626,19 @@ Initialize(); const char callback_id_in[] = "test-callback-id-1"; - base::Value print_ticket = printing::GetPrintPreviewTicket(false); + base::Value print_ticket = GetPrintPreviewTicket(false); std::unique_ptr<base::ListValue> list_args = - printing::ConstructPreviewArgs(callback_id_in, print_ticket); + ConstructPreviewArgs(callback_id_in, print_ticket); handler()->HandleGetPreview(list_args.get()); base::DictionaryValue preview_params = VerifyPreviewMessage(); // Read the preview UI ID and request ID - const base::Value* request_value = - preview_params.FindKey(printing::kPreviewRequestID); + const base::Value* request_value = preview_params.FindKey(kPreviewRequestID); ASSERT_TRUE(request_value); ASSERT_TRUE(request_value->is_int()); int preview_request_id = request_value->GetInt(); - const base::Value* ui_value = preview_params.FindKey(printing::kPreviewUIID); + const base::Value* ui_value = preview_params.FindKey(kPreviewUIID); ASSERT_TRUE(ui_value); ASSERT_TRUE(ui_value->is_int()); int preview_ui_id = ui_value->GetInt(); @@ -658,16 +646,16 @@ // Simulate renderer responses: PageLayoutReady, PageCountReady, // PagePreviewReady, and OnPrintPreviewReady will be called in that order. base::DictionaryValue layout; - layout.SetKey(printing::kSettingMarginTop, base::Value(34.0)); - layout.SetKey(printing::kSettingMarginLeft, base::Value(34.0)); - layout.SetKey(printing::kSettingMarginBottom, base::Value(34.0)); - layout.SetKey(printing::kSettingMarginRight, base::Value(34.0)); - layout.SetKey(printing::kSettingContentWidth, base::Value(544.0)); - layout.SetKey(printing::kSettingContentHeight, base::Value(700.0)); - layout.SetKey(printing::kSettingPrintableAreaX, base::Value(17)); - layout.SetKey(printing::kSettingPrintableAreaY, base::Value(17)); - layout.SetKey(printing::kSettingPrintableAreaWidth, base::Value(578)); - layout.SetKey(printing::kSettingPrintableAreaHeight, base::Value(734)); + layout.SetKey(kSettingMarginTop, base::Value(34.0)); + layout.SetKey(kSettingMarginLeft, base::Value(34.0)); + layout.SetKey(kSettingMarginBottom, base::Value(34.0)); + layout.SetKey(kSettingMarginRight, base::Value(34.0)); + layout.SetKey(kSettingContentWidth, base::Value(544.0)); + layout.SetKey(kSettingContentHeight, base::Value(700.0)); + layout.SetKey(kSettingPrintableAreaX, base::Value(17)); + layout.SetKey(kSettingPrintableAreaY, base::Value(17)); + layout.SetKey(kSettingPrintableAreaWidth, base::Value(578)); + layout.SetKey(kSettingPrintableAreaHeight, base::Value(734)); handler()->SendPageLayoutReady(layout, false, preview_request_id); // Verify that page-layout-ready webUI event was fired. @@ -703,10 +691,9 @@ EXPECT_EQ(handler()->bad_messages(), 3); } -class FailingTestPrinterHandler : public printing::TestPrinterHandler { +class FailingTestPrinterHandler : public TestPrinterHandler { public: - explicit FailingTestPrinterHandler( - const std::vector<printing::PrinterInfo>& printers) + explicit FailingTestPrinterHandler(const std::vector<PrinterInfo>& printers) : TestPrinterHandler(printers) {} ~FailingTestPrinterHandler() override = default; @@ -725,8 +712,8 @@ PrintPreviewHandlerFailingTest() = default; ~PrintPreviewHandlerFailingTest() override = default; - std::unique_ptr<printing::TestPrinterHandler> CreatePrinterHandler( - const std::vector<printing::PrinterInfo>& printers) override { + std::unique_ptr<TestPrinterHandler> CreatePrinterHandler( + const std::vector<PrinterInfo>& printers) override { return std::make_unique<FailingTestPrinterHandler>(printers); } @@ -740,7 +727,7 @@ // handling path. Failure is different from getting no capabilities. TEST_F(PrintPreviewHandlerFailingTest, GetPrinterCapabilities) { // Add an empty printer to the handler. - printers().push_back(printing::GetEmptyPrinterInfo()); + printers().push_back(GetEmptyPrinterInfo()); printer_handler()->SetPrinters(printers()); // Initial settings first to enable javascript. @@ -748,14 +735,14 @@ // Check all four printer types that implement // PrinterHandler::StartGetCapability(). - for (size_t i = 0; i < base::size(printing::kAllTypes); i++) { - printing::PrinterType type = printing::kAllTypes[i]; + for (size_t i = 0; i < base::size(kAllTypes); i++) { + PrinterType type = kAllTypes[i]; handler()->reset_calls(); base::Value args(base::Value::Type::LIST); std::string callback_id_in = "test-callback-id-" + base::UintToString(i + 1); args.GetList().emplace_back(callback_id_in); - args.GetList().emplace_back(printing::kDummyPrinterName); + args.GetList().emplace_back(kDummyPrinterName); args.GetList().emplace_back(type); std::unique_ptr<base::ListValue> list_args = base::ListValue::From(base::Value::ToUniquePtrValue(std::move(args))); @@ -774,3 +761,5 @@ EXPECT_TRUE(settings->is_none()); } } + +} // namespace printing
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc index c346a72..1e5839b 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_ui.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.cc
@@ -66,7 +66,8 @@ #endif using content::WebContents; -using printing::PageSizeMargins; + +namespace printing { namespace { @@ -136,7 +137,7 @@ // Parameters (< > required): // <PrintPreviewUIID> = PrintPreview UI ID // <PageIndex> = Page index is zero-based or -// |printing::COMPLETE_PREVIEW_DOCUMENT_INDEX| to represent +// |COMPLETE_PREVIEW_DOCUMENT_INDEX| to represent // a print ready PDF. // // Example: @@ -562,7 +563,7 @@ void PrintPreviewUI::OnPrintPreviewDialogClosed() { WebContents* preview_dialog = web_ui()->GetWebContents(); - printing::BackgroundPrintingManager* background_printing_manager = + BackgroundPrintingManager* background_printing_manager = g_browser_process->background_printing_manager(); if (background_printing_manager->HasPrintPreviewDialog(preview_dialog)) return; @@ -573,7 +574,7 @@ // Should only get here if the initiator was still tracked by the Print // Preview Dialog Controller, so the print job has not yet been sent. WebContents* preview_dialog = web_ui()->GetWebContents(); - printing::BackgroundPrintingManager* background_printing_manager = + BackgroundPrintingManager* background_printing_manager = g_browser_process->background_printing_manager(); if (background_printing_manager->HasPrintPreviewDialog(preview_dialog)) { // Dialog is hidden but is still generating the preview. Cancel the print @@ -632,18 +633,16 @@ printable_area_ = printable_area; base::DictionaryValue layout; - layout.SetDouble(printing::kSettingMarginTop, page_layout.margin_top); - layout.SetDouble(printing::kSettingMarginLeft, page_layout.margin_left); - layout.SetDouble(printing::kSettingMarginBottom, page_layout.margin_bottom); - layout.SetDouble(printing::kSettingMarginRight, page_layout.margin_right); - layout.SetDouble(printing::kSettingContentWidth, page_layout.content_width); - layout.SetDouble(printing::kSettingContentHeight, page_layout.content_height); - layout.SetInteger(printing::kSettingPrintableAreaX, printable_area.x()); - layout.SetInteger(printing::kSettingPrintableAreaY, printable_area.y()); - layout.SetInteger(printing::kSettingPrintableAreaWidth, - printable_area.width()); - layout.SetInteger(printing::kSettingPrintableAreaHeight, - printable_area.height()); + layout.SetDouble(kSettingMarginTop, page_layout.margin_top); + layout.SetDouble(kSettingMarginLeft, page_layout.margin_left); + layout.SetDouble(kSettingMarginBottom, page_layout.margin_bottom); + layout.SetDouble(kSettingMarginRight, page_layout.margin_right); + layout.SetDouble(kSettingContentWidth, page_layout.content_width); + layout.SetDouble(kSettingContentHeight, page_layout.content_height); + layout.SetInteger(kSettingPrintableAreaX, printable_area.x()); + layout.SetInteger(kSettingPrintableAreaY, printable_area.y()); + layout.SetInteger(kSettingPrintableAreaWidth, printable_area.width()); + layout.SetInteger(kSettingPrintableAreaHeight, printable_area.height()); handler_->SendPageLayoutReady(layout, has_custom_page_size_style, request_id); } @@ -687,8 +686,7 @@ initial_preview_start_time_ = base::TimeTicks(); } - SetPrintPreviewDataForIndex(printing::COMPLETE_PREVIEW_DOCUMENT_INDEX, - std::move(data)); + SetPrintPreviewDataForIndex(COMPLETE_PREVIEW_DOCUMENT_INDEX, std::move(data)); handler_->OnPrintPreviewReady(*id_, preview_request_id); } @@ -707,7 +705,7 @@ void PrintPreviewUI::OnHidePreviewDialog() { WebContents* preview_dialog = web_ui()->GetWebContents(); - printing::BackgroundPrintingManager* background_printing_manager = + BackgroundPrintingManager* background_printing_manager = g_browser_process->background_printing_manager(); if (background_printing_manager->HasPrintPreviewDialog(preview_dialog)) return; @@ -779,3 +777,5 @@ id_ = g_print_preview_ui_id_map.Get().Add(this); g_print_preview_request_id_map.Get().Set(*id_, -1); } + +} // namespace printing
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui.h b/chrome/browser/ui/webui/print_preview/print_preview_ui.h index 7a5c43e63..3af93ad 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_ui.h +++ b/chrome/browser/ui/webui/print_preview/print_preview_ui.h
@@ -21,7 +21,6 @@ #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" -class PrintPreviewHandler; struct PrintHostMsg_DidStartPreview_Params; struct PrintHostMsg_PreviewIds; struct PrintHostMsg_RequestPrintPreview_Params; @@ -38,8 +37,9 @@ } namespace printing { + +class PrintPreviewHandler; struct PageSizeMargins; -} class PrintPreviewUI : public ConstrainedWebDialogUI { public: @@ -48,8 +48,7 @@ ~PrintPreviewUI() override; // Gets the print preview |data|. |index| is zero-based, and can be - // |printing::COMPLETE_PREVIEW_DOCUMENT_INDEX| to get the entire preview - // document. + // |COMPLETE_PREVIEW_DOCUMENT_INDEX| to get the entire preview document. virtual void GetPrintPreviewDataForIndex( int index, scoped_refptr<base::RefCountedMemory>* data) const; @@ -106,7 +105,7 @@ // Notifies the Web UI of the default page layout according to the currently // selected printer and page size. - void OnDidGetDefaultPageLayout(const printing::PageSizeMargins& page_layout, + void OnDidGetDefaultPageLayout(const PageSizeMargins& page_layout, const gfx::Rect& printable_area, bool has_custom_page_size_style, int request_id); @@ -211,11 +210,9 @@ private: FRIEND_TEST_ALL_PREFIXES(PrintPreviewDialogControllerUnitTest, TitleAfterReload); - friend class FakePrintPreviewUI; // Sets the print preview |data|. |index| is zero-based, and can be - // |printing::COMPLETE_PREVIEW_DOCUMENT_INDEX| to set the entire preview - // document. + // |COMPLETE_PREVIEW_DOCUMENT_INDEX| to set the entire preview document. void SetPrintPreviewDataForIndex(int index, scoped_refptr<base::RefCountedMemory> data); @@ -268,4 +265,6 @@ DISALLOW_COPY_AND_ASSIGN(PrintPreviewUI); }; +} // namespace printing + #endif // CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PRINT_PREVIEW_UI_H_
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc b/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc index c385a358..38c43b9 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_ui_unittest.cc
@@ -27,6 +27,8 @@ using content::WebContents; using web_modal::WebContentsModalDialogManager; +namespace printing { + namespace { scoped_refptr<base::RefCountedBytes> CreateTestData() { @@ -71,12 +73,12 @@ ASSERT_TRUE(initiator); EXPECT_FALSE(IsShowingWebContentsModalDialog(initiator)); - printing::PrintPreviewDialogController* controller = - printing::PrintPreviewDialogController::GetInstance(); + PrintPreviewDialogController* controller = + PrintPreviewDialogController::GetInstance(); ASSERT_TRUE(controller); - printing::PrintViewManager* print_view_manager = - printing::PrintViewManager::FromWebContents(initiator); + PrintViewManager* print_view_manager = + PrintViewManager::FromWebContents(initiator); print_view_manager->PrintPreviewNow(initiator->GetMainFrame(), false); WebContents* preview_dialog = controller->GetOrCreatePreviewDialog(initiator); @@ -90,27 +92,24 @@ preview_ui->SetPreviewUIId(); scoped_refptr<base::RefCountedMemory> data; - preview_ui->GetPrintPreviewDataForIndex( - printing::COMPLETE_PREVIEW_DOCUMENT_INDEX, - &data); + preview_ui->GetPrintPreviewDataForIndex(COMPLETE_PREVIEW_DOCUMENT_INDEX, + &data); EXPECT_FALSE(data); scoped_refptr<base::RefCountedBytes> dummy_data = CreateTestData(); preview_ui->SetPrintPreviewDataForIndexForTest( - printing::COMPLETE_PREVIEW_DOCUMENT_INDEX, dummy_data.get()); - preview_ui->GetPrintPreviewDataForIndex( - printing::COMPLETE_PREVIEW_DOCUMENT_INDEX, - &data); + COMPLETE_PREVIEW_DOCUMENT_INDEX, dummy_data.get()); + preview_ui->GetPrintPreviewDataForIndex(COMPLETE_PREVIEW_DOCUMENT_INDEX, + &data); EXPECT_EQ(dummy_data->size(), data->size()); EXPECT_EQ(dummy_data.get(), data.get()); // Clear the preview data. preview_ui->ClearAllPreviewDataForTest(); - preview_ui->GetPrintPreviewDataForIndex( - printing::COMPLETE_PREVIEW_DOCUMENT_INDEX, - &data); + preview_ui->GetPrintPreviewDataForIndex(COMPLETE_PREVIEW_DOCUMENT_INDEX, + &data); EXPECT_FALSE(data); } @@ -119,12 +118,12 @@ WebContents* initiator = browser()->tab_strip_model()->GetActiveWebContents(); ASSERT_TRUE(initiator); - printing::PrintPreviewDialogController* controller = - printing::PrintPreviewDialogController::GetInstance(); + PrintPreviewDialogController* controller = + PrintPreviewDialogController::GetInstance(); ASSERT_TRUE(controller); - printing::PrintViewManager* print_view_manager = - printing::PrintViewManager::FromWebContents(initiator); + PrintViewManager* print_view_manager = + PrintViewManager::FromWebContents(initiator); print_view_manager->PrintPreviewNow(initiator->GetMainFrame(), false); WebContents* preview_dialog = controller->GetOrCreatePreviewDialog(initiator); @@ -138,40 +137,37 @@ preview_ui->SetPreviewUIId(); scoped_refptr<base::RefCountedMemory> data; - preview_ui->GetPrintPreviewDataForIndex(printing::FIRST_PAGE_INDEX, &data); + preview_ui->GetPrintPreviewDataForIndex(FIRST_PAGE_INDEX, &data); EXPECT_FALSE(data); scoped_refptr<base::RefCountedBytes> dummy_data = CreateTestData(); - preview_ui->SetPrintPreviewDataForIndexForTest(printing::FIRST_PAGE_INDEX, + preview_ui->SetPrintPreviewDataForIndexForTest(FIRST_PAGE_INDEX, dummy_data.get()); - preview_ui->GetPrintPreviewDataForIndex(printing::FIRST_PAGE_INDEX, &data); + preview_ui->GetPrintPreviewDataForIndex(FIRST_PAGE_INDEX, &data); EXPECT_EQ(dummy_data->size(), data->size()); EXPECT_EQ(dummy_data.get(), data.get()); // Set and get the third page data. - preview_ui->SetPrintPreviewDataForIndexForTest(printing::FIRST_PAGE_INDEX + 2, + preview_ui->SetPrintPreviewDataForIndexForTest(FIRST_PAGE_INDEX + 2, dummy_data.get()); - preview_ui->GetPrintPreviewDataForIndex(printing::FIRST_PAGE_INDEX + 2, - &data); + preview_ui->GetPrintPreviewDataForIndex(FIRST_PAGE_INDEX + 2, &data); EXPECT_EQ(dummy_data->size(), data->size()); EXPECT_EQ(dummy_data.get(), data.get()); // Get the second page data. - preview_ui->GetPrintPreviewDataForIndex(printing::FIRST_PAGE_INDEX + 1, - &data); + preview_ui->GetPrintPreviewDataForIndex(FIRST_PAGE_INDEX + 1, &data); EXPECT_FALSE(data); - preview_ui->SetPrintPreviewDataForIndexForTest(printing::FIRST_PAGE_INDEX + 1, + preview_ui->SetPrintPreviewDataForIndexForTest(FIRST_PAGE_INDEX + 1, dummy_data.get()); - preview_ui->GetPrintPreviewDataForIndex(printing::FIRST_PAGE_INDEX + 1, - &data); + preview_ui->GetPrintPreviewDataForIndex(FIRST_PAGE_INDEX + 1, &data); EXPECT_EQ(dummy_data->size(), data->size()); EXPECT_EQ(dummy_data.get(), data.get()); // Clear the preview data. preview_ui->ClearAllPreviewDataForTest(); - preview_ui->GetPrintPreviewDataForIndex(printing::FIRST_PAGE_INDEX, &data); + preview_ui->GetPrintPreviewDataForIndex(FIRST_PAGE_INDEX, &data); EXPECT_FALSE(data); } @@ -180,12 +176,12 @@ WebContents* initiator = browser()->tab_strip_model()->GetActiveWebContents(); ASSERT_TRUE(initiator); - printing::PrintPreviewDialogController* controller = - printing::PrintPreviewDialogController::GetInstance(); + PrintPreviewDialogController* controller = + PrintPreviewDialogController::GetInstance(); ASSERT_TRUE(controller); - printing::PrintViewManager* print_view_manager = - printing::PrintViewManager::FromWebContents(initiator); + PrintViewManager* print_view_manager = + PrintViewManager::FromWebContents(initiator); print_view_manager->PrintPreviewNow(initiator->GetMainFrame(), false); WebContents* preview_dialog = controller->GetOrCreatePreviewDialog(initiator); @@ -216,3 +212,5 @@ EXPECT_TRUE(preview_ui->ShouldCancelRequest({kFirstRequestId, preview_id})); EXPECT_FALSE(preview_ui->ShouldCancelRequest({kSecondRequestId, preview_id})); } + +} // namespace printing
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_utils.cc b/chrome/browser/ui/webui/print_preview/print_preview_utils.cc index 6d8dc9b..f3db3ad 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_utils.cc +++ b/chrome/browser/ui/webui/print_preview/print_preview_utils.cc
@@ -205,9 +205,9 @@ } bool system_dialog = false; - job_settings->GetBoolean(printing::kSettingShowSystemDialog, &system_dialog); + job_settings->GetBoolean(kSettingShowSystemDialog, &system_dialog); bool open_in_pdf = false; - job_settings->GetBoolean(printing::kSettingOpenPDFInPreview, &open_in_pdf); + job_settings->GetBoolean(kSettingOpenPDFInPreview, &open_in_pdf); if (system_dialog || open_in_pdf) { // Run the callback early, or the modal dialogs will prevent the preview // from closing until they do.
diff --git a/chrome/browser/ui/webui/print_preview/print_preview_utils.h b/chrome/browser/ui/webui/print_preview/print_preview_utils.h index f13e2c1..92016d22 100644 --- a/chrome/browser/ui/webui/print_preview/print_preview_utils.h +++ b/chrome/browser/ui/webui/print_preview/print_preview_utils.h
@@ -32,7 +32,7 @@ void ConvertPrinterListForCallback( const PrinterHandler::AddedPrintersCallback& callback, PrinterHandler::GetPrintersDoneCallback done_callback, - const printing::PrinterList& printer_list); + const PrinterList& printer_list); // Returns a unique_ptr to a sanitized version of |cdd| to prevent possible JS // errors in Print Preview. Will remove null items from lists or options lists
diff --git a/chrome/browser/ui/webui/print_preview/printer_handler.cc b/chrome/browser/ui/webui/print_preview/printer_handler.cc index 4ce4aca1..d5fcabd 100644 --- a/chrome/browser/ui/webui/print_preview/printer_handler.cc +++ b/chrome/browser/ui/webui/print_preview/printer_handler.cc
@@ -20,6 +20,8 @@ #include "chrome/browser/ui/webui/print_preview/local_printer_handler_default.h" #endif +namespace printing { + // static std::unique_ptr<PrinterHandler> PrinterHandler::CreateForCloudPrinters() { return std::make_unique<CloudPrinterHandler>(); @@ -47,7 +49,7 @@ std::unique_ptr<PrinterHandler> PrinterHandler::CreateForPdfPrinter( Profile* profile, content::WebContents* preview_web_contents, - printing::StickySettings* sticky_settings) { + StickySettings* sticky_settings) { return std::make_unique<PdfPrinterHandler>(profile, preview_web_contents, sticky_settings); } @@ -68,3 +70,5 @@ GetPrinterInfoCallback callback) { NOTREACHED(); } + +} // namespace printing
diff --git a/chrome/browser/ui/webui/print_preview/printer_handler.h b/chrome/browser/ui/webui/print_preview/printer_handler.h index 408cb3cd..04b2998 100644 --- a/chrome/browser/ui/webui/print_preview/printer_handler.h +++ b/chrome/browser/ui/webui/print_preview/printer_handler.h
@@ -28,12 +28,12 @@ class Size; } -namespace printing { -class StickySettings; -} - class Profile; +namespace printing { + +class StickySettings; + // Wrapper around PrinterProviderAPI to be used by print preview. // It makes request lifetime management easier, and hides details of more // complex operations like printing from the print preview handler. This class @@ -45,13 +45,12 @@ using AddedPrintersCallback = base::RepeatingCallback<void(const base::ListValue& printers)>; using GetPrintersDoneCallback = base::OnceClosure; - // |capability| should contain a CDD with key printing::kSettingCapabilities. + // |capability| should contain a CDD with key |kSettingCapabilities|. // It may also contain other information about the printer in a dictionary - // with key printing::kPrinter. + // with key |kPrinter|. // If |capability| is null, empty, or does not contain a dictionary with key - // printing::kSettingCapabilities, this indicates a failure to retrieve - // capabilities. - // If the dictionary with key printing::kSettingCapabilities is + // |kSettingCapabilities|, this indicates a failure to retrieve capabilities. + // If the dictionary with key |kSettingCapabilities| is // empty, this indicates capabilities were retrieved but the printer does // not support any of the capability fields in a CDD. using GetCapabilityCallback = @@ -72,7 +71,7 @@ static std::unique_ptr<PrinterHandler> CreateForPdfPrinter( Profile* profile, content::WebContents* preview_web_contents, - printing::StickySettings* sticky_settings); + StickySettings* sticky_settings); static std::unique_ptr<PrinterHandler> CreateForLocalPrinters( content::WebContents* preview_web_contents, @@ -134,4 +133,6 @@ PrintCallback callback) = 0; }; +} // namespace printing + #endif // CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PRINTER_HANDLER_H_
diff --git a/chrome/browser/ui/webui/print_preview/privet_printer_handler.cc b/chrome/browser/ui/webui/print_preview/privet_printer_handler.cc index d01ac56..dceb17b1 100644 --- a/chrome/browser/ui/webui/print_preview/privet_printer_handler.cc +++ b/chrome/browser/ui/webui/print_preview/privet_printer_handler.cc
@@ -26,6 +26,8 @@ #include "services/network/public/cpp/shared_url_loader_factory.h" #include "ui/gfx/geometry/size.h" +namespace printing { + namespace { // Timeout for searching for privet printers, in seconds. const int kSearchTimeoutSec = 5; @@ -198,11 +200,10 @@ std::move(printer_info)); std::unique_ptr<base::DictionaryValue> capabilities_copy = capabilities->CreateDeepCopy(); - printer_info_and_caps.SetDictionary(printing::kSettingCapabilities, + printer_info_and_caps.SetDictionary(kSettingCapabilities, std::move(capabilities_copy)); std::move(capabilities_callback_) - .Run(std::move( - *printing::ValidateCddForPrintPreview(printer_info_and_caps))); + .Run(std::move(*ValidateCddForPrintPreview(printer_info_and_caps))); privet_capabilities_operation_.reset(); } @@ -280,3 +281,5 @@ privet_http_resolution_ = privet_http_factory_->CreatePrivetHTTP(name); privet_http_resolution_->Start(device_description->address, callback); } + +} // namespace printing
diff --git a/chrome/browser/ui/webui/print_preview/privet_printer_handler.h b/chrome/browser/ui/webui/print_preview/privet_printer_handler.h index 4a14f2a..01b84a0 100644 --- a/chrome/browser/ui/webui/print_preview/privet_printer_handler.h +++ b/chrome/browser/ui/webui/print_preview/privet_printer_handler.h
@@ -26,6 +26,8 @@ class Size; } +namespace printing { + // Implementation of PrinterHandler interface class PrivetPrinterHandler : public PrinterHandler, @@ -113,4 +115,7 @@ DISALLOW_COPY_AND_ASSIGN(PrivetPrinterHandler); }; + +} // namespace printing + #endif // CHROME_BROWSER_UI_WEBUI_PRINT_PREVIEW_PRIVET_PRINTER_HANDLER_H_
diff --git a/chrome/service/service_utility_process_host.cc b/chrome/service/service_utility_process_host.cc index 2502239..68664618 100644 --- a/chrome/service/service_utility_process_host.cc +++ b/chrome/service/service_utility_process_host.cc
@@ -361,7 +361,7 @@ // "content_utility". This is all set up here. service_manager_ = std::make_unique<service_manager::ServiceManager>( std::make_unique<NullServiceProcessLauncherFactory>(), - CreateServiceProcessCatalog(), nullptr); + CreateServiceProcessCatalog()); service_manager::mojom::ServicePtr browser_proxy; service_manager_connection_ = content::ServiceManagerConnection::Create(
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index f86af4e..b5d915c 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -2239,8 +2239,6 @@ ] } -# Temporary target for running benchmarks without building Chrome -# Will be removed as a part of crbug.com/758632 group("telemetry_perf_tests_without_chrome") { testonly = true deps = [
diff --git a/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js b/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js index 19def6a..b91c66d 100644 --- a/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js +++ b/chrome/test/data/extensions/api_test/networking_private/chromeos/test.js
@@ -871,9 +871,9 @@ // Connecting to wifi2 should set wifi1 to offline. Connected or Connecting // networks should be listed first, sorted by type. var expected = ['stub_ethernet_guid', - 'stub_wifi2_guid', 'stub_wimax_guid', 'stub_vpn1_guid', + 'stub_wifi2_guid', 'stub_wifi1_guid', 'stub_vpn2_guid']; var done = chrome.test.callbackAdded();
diff --git a/chrome/test/data/webui/welcome/nux_set_as_default_test.js b/chrome/test/data/webui/welcome/nux_set_as_default_test.js new file mode 100644 index 0000000..f76a7ea --- /dev/null +++ b/chrome/test/data/webui/welcome/nux_set_as_default_test.js
@@ -0,0 +1,74 @@ +// Copyright 2018 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. + +cr.define('onboarding_set_as_default_test', function() { + suite('SetAsDefaultTest', function() { + /** @type {NuxSetAsDefaultElement} */ + let testElement; + + /** @type {nux.NuxSetAsDefaultProxy} */ + let testSetAsDefaultProxy; + + /** @type {!Promise} */ + let navigatedPromise; + + setup(function() { + testSetAsDefaultProxy = new TestNuxSetAsDefaultProxy(); + nux.NuxSetAsDefaultProxyImpl.instance_ = testSetAsDefaultProxy; + + navigatedPromise = new Promise(resolve => { + // Spy on navigational function to make sure it's called. + welcome.navigateToNextStep = () => resolve(); + }); + + PolymerTest.clearBody(); + testElement = document.createElement('nux-set-as-default'); + document.body.appendChild(testElement); + }); + + teardown(function() { + testElement.remove(); + }); + + test('skip', function() { + testElement.$['decline-button'].click(); + return testSetAsDefaultProxy.whenCalled('recordSkip'); + }); + + test( + 'click set-default button and finishes setting default', + async function() { + testElement.$$('.action-button').click(); + + await Promise.all([ + testSetAsDefaultProxy.whenCalled('recordBeginSetDefault'), + testSetAsDefaultProxy.whenCalled('setAsDefault'), + ]); + + cr.webUIListenerCallback( + 'browser-default-state-changed', {isDefault: true}); + + return Promise.all([ + testSetAsDefaultProxy.whenCalled('recordSuccessfullySetDefault'), + navigatedPromise + ]); + }); + + test('click set-default button but gives up and skip', async function() { + testElement.$$('.action-button').click(); + + await Promise.all([ + testSetAsDefaultProxy.whenCalled('recordBeginSetDefault'), + testSetAsDefaultProxy.whenCalled('setAsDefault'), + ]); + + testElement.$['decline-button'].click(); + + return Promise.all([ + testSetAsDefaultProxy.whenCalled('recordSkip'), + navigatedPromise, + ]); + }); + }); +});
diff --git a/chrome/test/data/webui/welcome/onboarding_welcome_browsertest.js b/chrome/test/data/webui/welcome/onboarding_welcome_browsertest.js index 13348d3..73ba24bd 100644 --- a/chrome/test/data/webui/welcome/onboarding_welcome_browsertest.js +++ b/chrome/test/data/webui/welcome/onboarding_welcome_browsertest.js
@@ -135,3 +135,22 @@ TEST_F('OnboardingWelcomeModuleMetricsTest', 'All', function() { mocha.run(); }); + +OnboardingWelcomeSetAsDefaultTest = class extends OnboardingWelcomeBrowserTest { + /** @override */ + get browsePreload() { + return 'chrome://welcome/set_as_default/nux_set_as_default.html'; + } + + /** @override */ + get extraLibraries() { + return super.extraLibraries.concat([ + 'nux_set_as_default_test.js', + 'test_nux_set_as_default_proxy.js', + ]); + } +}; + +TEST_F('OnboardingWelcomeSetAsDefaultTest', 'All', function() { + mocha.run(); +});
diff --git a/chromecast/media/cma/backend/filter_group.cc b/chromecast/media/cma/backend/filter_group.cc index 67122abc..e08f759 100644 --- a/chromecast/media/cma/backend/filter_group.cc +++ b/chromecast/media/cma/backend/filter_group.cc
@@ -20,27 +20,24 @@ FilterGroup::FilterGroup(int num_channels, const std::string& name, - std::unique_ptr<PostProcessingPipeline> pipeline, - const base::flat_set<std::string>& device_ids, - const std::vector<FilterGroup*>& mixed_inputs) + std::unique_ptr<PostProcessingPipeline> pipeline) : num_channels_(num_channels), name_(name), - device_ids_(device_ids), - mixed_inputs_(mixed_inputs), playout_channel_selection_(kChannelAll), output_samples_per_second_(0), frames_zeroed_(0), last_volume_(0.0), delay_frames_(0), content_type_(AudioContentType::kMedia), - post_processing_pipeline_(std::move(pipeline)) { - for (auto* const m : mixed_inputs) { - DCHECK_EQ(m->GetOutputChannelCount(), num_channels); - } -} + post_processing_pipeline_(std::move(pipeline)) {} FilterGroup::~FilterGroup() = default; +void FilterGroup::AddMixedInput(FilterGroup* input) { + mixed_inputs_.push_back(input); + DCHECK_EQ(input->GetOutputChannelCount(), num_channels_); +} + void FilterGroup::Initialize(int output_samples_per_second) { output_samples_per_second_ = output_samples_per_second; CHECK(post_processing_pipeline_->SetSampleRate(output_samples_per_second)); @@ -48,10 +45,6 @@ active_inputs_.clear(); } -bool FilterGroup::CanProcessInput(const std::string& input_device_id) { - return !(device_ids_.find(input_device_id) == device_ids_.end()); -} - void FilterGroup::AddInput(MixerInput* input) { active_inputs_.insert(input); if (mixed_) { @@ -235,5 +228,15 @@ post_processing_pipeline_->UpdatePlayoutChannel(playout_channel); } +void FilterGroup::PrintTopology() const { + std::string input_groups; + for (const FilterGroup* mixed_input : mixed_inputs_) { + mixed_input->PrintTopology(); + input_groups += mixed_input->name() + ", "; + } + + LOG(INFO) << input_groups << " -> " << num_channels_ << "ch -> " << name_; +} + } // namespace media } // namespace chromecast
diff --git a/chromecast/media/cma/backend/filter_group.h b/chromecast/media/cma/backend/filter_group.h index 6bc1cb6..960a4da3 100644 --- a/chromecast/media/cma/backend/filter_group.h +++ b/chromecast/media/cma/backend/filter_group.h
@@ -37,32 +37,22 @@ class FilterGroup { public: // |num_channels| indicates number of input audio channels. - // |type| indicates where in the pipeline this FilterGroup sits. // |name| is used for debug printing // |pipeline| - processing pipeline. - // |device_ids| is a set of strings that is used as a filter to determine - // if an InputQueue belongs to this group (InputQueue->name() must exactly - // match an entry in |device_ids| to be processed by this group). - // |mixed_inputs| are FilterGroups that will be mixed into this FilterGroup. - // ex: the final mix ("mix") FilterGroup mixes all other filter groups. - // FilterGroups currently use either InputQueues OR FilterGroups as inputs, - // but there is no technical limitation preventing mixing input classes. - FilterGroup(int num_channels, const std::string& name, - std::unique_ptr<PostProcessingPipeline> pipeline, - const base::flat_set<std::string>& device_ids, - const std::vector<FilterGroup*>& mixed_inputs); + std::unique_ptr<PostProcessingPipeline> pipeline); ~FilterGroup(); + // |input| will be recursively mixed into this FilterGroup's input buffer when + // MixAndFilter() is called. Registering a FilterGroup as an input to more + // than one FilterGroup will result in incorrect behavior. + void AddMixedInput(FilterGroup* input); + // Sets the sample rate of the post-processors. void Initialize(int output_samples_per_second); - // Returns |true| if this FilterGroup is appropriate to process an input with - // the given |input_device_id|. - bool CanProcessInput(const std::string& input_device_id); - // Adds/removes |input| from |active_inputs_|. void AddInput(MixerInput* input); void RemoveInput(MixerInput* input); @@ -108,6 +98,9 @@ // Get content type AudioContentType content_type() const { return content_type_; } + // Recursively print the layout of the pipeline. + void PrintTopology() const; + private: // Resizes temp_ and mixed_ if they are too small to hold |num_frames| frames. // Returns |true| if |num_frames| is larger than all previous |num_frames|. @@ -116,7 +109,6 @@ const int num_channels_; const std::string name_; - const base::flat_set<std::string> device_ids_; std::vector<FilterGroup*> mixed_inputs_; base::flat_set<MixerInput*> active_inputs_;
diff --git a/chromecast/media/cma/backend/filter_group_unittest.cc b/chromecast/media/cma/backend/filter_group_unittest.cc index a36c35f..ac8b068b 100644 --- a/chromecast/media/cma/backend/filter_group_unittest.cc +++ b/chromecast/media/cma/backend/filter_group_unittest.cc
@@ -169,9 +169,7 @@ EXPECT_CALL(*post_processor_, SetContentType(kDefaultContentType)); EXPECT_CALL(*post_processor_, UpdatePlayoutChannel(kDefaultPlayoutChannel)); filter_group_ = std::make_unique<FilterGroup>( - kNumInputChannels, "test_filter", std::move(post_processor), - base::flat_set<std::string>() /* device_ids */, - std::vector<FilterGroup*>()); + kNumInputChannels, "test_filter", std::move(post_processor)); filter_group_->Initialize(kInputSampleRate); filter_group_->AddInput(&input_); filter_group_->UpdatePlayoutChannel(kChannelAll);
diff --git a/chromecast/media/cma/backend/mixer_pipeline.cc b/chromecast/media/cma/backend/mixer_pipeline.cc index 8207b9c..4f8656a8 100644 --- a/chromecast/media/cma/backend/mixer_pipeline.cc +++ b/chromecast/media/cma/backend/mixer_pipeline.cc
@@ -32,15 +32,13 @@ std::unique_ptr<FilterGroup> CreateFilterGroup( int input_channels, const std::string& name, - const base::ListValue* filter_list, - const base::flat_set<std::string>& device_ids, - const std::vector<FilterGroup*>& mixed_inputs, + const base::Value* filter_list, PostProcessingPipelineFactory* ppp_factory) { DCHECK(ppp_factory); auto pipeline = ppp_factory->CreatePipeline(name, filter_list, input_channels); - return std::make_unique<FilterGroup>( - input_channels, name, std::move(pipeline), device_ids, mixed_inputs); + return std::make_unique<FilterGroup>(input_channels, name, + std::move(pipeline)); } } // namespace @@ -64,85 +62,100 @@ PostProcessingPipelineFactory* factory) { DCHECK(config); DCHECK(factory); - base::flat_set<std::string> used_streams; + int mix_group_input_channels = -1; + + // Create "stream" processor groups: for (auto& stream_pipeline : config->GetStreamPipelines()) { - const auto& device_ids = stream_pipeline.stream_types; - for (const std::string& stream_type : device_ids) { - if (!IsOutputDeviceId(stream_type)) { - LOG(ERROR) << stream_type - << " is not a stream type. Stream types are listed " - << "in chromecast/media/base/audio_device_ids.cc and " - << "media/audio/audio_device_description.cc"; - return false; - } - if (!used_streams.insert(stream_type).second) { - LOG(ERROR) << "Multiple instances of stream type '" << stream_type - << "' in " << config->GetFilePath() << "."; - return false; - } - filter_groups_.push_back(CreateFilterGroup( - kNumInputChannels, *device_ids.begin() /* name */, - stream_pipeline.pipeline, device_ids, - std::vector<FilterGroup*>() /* mixed_inputs */, factory)); - if (device_ids.find(::media::AudioDeviceDescription::kDefaultDeviceId) != - device_ids.end()) { - default_stream_group_ = filter_groups_.back().get(); - } + const base::Value* device_ids = stream_pipeline.stream_types; + + DCHECK(!device_ids->GetList().empty()); + DCHECK(device_ids->GetList()[0].is_string()); + filter_groups_.push_back(CreateFilterGroup( + kNumInputChannels, device_ids->GetList()[0].GetString() /* name */, + stream_pipeline.pipeline, factory)); + + if (!SetGroupDeviceIds(device_ids, filter_groups_.back().get())) { + return false; + } + + if (mix_group_input_channels == -1) { + mix_group_input_channels = filter_groups_.back()->GetOutputChannelCount(); + } else if (mix_group_input_channels != + filter_groups_.back()->GetOutputChannelCount()) { + LOG(ERROR) + << "All output stream mixers must have the same number of channels" + << filter_groups_.back()->name() << " has " + << filter_groups_.back()->GetOutputChannelCount() + << " but others have " << mix_group_input_channels; + return false; } } - if (!filter_groups_.empty()) { - std::vector<FilterGroup*> filter_group_ptrs(filter_groups_.size()); - int mix_group_input_channels = filter_groups_[0]->GetOutputChannelCount(); - for (size_t i = 0; i < filter_groups_.size(); ++i) { - if (mix_group_input_channels != - filter_groups_[i]->GetOutputChannelCount()) { - LOG(ERROR) - << "All output stream mixers must have the same number of channels" - << filter_groups_[i]->name() << " has " - << filter_groups_[i]->GetOutputChannelCount() << " but others have " - << mix_group_input_channels; - return false; - } - filter_group_ptrs[i] = filter_groups_[i].get(); - } - - filter_groups_.push_back(CreateFilterGroup( - mix_group_input_channels, "mix", config->GetMixPipeline(), - base::flat_set<std::string>() /* device_ids */, filter_group_ptrs, - factory)); - } else { - // Mix group directly mixes all inputs. - std::string kDefaultDeviceId = - ::media::AudioDeviceDescription::kDefaultDeviceId; - filter_groups_.push_back(CreateFilterGroup( - kNumInputChannels, "mix", config->GetMixPipeline(), - base::flat_set<std::string>({kDefaultDeviceId}), - std::vector<FilterGroup*>() /* mixed_inputs */, factory)); - default_stream_group_ = filter_groups_.back().get(); + if (mix_group_input_channels == -1) { + mix_group_input_channels = kNumInputChannels; } - loopback_output_group_ = filter_groups_.back().get(); + // Create "mix" processor group: + const auto mix_pipeline = config->GetMixPipeline(); + std::unique_ptr<FilterGroup> mix_filter = CreateFilterGroup( + mix_group_input_channels, "mix", mix_pipeline.pipeline, factory); + for (std::unique_ptr<FilterGroup>& group : filter_groups_) { + mix_filter->AddMixedInput(group.get()); + } + if (!SetGroupDeviceIds(mix_pipeline.stream_types, mix_filter.get())) { + return false; + } + loopback_output_group_ = mix_filter.get(); + filter_groups_.push_back(std::move(mix_filter)); - filter_groups_.push_back(CreateFilterGroup( - loopback_output_group_->GetOutputChannelCount(), "linearize", - config->GetLinearizePipeline(), - base::flat_set<std::string>() /* device_ids */, - std::vector<FilterGroup*>({loopback_output_group_}), factory)); + // Create "linearize" processor group: + const auto linearize_pipeline = config->GetLinearizePipeline(); + filter_groups_.push_back( + CreateFilterGroup(loopback_output_group_->GetOutputChannelCount(), + "linearize", linearize_pipeline.pipeline, factory)); output_group_ = filter_groups_.back().get(); - - LOG(INFO) << "PostProcessor configuration:"; - if (default_stream_group_ == loopback_output_group_) { - LOG(INFO) << "Stream layer: none"; - } else { - LOG(INFO) << "Stream layer: " - << default_stream_group_->GetOutputChannelCount() << " channels"; + output_group_->AddMixedInput(loopback_output_group_); + if (!SetGroupDeviceIds(linearize_pipeline.stream_types, output_group_)) { + return false; } - LOG(INFO) << "Mix filter: " << loopback_output_group_->GetOutputChannelCount() - << " channels"; - LOG(INFO) << "Linearize filter: " << output_group_->GetOutputChannelCount() - << " channels"; + // If no default group is provided, use the "mix" group. + if (stream_sinks_.find(::media::AudioDeviceDescription::kDefaultDeviceId) == + stream_sinks_.end()) { + stream_sinks_[::media::AudioDeviceDescription::kDefaultDeviceId] = + loopback_output_group_; + } + + output_group_->PrintTopology(); + + return true; +} + +bool MixerPipeline::SetGroupDeviceIds(const base::Value* ids, + FilterGroup* filter_group) { + if (!ids) { + return true; + } + DCHECK(filter_group); + DCHECK(ids->is_list()); + + for (const base::Value& stream_type_val : ids->GetList()) { + DCHECK(stream_type_val.is_string()); + const std::string& stream_type = stream_type_val.GetString(); + if (!IsOutputDeviceId(stream_type)) { + LOG(ERROR) << stream_type + << " is not a stream type. Stream types are listed " + << "in chromecast/media/base/audio_device_ids.cc and " + << "media/audio/audio_device_description.cc"; + return false; + } + if (stream_sinks_.find(stream_type) != stream_sinks_.end()) { + LOG(ERROR) << "Multiple instances of stream type '" << stream_type + << "' in cast_audio.json"; + return false; + } + stream_sinks_[stream_type] = filter_group; + } return true; } @@ -153,19 +166,12 @@ } FilterGroup* MixerPipeline::GetInputGroup(const std::string& device_id) { - for (auto&& filter_group : filter_groups_) { - if (filter_group->CanProcessInput(device_id)) { - return filter_group.get(); - break; - } + auto got = stream_sinks_.find(device_id); + if (got != stream_sinks_.end()) { + return got->second; } - if (default_stream_group_) { - return default_stream_group_; - } - - NOTREACHED() << "Could not find a filter group to re-attach " << device_id; - return nullptr; + return stream_sinks_[::media::AudioDeviceDescription::kDefaultDeviceId]; } void MixerPipeline::MixAndFilter(
diff --git a/chromecast/media/cma/backend/mixer_pipeline.h b/chromecast/media/cma/backend/mixer_pipeline.h index 7a83621..779dd19 100644 --- a/chromecast/media/cma/backend/mixer_pipeline.h +++ b/chromecast/media/cma/backend/mixer_pipeline.h
@@ -10,10 +10,15 @@ #include <string> #include <vector> +#include "base/containers/flat_map.h" #include "base/macros.h" #include "chromecast/public/media/audio_post_processor_shlib.h" #include "chromecast/public/media/media_pipeline_backend.h" +namespace base { +class Value; +} // namespace base + namespace chromecast { namespace media { @@ -82,8 +87,11 @@ bool BuildPipeline(PostProcessingPipelineParser* config, PostProcessingPipelineFactory* factory); + // Adds |ids| to the list of DeviceIds |filter_group| can process. + bool SetGroupDeviceIds(const base::Value* ids, FilterGroup* filter_group); + std::vector<std::unique_ptr<FilterGroup>> filter_groups_; - FilterGroup* default_stream_group_ = nullptr; + base::flat_map<std::string, FilterGroup*> stream_sinks_; FilterGroup* loopback_output_group_ = nullptr; FilterGroup* output_group_ = nullptr;
diff --git a/chromecast/media/cma/backend/mock_post_processor_factory.cc b/chromecast/media/cma/backend/mock_post_processor_factory.cc index 6f488d32..326ad79 100644 --- a/chromecast/media/cma/backend/mock_post_processor_factory.cc +++ b/chromecast/media/cma/backend/mock_post_processor_factory.cc
@@ -13,11 +13,10 @@ using testing::_; using testing::NiceMock; -MockPostProcessor::MockPostProcessor( - MockPostProcessorFactory* factory, - const std::string& name, - const base::ListValue* filter_description_list, - int channels) +MockPostProcessor::MockPostProcessor(MockPostProcessorFactory* factory, + const std::string& name, + const base::Value* filter_description_list, + int channels) : factory_(factory), name_(name), num_output_channels_(channels) { DCHECK(factory_); CHECK(factory_->instances.insert({name_, this}).second); @@ -32,23 +31,32 @@ } // Parse |filter_description_list| for parameters. - for (size_t i = 0; i < filter_description_list->GetSize(); ++i) { - const base::DictionaryValue* description_dict; - CHECK(filter_description_list->GetDictionary(i, &description_dict)); - std::string solib; - CHECK(description_dict->GetString("processor", &solib)); - // This will initially be called with the actual pipeline on creation. - // Ignore and wait for the call to ResetPostProcessorsForTest. - const std::string kDelayModuleSolib = "delay.so"; - if (solib == kDelayModuleSolib) { - const base::DictionaryValue* processor_config_dict; - CHECK(description_dict->GetDictionary("config", &processor_config_dict)); - int module_delay; - CHECK(processor_config_dict->GetInteger("delay", &module_delay)); - rendering_delay_ += module_delay; - processor_config_dict->GetBoolean("ringing", &ringing_); - processor_config_dict->GetInteger("output_channels", - &num_output_channels_); + for (const base::Value& elem : filter_description_list->GetList()) { + CHECK(elem.is_dict()); + const base::Value* processor_val = + elem.FindKeyOfType("processor", base::Value::Type::STRING); + CHECK(processor_val); + std::string solib = processor_val->GetString(); + + if (solib == "delay.so") { + const base::Value* processor_config_dict = + elem.FindKeyOfType("config", base::Value::Type::DICTIONARY); + CHECK(processor_config_dict); + const base::Value* delay_val = processor_config_dict->FindKeyOfType( + "delay", base::Value::Type::INTEGER); + CHECK(delay_val); + rendering_delay_ += delay_val->GetInt(); + const base::Value* ringing_val = processor_config_dict->FindKeyOfType( + "ringing", base::Value::Type::BOOLEAN); + if (ringing_val) { + ringing_ = ringing_val->GetBool(); + } + + const base::Value* output_ch_val = processor_config_dict->FindKeyOfType( + "output_channels", base::Value::Type::INTEGER); + if (output_ch_val) { + num_output_channels_ = output_ch_val->GetInt(); + } } } } @@ -60,7 +68,7 @@ std::unique_ptr<PostProcessingPipeline> MockPostProcessorFactory::CreatePipeline( const std::string& name, - const base::ListValue* filter_description_list, + const base::Value* filter_description_list, int channels) { return std::make_unique<testing::NiceMock<MockPostProcessor>>( this, name, filter_description_list, channels);
diff --git a/chromecast/media/cma/backend/mock_post_processor_factory.h b/chromecast/media/cma/backend/mock_post_processor_factory.h index 20ba1e3..63d87cf 100644 --- a/chromecast/media/cma/backend/mock_post_processor_factory.h +++ b/chromecast/media/cma/backend/mock_post_processor_factory.h
@@ -13,6 +13,10 @@ #include "chromecast/media/cma/backend/post_processing_pipeline.h" #include "testing/gmock/include/gmock/gmock.h" +namespace base { +class Value; +} // namespace base + namespace chromecast { namespace media { @@ -21,7 +25,7 @@ public: MockPostProcessor(MockPostProcessorFactory* factory, const std::string& name, - const base::ListValue* filter_description_list, + const base::Value* filter_description_list, int channels); ~MockPostProcessor() override; MOCK_METHOD4( @@ -64,7 +68,7 @@ ~MockPostProcessorFactory() override; std::unique_ptr<PostProcessingPipeline> CreatePipeline( const std::string& name, - const base::ListValue* filter_description_list, + const base::Value* filter_description_list, int channels) override; std::unordered_map<std::string, MockPostProcessor*> instances;
diff --git a/chromecast/media/cma/backend/post_processing_pipeline.h b/chromecast/media/cma/backend/post_processing_pipeline.h index c1063fd1..55ee73a1 100644 --- a/chromecast/media/cma/backend/post_processing_pipeline.h +++ b/chromecast/media/cma/backend/post_processing_pipeline.h
@@ -11,7 +11,7 @@ #include "chromecast/public/volume_control.h" namespace base { -class ListValue; +class Value; } // namespace base namespace chromecast { @@ -41,7 +41,7 @@ virtual std::unique_ptr<PostProcessingPipeline> CreatePipeline( const std::string& name, - const base::ListValue* filter_description_list, + const base::Value* filter_description_list, int num_channels) = 0; };
diff --git a/chromecast/media/cma/backend/post_processing_pipeline_impl.cc b/chromecast/media/cma/backend/post_processing_pipeline_impl.cc index 3ff8c35..a39a935 100644 --- a/chromecast/media/cma/backend/post_processing_pipeline_impl.cc +++ b/chromecast/media/cma/backend/post_processing_pipeline_impl.cc
@@ -42,7 +42,7 @@ std::unique_ptr<PostProcessingPipeline> PostProcessingPipelineFactoryImpl::CreatePipeline( const std::string& name, - const base::ListValue* filter_description_list, + const base::Value* filter_description_list, int num_channels) { return std::make_unique<PostProcessingPipelineImpl>( name, filter_description_list, num_channels); @@ -50,7 +50,7 @@ PostProcessingPipelineImpl::PostProcessingPipelineImpl( const std::string& name, - const base::ListValue* filter_description_list, + const base::Value* filter_description_list, int channels) : name_(name), sample_rate_(kNoSampleRate), num_output_channels_(channels) { if (!filter_description_list) {
diff --git a/chromecast/media/cma/backend/post_processing_pipeline_impl.h b/chromecast/media/cma/backend/post_processing_pipeline_impl.h index 21f29e0..71e8255 100644 --- a/chromecast/media/cma/backend/post_processing_pipeline_impl.h +++ b/chromecast/media/cma/backend/post_processing_pipeline_impl.h
@@ -15,7 +15,7 @@ #include "chromecast/public/volume_control.h" namespace base { -class ListValue; +class Value; } // namespace base namespace chromecast { @@ -28,7 +28,7 @@ class PostProcessingPipelineImpl : public PostProcessingPipeline { public: PostProcessingPipelineImpl(const std::string& name, - const base::ListValue* filter_description_list, + const base::Value* filter_description_list, int channels); ~PostProcessingPipelineImpl() override; @@ -87,7 +87,7 @@ // PostProcessingPipelineFactory interface. std::unique_ptr<PostProcessingPipeline> CreatePipeline( const std::string& name, - const base::ListValue* filter_description_list, + const base::Value* filter_description_list, int num_channels) override; };
diff --git a/chromecast/media/cma/backend/post_processing_pipeline_parser.cc b/chromecast/media/cma/backend/post_processing_pipeline_parser.cc index deac7d19..cb104c7 100644 --- a/chromecast/media/cma/backend/post_processing_pipeline_parser.cc +++ b/chromecast/media/cma/backend/post_processing_pipeline_parser.cc
@@ -26,8 +26,8 @@ } // namespace StreamPipelineDescriptor::StreamPipelineDescriptor( - const base::ListValue* pipeline_in, - const base::flat_set<std::string>& stream_types_in) + const base::Value* pipeline_in, + const base::Value* stream_types_in) : pipeline(pipeline_in), stream_types(stream_types_in) {} StreamPipelineDescriptor::~StreamPipelineDescriptor() = default; @@ -69,57 +69,60 @@ std::vector<StreamPipelineDescriptor> PostProcessingPipelineParser::GetStreamPipelines() { std::vector<StreamPipelineDescriptor> descriptors; - const base::ListValue* pipelines_list; - if (!postprocessor_config_ || - !postprocessor_config_->GetList(kOutputStreamsKey, &pipelines_list)) { + if (!postprocessor_config_) { + return descriptors; + } + const base::Value* pipelines_list = postprocessor_config_->FindKeyOfType( + kOutputStreamsKey, base::Value::Type::LIST); + if (!pipelines_list) { LOG(WARNING) << "No post-processors found for streams (key = " << kOutputStreamsKey << ").\n No stream-specific processing will occur."; return descriptors; } - for (size_t i = 0; i < pipelines_list->GetSize(); ++i) { - const base::DictionaryValue* pipeline_description_dict; - CHECK(pipelines_list->GetDictionary(i, &pipeline_description_dict)); + for (const base::Value& pipeline_description_dict : + pipelines_list->GetList()) { + CHECK(pipeline_description_dict.is_dict()); - const base::ListValue* processors_list; - CHECK(pipeline_description_dict->GetList(kProcessorsKey, &processors_list)); + const base::Value* processors_list = + pipeline_description_dict.FindKeyOfType(kProcessorsKey, + base::Value::Type::LIST); + CHECK(processors_list); - const base::ListValue* streams_list; - CHECK(pipeline_description_dict->GetList(kStreamsKey, &streams_list)); - base::flat_set<std::string> streams_set; - for (size_t stream = 0; stream < streams_list->GetSize(); ++stream) { - std::string stream_name; - CHECK(streams_list->GetString(stream, &stream_name)); - CHECK(streams_set.insert(stream_name).second) - << "Duplicate stream type: " << stream_name; - } + const base::Value* streams_list = pipeline_description_dict.FindKeyOfType( + kStreamsKey, base::Value::Type::LIST); + CHECK(streams_list); - descriptors.emplace_back(processors_list, std::move(streams_set)); + descriptors.emplace_back(processors_list, streams_list); } return descriptors; } -const base::ListValue* PostProcessingPipelineParser::GetMixPipeline() { +StreamPipelineDescriptor PostProcessingPipelineParser::GetMixPipeline() { return GetPipelineByKey(kMixPipelineKey); } -const base::ListValue* PostProcessingPipelineParser::GetLinearizePipeline() { +StreamPipelineDescriptor PostProcessingPipelineParser::GetLinearizePipeline() { return GetPipelineByKey(kLinearizePipelineKey); } -const base::ListValue* PostProcessingPipelineParser::GetPipelineByKey( +StreamPipelineDescriptor PostProcessingPipelineParser::GetPipelineByKey( const std::string& key) { const base::DictionaryValue* stream_dict; if (!postprocessor_config_ || !postprocessor_config_->GetDictionary(key, &stream_dict)) { LOG(WARNING) << "No post-processor description found for \"" << key << "\" in " << file_path_ << ". Using passthrough."; - return nullptr; + return StreamPipelineDescriptor(nullptr, nullptr); } - const base::ListValue* out_list; - CHECK(stream_dict->GetList(kProcessorsKey, &out_list)); + const base::Value* processors_list = + stream_dict->FindKeyOfType(kProcessorsKey, base::Value::Type::LIST); + CHECK(processors_list); - return out_list; + const base::Value* streams_list = + stream_dict->FindKeyOfType(kStreamsKey, base::Value::Type::LIST); + + return StreamPipelineDescriptor(processors_list, streams_list); } base::FilePath PostProcessingPipelineParser::GetFilePath() const {
diff --git a/chromecast/media/cma/backend/post_processing_pipeline_parser.h b/chromecast/media/cma/backend/post_processing_pipeline_parser.h index b5aadea..27e50fe 100644 --- a/chromecast/media/cma/backend/post_processing_pipeline_parser.h +++ b/chromecast/media/cma/backend/post_processing_pipeline_parser.h
@@ -15,7 +15,7 @@ namespace base { class DictionaryValue; -class ListValue; +class Value; } // namespace base namespace chromecast { @@ -29,11 +29,11 @@ // {"processor": "PATH_TO_SHARED_OBJECT", // "config": "CONFIGURATION_STRING"}, // ... ] - const base::ListValue* pipeline; - base::flat_set<std::string> stream_types; + const base::Value* pipeline; + const base::Value* stream_types; - StreamPipelineDescriptor(const base::ListValue* pipeline_in, - const base::flat_set<std::string>& stream_types_in); + StreamPipelineDescriptor(const base::Value* pipeline_in, + const base::Value* stream_types_in); ~StreamPipelineDescriptor(); StreamPipelineDescriptor(const StreamPipelineDescriptor& other); StreamPipelineDescriptor operator=(const StreamPipelineDescriptor& other) = @@ -55,14 +55,14 @@ // Gets the list of processors for the mix/linearize stages. // Same format as StreamPipelineDescriptor.pipeline - const base::ListValue* GetMixPipeline(); - const base::ListValue* GetLinearizePipeline(); + StreamPipelineDescriptor GetMixPipeline(); + StreamPipelineDescriptor GetLinearizePipeline(); // Returns the file path used to load this object. base::FilePath GetFilePath() const; private: - const base::ListValue* GetPipelineByKey(const std::string& key); + StreamPipelineDescriptor GetPipelineByKey(const std::string& key); const base::FilePath file_path_; std::unique_ptr<base::DictionaryValue> config_dict_;
diff --git a/chromecast/media/cma/backend/stream_mixer.cc b/chromecast/media/cma/backend/stream_mixer.cc index efd6454b..ddffd252 100644 --- a/chromecast/media/cma/backend/stream_mixer.cc +++ b/chromecast/media/cma/backend/stream_mixer.cc
@@ -486,8 +486,6 @@ DCHECK(mixer_task_runner_->BelongsToCurrentThread()); DCHECK(input_source); - LOG(INFO) << "Add input " << input_source; - // If the new input is a primary one (or there were no inputs previously), we // may need to change the output sample rate to match the input sample rate. // We only change the output rate if it is not set to a fixed value. @@ -507,6 +505,8 @@ DCHECK(input_group) << "Could not find a processor for " << input_source->device_id(); + LOG(INFO) << "Add input " << input_source << " to " << input_group->name(); + auto input = std::make_unique<MixerInput>( input_source, output_samples_per_second_, frames_per_write_, GetTotalRenderingDelay(input_group), input_group);
diff --git a/chromeos/dbus/fake_shill_manager_client.cc b/chromeos/dbus/fake_shill_manager_client.cc index ee5a479..489a89e8 100644 --- a/chromeos/dbus/fake_shill_manager_client.cc +++ b/chromeos/dbus/fake_shill_manager_client.cc
@@ -54,51 +54,125 @@ const base::Value* first_; }; -// Appends string entries from |service_list_in| whose entries in ServiceClient -// have Type |match_type| to one of the output lists based on the entry's State. -void AppendServicesForType( - const base::ListValue* service_list_in, - const char* match_type, - bool technology_enabled, - std::vector<std::string>* active_service_list_out, - std::vector<std::string>* inactive_service_list_out, - std::vector<std::string>* disabled_service_list_out) { - ShillServiceClient::TestInterface* service_client = - DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); - for (base::ListValue::const_iterator iter = service_list_in->begin(); - iter != service_list_in->end(); ++iter) { - std::string service_path; - if (!iter->GetAsString(&service_path)) - continue; - const base::DictionaryValue* properties = - service_client->GetServiceProperties(service_path); - if (!properties) { - LOG(ERROR) << "Properties not found for service: " << service_path; - continue; - } - std::string type; - properties->GetString(shill::kTypeProperty, &type); - if (type != match_type) - continue; - bool visible = false; - if (technology_enabled) - properties->GetBoolean(shill::kVisibleProperty, &visible); - if (!visible) { - disabled_service_list_out->push_back(service_path); - continue; - } - std::string state; - properties->GetString(shill::kStateProperty, &state); - if (state == shill::kStateOnline || - state == shill::kStateAssociation || - state == shill::kStateConfiguration || - state == shill::kStatePortal || - state == shill::kStateReady) { - active_service_list_out->push_back(service_path); - } else { - inactive_service_list_out->push_back(service_path); - } - } +bool GetBoolValue(const base::Value& dict, const char* key) { + const base::Value* value = + dict.FindKeyOfType(key, base::Value::Type::BOOLEAN); + return value ? value->GetBool() : false; +} + +int GetIntValue(const base::Value& dict, const char* key) { + const base::Value* value = + dict.FindKeyOfType(key, base::Value::Type::INTEGER); + return value ? value->GetInt() : 0; +} + +std::string GetStringValue(const base::Value& dict, const char* key) { + const base::Value* value = dict.FindKeyOfType(key, base::Value::Type::STRING); + return value ? value->GetString() : std::string(); +} + +int GetStateOrder(const base::Value& dict) { + std::string state = GetStringValue(dict, shill::kStateProperty); + if (state == shill::kStateOnline) + return 1; + if (state == shill::kStateReady) + return 2; + if (state == shill::kStatePortal) + return 3; + if (state == shill::kStateAssociation || state == shill::kStateConfiguration) + return 4; + return 5; +} + +int GetTechnologyOrder(const base::Value& dict) { + std::string technology = GetStringValue(dict, shill::kTypeProperty); + // Note: In Shill, VPN is the highest priority network, but it is generally + // dependent on the underlying network and gets sorted after that network. + // For now, we simulate this by sorting VPN last. TODO(stevenjb): Support + // VPN dependencies. + if (technology == shill::kTypeVPN) + return 10; + + if (technology == shill::kTypeEthernet) + return 1; + if (technology == shill::kTypeWifi) + return 2; + if (technology == shill::kTypeWimax) + return 3; + if (technology == shill::kTypeCellular) + return 4; + return 5; +} + +int GetSecurityOrder(const base::Value& dict) { + std::string security = GetStringValue(dict, shill::kSecurityProperty); + // No security is listed last. + if (security == shill::kSecurityNone) + return 3; + + // 8021x is listed first. + if (security == shill::kSecurity8021x) + return 1; + + // All other security types are equal priority. + return 2; +} + +// Matches Shill's Service::Compare function. +bool CompareNetworks(const base::Value& a, const base::Value& b) { + // Connection State: Online, Connected, Portal, Connecting + int state_order_a = GetStateOrder(a); + int state_order_b = GetStateOrder(b); + if (state_order_a != state_order_b) + return state_order_a < state_order_b; + + // Connectable (i.e. configured) + bool connectable_a = GetBoolValue(a, shill::kConnectableProperty); + bool connectable_b = GetBoolValue(b, shill::kConnectableProperty); + if (connectable_a != connectable_b) + return connectable_a; + + // Note: VPN is normally sorted first because of dependencies, see comment + // in GetTechnologyOrder. + + // Technology + int technology_order_a = GetTechnologyOrder(a); + int technology_order_b = GetTechnologyOrder(b); + if (technology_order_a != technology_order_b) + return technology_order_a < technology_order_b; + + // Priority + int priority_a = GetIntValue(a, shill::kPriorityProperty); + int priority_b = GetIntValue(b, shill::kPriorityProperty); + if (priority_a != priority_b) + return priority_a > priority_b; + + // TODO: Sort on: Managed + + // AutoConnect + bool auto_connect_a = GetBoolValue(a, shill::kAutoConnectProperty); + bool auto_connect_b = GetBoolValue(b, shill::kAutoConnectProperty); + if (auto_connect_a != auto_connect_b) + return auto_connect_a; + + // Security + int security_order_a = GetSecurityOrder(a); + int security_order_b = GetSecurityOrder(b); + if (security_order_a != security_order_b) + return security_order_a < security_order_b; + + // TODO: Sort on: Profile: User profile < Device profile + // TODO: Sort on: Has ever connected + + // SignalStrength + int strength_a = GetIntValue(a, shill::kSignalStrengthProperty); + int strength_b = GetIntValue(b, shill::kSignalStrengthProperty); + if (strength_a != strength_b) + return strength_a > strength_b; + + // Arbitrary identifier: SSID + return GetStringValue(a, shill::kSSIDProperty) < + GetStringValue(b, shill::kSSIDProperty); } void LogErrorCallback(const std::string& error_name, @@ -141,6 +215,8 @@ ->SetDeviceProperty(device_path, name, value, /*notify_changed=*/false); } +const char kPathKey[] = "path"; + const char kTechnologyUnavailable[] = "unavailable"; const char kTechnologyInitializing[] = "initializing"; const char kNetworkActivated[] = "activated"; @@ -229,7 +305,7 @@ const std::string& type, const base::Closure& callback, const ErrorCallback& error_callback) { - base::ListValue* enabled_list = NULL; + base::ListValue* enabled_list = nullptr; if (!stub_properties_.GetListWithoutPathExpansion( shill::kAvailableTechnologiesProperty, &enabled_list)) { base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); @@ -249,7 +325,7 @@ const std::string& type, const base::Closure& callback, const ErrorCallback& error_callback) { - base::ListValue* enabled_list = NULL; + base::ListValue* enabled_list = nullptr; if (!stub_properties_.GetListWithoutPathExpansion( shill::kAvailableTechnologiesProperty, &enabled_list)) { base::ThreadTaskRunnerHandle::Get()->PostTask( @@ -297,13 +373,9 @@ if (!existing_properties) { // Add a new service to the service client stub because none exists, yet. // This calls AddManagerService. - service_client->AddServiceWithIPConfig(service_path, - guid /* guid */, - guid /* name */, - type, - shill::kStateIdle, - ipconfig_path, - true /* visible */); + service_client->AddServiceWithIPConfig( + service_path, guid /* guid */, guid /* name */, type, shill::kStateIdle, + ipconfig_path, true /* visible */); existing_properties = service_client->GetServiceProperties(service_path); } @@ -344,11 +416,9 @@ ConfigureService(properties, callback, error_callback); } - -void FakeShillManagerClient::GetService( - const base::DictionaryValue& properties, - const ObjectPathCallback& callback, - const ErrorCallback& error_callback) { +void FakeShillManagerClient::GetService(const base::DictionaryValue& properties, + const ObjectPathCallback& callback, + const ErrorCallback& error_callback) { base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(callback, dbus::ObjectPath())); } @@ -380,8 +450,8 @@ void FakeShillManagerClient::RemoveDevice(const std::string& device_path) { base::Value device_path_value(device_path); - if (GetListProperty(shill::kDevicesProperty)->Remove( - device_path_value, NULL)) { + if (GetListProperty(shill::kDevicesProperty) + ->Remove(device_path_value, nullptr)) { CallNotifyObserversPropertyChanged(shill::kDevicesProperty); } } @@ -395,28 +465,24 @@ bool enabled) { if (GetListProperty(shill::kAvailableTechnologiesProperty) ->AppendIfNotPresent(std::make_unique<base::Value>(type))) { - CallNotifyObserversPropertyChanged( - shill::kAvailableTechnologiesProperty); + CallNotifyObserversPropertyChanged(shill::kAvailableTechnologiesProperty); } if (enabled && GetListProperty(shill::kEnabledTechnologiesProperty) ->AppendIfNotPresent(std::make_unique<base::Value>(type))) { - CallNotifyObserversPropertyChanged( - shill::kEnabledTechnologiesProperty); + CallNotifyObserversPropertyChanged(shill::kEnabledTechnologiesProperty); } } void FakeShillManagerClient::RemoveTechnology(const std::string& type) { base::Value type_value(type); - if (GetListProperty(shill::kAvailableTechnologiesProperty)->Remove( - type_value, NULL)) { - CallNotifyObserversPropertyChanged( - shill::kAvailableTechnologiesProperty); + if (GetListProperty(shill::kAvailableTechnologiesProperty) + ->Remove(type_value, nullptr)) { + CallNotifyObserversPropertyChanged(shill::kAvailableTechnologiesProperty); } - if (GetListProperty(shill::kEnabledTechnologiesProperty)->Remove( - type_value, NULL)) { - CallNotifyObserversPropertyChanged( - shill::kEnabledTechnologiesProperty); + if (GetListProperty(shill::kEnabledTechnologiesProperty) + ->Remove(type_value, nullptr)) { + CallNotifyObserversPropertyChanged(shill::kEnabledTechnologiesProperty); } } @@ -430,7 +496,7 @@ } } else { if (GetListProperty(shill::kUninitializedTechnologiesProperty) - ->Remove(base::Value(type), NULL)) { + ->Remove(base::Value(type), nullptr)) { CallNotifyObserversPropertyChanged( shill::kUninitializedTechnologiesProperty); } @@ -466,9 +532,8 @@ SetProperty(key, value, base::DoNothing(), base::Bind(&LogErrorCallback)); } -void FakeShillManagerClient::AddManagerService( - const std::string& service_path, - bool notify_observers) { +void FakeShillManagerClient::AddManagerService(const std::string& service_path, + bool notify_observers) { VLOG(2) << "AddManagerService: " << service_path; GetListProperty(shill::kServiceCompleteListProperty) ->AppendIfNotPresent(std::make_unique<base::Value>(service_path)); @@ -481,8 +546,8 @@ const std::string& service_path) { VLOG(2) << "RemoveManagerService: " << service_path; base::Value service_path_value(service_path); - GetListProperty(shill::kServiceCompleteListProperty)->Remove( - service_path_value, NULL); + GetListProperty(shill::kServiceCompleteListProperty) + ->Remove(service_path_value, nullptr); CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty); } @@ -505,63 +570,72 @@ void FakeShillManagerClient::SortManagerServices(bool notify) { VLOG(1) << "SortManagerServices"; - static const char* ordered_types[] = {shill::kTypeEthernet, - shill::kTypeEthernetEap, - shill::kTypeWifi, - shill::kTypeCellular, - shill::kTypeWimax, - shill::kTypeVPN}; - base::ListValue* complete_list = - GetListProperty(shill::kServiceCompleteListProperty); - if (complete_list->empty()) + // ServiceCompleteList contains string path values for each service. + base::Value* complete_path_list = stub_properties_.FindKeyOfType( + shill::kServiceCompleteListProperty, base::Value::Type::LIST); + if (!complete_path_list || complete_path_list->GetList().empty()) return; - std::unique_ptr<base::ListValue> prev_complete_list( - complete_list->DeepCopy()); - std::vector<std::string> active_services; - std::vector<std::string> inactive_services; - std::vector<std::string> disabled_services; - for (size_t i = 0; i < arraysize(ordered_types); ++i) { - AppendServicesForType(complete_list, - ordered_types[i], - TechnologyEnabled(ordered_types[i]), - &active_services, - &inactive_services, - &disabled_services); - } - complete_list->Clear(); - for (size_t i = 0; i < active_services.size(); ++i) - complete_list->AppendString(active_services[i]); - for (size_t i = 0; i < inactive_services.size(); ++i) - complete_list->AppendString(inactive_services[i]); - for (size_t i = 0; i < disabled_services.size(); ++i) - complete_list->AppendString(disabled_services[i]); + base::Value prev_complete_path_list = complete_path_list->Clone(); - if (notify && !complete_list->Equals(prev_complete_list.get())) - CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty); + // Networks for disabled services get appended to the end without sorting. + std::vector<std::string> disabled_path_list; - // Set the first active service as the Default service. - std::string new_default_service; - if (!active_services.empty()) { - ShillServiceClient::TestInterface* service_client = - DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface(); - std::string service_path = active_services[0]; - const base::DictionaryValue* properties = - service_client->GetServiceProperties(service_path); + // Build a list of dictionaries for each service in the list. + std::vector<base::Value> complete_dict_list; + for (const base::Value& value : complete_path_list->GetList()) { + std::string service_path = value.GetString(); + const base::Value* properties = DBusThreadManager::Get() + ->GetShillServiceClient() + ->GetTestInterface() + ->GetServiceProperties(service_path); if (!properties) { LOG(ERROR) << "Properties not found for service: " << service_path; - } else { - std::string state; - properties->GetString(shill::kStateProperty, &state); - if (IsConnectedState(state)) - new_default_service = service_path; + continue; } + + std::string type = GetStringValue(*properties, shill::kTypeProperty); + if (!TechnologyEnabled(type)) { + disabled_path_list.push_back(service_path); + continue; + } + + base::Value properties_copy = properties->Clone(); + properties_copy.SetKey(kPathKey, base::Value(service_path)); + complete_dict_list.emplace_back(std::move(properties_copy)); + } + + // Sort the service list using the same logic as Shill's Service::Compare. + std::sort(complete_dict_list.begin(), complete_dict_list.end(), + CompareNetworks); + + // Rebuild |complete_path_list| with the new sort order. + complete_path_list->GetList().clear(); + for (const base::Value& dict : complete_dict_list) { + std::string service_path = GetStringValue(dict, kPathKey); + complete_path_list->GetList().push_back(base::Value(service_path)); + } + // Append disabled networks to the end of the complete path list. + for (const std::string& path : disabled_path_list) + complete_path_list->GetList().push_back(base::Value(path)); + + // Notify observers if the order changed. + if (notify && *complete_path_list != prev_complete_path_list) + CallNotifyObserversPropertyChanged(shill::kServiceCompleteListProperty); + + // Set the first connected service as the Default service. Note: + // |new_default_service| may be empty indicating no default network. + std::string new_default_service; + const base::Value& default_network = complete_dict_list[0]; + if (IsConnectedState( + GetStringValue(default_network, shill::kStateProperty))) { + new_default_service = GetStringValue(default_network, kPathKey); } if (default_service_ != new_default_service) { default_service_ = new_default_service; - base::Value default_service_value(default_service_); - SetManagerProperty(shill::kDefaultServiceProperty, default_service_value); + SetManagerProperty(shill::kDefaultServiceProperty, + base::Value(default_service_)); } } @@ -954,7 +1028,7 @@ void FakeShillManagerClient::NotifyObserversPropertyChanged( const std::string& property) { VLOG(1) << "NotifyObserversPropertyChanged: " << property; - base::Value* value = NULL; + base::Value* value = nullptr; if (!stub_properties_.GetWithoutPathExpansion(property, &value)) { LOG(ERROR) << "Notify for unknown property: " << property; return; @@ -996,18 +1070,16 @@ return enabled; } -void FakeShillManagerClient::SetTechnologyEnabled( - const std::string& type, - const base::Closure& callback, - bool enabled) { +void FakeShillManagerClient::SetTechnologyEnabled(const std::string& type, + const base::Closure& callback, + bool enabled) { base::ListValue* enabled_list = GetListProperty(shill::kEnabledTechnologiesProperty); if (enabled) enabled_list->AppendIfNotPresent(std::make_unique<base::Value>(type)); else - enabled_list->Remove(base::Value(type), NULL); - CallNotifyObserversPropertyChanged( - shill::kEnabledTechnologiesProperty); + enabled_list->Remove(base::Value(type), nullptr); + CallNotifyObserversPropertyChanged(shill::kEnabledTechnologiesProperty); base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); // May affect available services. SortManagerServices(true); @@ -1198,10 +1270,8 @@ if (type_arg == "eth") type_arg = shill::kTypeEthernet; - if (type_arg != shill::kTypeEthernet && - type_arg != shill::kTypeWifi && - type_arg != shill::kTypeCellular && - type_arg != shill::kTypeWimax && + if (type_arg != shill::kTypeEthernet && type_arg != shill::kTypeWifi && + type_arg != shill::kTypeCellular && type_arg != shill::kTypeWimax && type_arg != shill::kTypeVPN) { LOG(WARNING) << "Unrecognized Shill network type: " << type_arg; return false;
diff --git a/chromeos/dbus/fake_shill_service_client.cc b/chromeos/dbus/fake_shill_service_client.cc index ece0aedb..0ee7fbd 100644 --- a/chromeos/dbus/fake_shill_service_client.cc +++ b/chromeos/dbus/fake_shill_service_client.cc
@@ -38,26 +38,28 @@ } void CallSortManagerServices() { - DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()-> - SortManagerServices(true); + DBusThreadManager::Get() + ->GetShillManagerClient() + ->GetTestInterface() + ->SortManagerServices(true); } int GetInteractiveDelay() { - return DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()-> - GetInteractiveDelay(); + return DBusThreadManager::Get() + ->GetShillManagerClient() + ->GetTestInterface() + ->GetInteractiveDelay(); } } // namespace -FakeShillServiceClient::FakeShillServiceClient() : weak_ptr_factory_(this) { -} +FakeShillServiceClient::FakeShillServiceClient() : weak_ptr_factory_(this) {} FakeShillServiceClient::~FakeShillServiceClient() = default; // ShillServiceClient overrides. -void FakeShillServiceClient::Init(dbus::Bus* bus) { -} +void FakeShillServiceClient::Init(dbus::Bus* bus) {} void FakeShillServiceClient::AddPropertyChangedObserver( const dbus::ObjectPath& service_path, @@ -74,7 +76,7 @@ void FakeShillServiceClient::GetProperties( const dbus::ObjectPath& service_path, const DictionaryValueCallback& callback) { - base::DictionaryValue* nested_dict = NULL; + base::DictionaryValue* nested_dict = nullptr; std::unique_ptr<base::DictionaryValue> result_properties; DBusMethodCallStatus call_status; stub_services_.GetDictionaryWithoutPathExpansion(service_path.value(), @@ -83,7 +85,7 @@ result_properties.reset(nested_dict->DeepCopy()); // Remove credentials that Shill wouldn't send. result_properties->RemoveWithoutPathExpansion(shill::kPassphraseProperty, - NULL); + nullptr); call_status = DBUS_METHOD_CALL_SUCCESS; } else { // This may happen if we remove services from the list. @@ -116,8 +118,8 @@ const base::DictionaryValue& properties, const base::Closure& callback, const ErrorCallback& error_callback) { - for (base::DictionaryValue::Iterator iter(properties); - !iter.IsAtEnd(); iter.Advance()) { + for (base::DictionaryValue::Iterator iter(properties); !iter.IsAtEnd(); + iter.Advance()) { if (!SetServiceProperty(service_path.value(), iter.key(), iter.value())) { LOG(ERROR) << "Service not found: " << service_path.value(); error_callback.Run("Error.InvalidService", "Invalid Service"); @@ -132,13 +134,13 @@ const std::string& name, const base::Closure& callback, const ErrorCallback& error_callback) { - base::DictionaryValue* dict = NULL; - if (!stub_services_.GetDictionaryWithoutPathExpansion( - service_path.value(), &dict)) { + base::DictionaryValue* dict = nullptr; + if (!stub_services_.GetDictionaryWithoutPathExpansion(service_path.value(), + &dict)) { error_callback.Run("Error.InvalidService", "Invalid Service"); return; } - dict->RemoveWithoutPathExpansion(name, NULL); + dict->RemoveWithoutPathExpansion(name, nullptr); // Note: Shill does not send notifications when properties are cleared. base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, callback); } @@ -168,7 +170,7 @@ const base::Closure& callback, const ErrorCallback& error_callback) { VLOG(1) << "FakeShillServiceClient::Connect: " << service_path.value(); - base::DictionaryValue* service_properties = NULL; + base::DictionaryValue* service_properties = nullptr; if (!stub_services_.GetDictionary(service_path.value(), &service_properties)) { LOG(ERROR) << "Service not found: " << service_path.value(); @@ -303,14 +305,16 @@ const std::string& state, const std::string& ipconfig_path, bool visible) { - base::DictionaryValue* properties = SetServiceProperties( - service_path, guid, name, type, state, visible); + base::DictionaryValue* properties = + SetServiceProperties(service_path, guid, name, type, state, visible); if (!ipconfig_path.empty()) properties->SetKey(shill::kIPConfigProperty, base::Value(ipconfig_path)); - DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()-> - AddManagerService(service_path, true); + DBusThreadManager::Get() + ->GetShillManagerClient() + ->GetTestInterface() + ->AddManagerService(service_path, true); } base::DictionaryValue* FakeShillServiceClient::SetServiceProperties( @@ -359,20 +363,27 @@ base::Value(shill::kSecurityNone)); properties->SetKey(shill::kModeProperty, base::Value(shill::kModeManaged)); } + + // Ethernet is always connectable; + if (type == shill::kTypeEthernet) + properties->SetKey(shill::kConnectableProperty, base::Value(true)); + return properties; } void FakeShillServiceClient::RemoveService(const std::string& service_path) { - stub_services_.RemoveWithoutPathExpansion(service_path, NULL); + stub_services_.RemoveWithoutPathExpansion(service_path, nullptr); connect_behavior_.erase(service_path); - DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()-> - RemoveManagerService(service_path); + DBusThreadManager::Get() + ->GetShillManagerClient() + ->GetTestInterface() + ->RemoveManagerService(service_path); } bool FakeShillServiceClient::SetServiceProperty(const std::string& service_path, const std::string& property, const base::Value& value) { - base::DictionaryValue* dict = NULL; + base::DictionaryValue* dict = nullptr; if (!stub_services_.GetDictionaryWithoutPathExpansion(service_path, &dict)) return false; @@ -397,7 +408,7 @@ provider->SetKey(key, value.Clone()); changed_property = shill::kProviderProperty; } else if (value.is_dict()) { - const base::DictionaryValue* new_dict = NULL; + const base::DictionaryValue* new_dict = nullptr; value.GetAsDictionary(&new_dict); CHECK(new_dict); std::unique_ptr<base::Value> cur_value; @@ -416,6 +427,18 @@ changed_property = property; } + // Make PSK networks connectable if 'Passphrase' is set. + if (changed_property == shill::kPassphraseProperty && value.is_string() && + !value.GetString().empty()) { + new_properties.SetKey(shill::kPassphraseRequiredProperty, + base::Value(false)); + base::Value* security = dict->FindKey(shill::kSecurityClassProperty); + if (security && security->is_string() && + security->GetString() == shill::kSecurityPsk) { + new_properties.SetKey(shill::kConnectableProperty, base::Value(true)); + } + } + dict->MergeDictionary(&new_properties); // Add or update the profile entry. @@ -431,8 +454,9 @@ } } else { std::string profile_path; - if (dict->GetStringWithoutPathExpansion( - shill::kProfileProperty, &profile_path) && !profile_path.empty()) { + if (dict->GetStringWithoutPathExpansion(shill::kProfileProperty, + &profile_path) && + !profile_path.empty()) { profile_test->UpdateService(profile_path, service_path); } } @@ -441,8 +465,10 @@ if (property == shill::kStateProperty) { std::string state; value.GetAsString(&state); - DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()-> - ServiceStateChanged(service_path, state); + DBusThreadManager::Get() + ->GetShillManagerClient() + ->GetTestInterface() + ->ServiceStateChanged(service_path, state); } // If the State or Visibility changes, the sort order of service lists may @@ -464,37 +490,38 @@ const base::DictionaryValue* FakeShillServiceClient::GetServiceProperties( const std::string& service_path) const { - const base::DictionaryValue* properties = NULL; + const base::DictionaryValue* properties = nullptr; stub_services_.GetDictionaryWithoutPathExpansion(service_path, &properties); return properties; } void FakeShillServiceClient::ClearServices() { - DBusThreadManager::Get()->GetShillManagerClient()->GetTestInterface()-> - ClearManagerServices(); + DBusThreadManager::Get() + ->GetShillManagerClient() + ->GetTestInterface() + ->ClearManagerServices(); stub_services_.Clear(); connect_behavior_.clear(); } void FakeShillServiceClient::SetConnectBehavior(const std::string& service_path, - const base::Closure& behavior) { + const base::Closure& behavior) { connect_behavior_[service_path] = behavior; } void FakeShillServiceClient::NotifyObserversPropertyChanged( const dbus::ObjectPath& service_path, const std::string& property) { - base::DictionaryValue* dict = NULL; + base::DictionaryValue* dict = nullptr; std::string path = service_path.value(); if (!stub_services_.GetDictionaryWithoutPathExpansion(path, &dict)) { LOG(ERROR) << "Notify for unknown service: " << path; return; } - base::Value* value = NULL; + base::Value* value = nullptr; if (!dict->GetWithoutPathExpansion(property, &value)) { - LOG(ERROR) << "Notify for unknown property: " - << path << " : " << property; + LOG(ERROR) << "Notify for unknown property: " << path << " : " << property; return; } for (auto& observer : GetObserverList(service_path)) @@ -502,8 +529,9 @@ } base::DictionaryValue* FakeShillServiceClient::GetModifiableServiceProperties( - const std::string& service_path, bool create_if_missing) { - base::DictionaryValue* properties = NULL; + const std::string& service_path, + bool create_if_missing) { + base::DictionaryValue* properties = nullptr; if (!stub_services_.GetDictionaryWithoutPathExpansion(service_path, &properties) && create_if_missing) { @@ -525,8 +553,8 @@ void FakeShillServiceClient::SetOtherServicesOffline( const std::string& service_path) { - const base::DictionaryValue* service_properties = GetServiceProperties( - service_path); + const base::DictionaryValue* service_properties = + GetServiceProperties(service_path); if (!service_properties) { LOG(ERROR) << "Missing service: " << service_path; return; @@ -534,8 +562,8 @@ std::string service_type; service_properties->GetString(shill::kTypeProperty, &service_type); // Set all other services of the same type to offline (Idle). - for (base::DictionaryValue::Iterator iter(stub_services_); - !iter.IsAtEnd(); iter.Advance()) { + for (base::DictionaryValue::Iterator iter(stub_services_); !iter.IsAtEnd(); + iter.Advance()) { std::string path = iter.key(); if (path == service_path) continue; @@ -563,7 +591,7 @@ void FakeShillServiceClient::ContinueConnect(const std::string& service_path) { VLOG(1) << "FakeShillServiceClient::ContinueConnect: " << service_path; - base::DictionaryValue* service_properties = NULL; + base::DictionaryValue* service_properties = nullptr; if (!stub_services_.GetDictionary(service_path, &service_properties)) { LOG(ERROR) << "Service not found: " << service_path; return;
diff --git a/chromeos/network/managed_network_configuration_handler_unittest.cc b/chromeos/network/managed_network_configuration_handler_unittest.cc index 576b9858..1138fb77 100644 --- a/chromeos/network/managed_network_configuration_handler_unittest.cc +++ b/chromeos/network/managed_network_configuration_handler_unittest.cc
@@ -432,7 +432,9 @@ // The passphrase isn't sent again, because it's configured by the user and // Shill doesn't send it on GetProperties calls. expected_shill_properties->RemoveWithoutPathExpansion( - shill::kPassphraseProperty, NULL); + shill::kPassphraseProperty, nullptr); + expected_shill_properties->RemoveWithoutPathExpansion( + shill::kPassphraseRequiredProperty, nullptr); // Before setting policy, old_entry_path should exist. ASSERT_TRUE(GetShillProfileClient()->HasService("old_entry_path")); @@ -527,7 +529,9 @@ // The passphrase isn't sent again, because it's configured by the user and // Shill doesn't send it on GetProperties calls. expected_shill_properties->RemoveWithoutPathExpansion( - shill::kPassphraseProperty, NULL); + shill::kPassphraseProperty, nullptr); + expected_shill_properties->RemoveWithoutPathExpansion( + shill::kPassphraseRequiredProperty, nullptr); SetPolicy(::onc::ONC_SOURCE_USER_POLICY, kUser1, "policy/policy_wifi1.onc"); base::RunLoop().RunUntilIdle();
diff --git a/chromeos/network/network_state_handler.cc b/chromeos/network/network_state_handler.cc index fd28bb4..b092034 100644 --- a/chromeos/network/network_state_handler.cc +++ b/chromeos/network/network_state_handler.cc
@@ -1449,10 +1449,11 @@ // Note: usually active networks will precede inactive networks, however // this may briefly be untrue during state transitions (e.g. a network may - // transition to idle before the list is updated). Also separate Cellular - // networks (see below). - ManagedStateList cellular, active, non_wifi_visible, wifi_visible, hidden, - new_networks; + // transition to idle before the list is updated). Also separate inactive + // Mobile and VPN networks (see below). + ManagedStateList active, non_wifi_visible, wifi_visible, hidden, new_networks; + int cellular_count = 0; + bool have_default_cellular = false; for (ManagedStateList::iterator iter = network_list_.begin(); iter != network_list_.end(); ++iter) { NetworkState* network = (*iter)->AsNetworkState(); @@ -1463,30 +1464,36 @@ continue; } if (NetworkTypePattern::Cellular().MatchesType(network->type())) { - cellular.push_back(std::move(*iter)); - continue; + ++cellular_count; + if ((*iter)->AsNetworkState()->IsDefaultCellular()) + have_default_cellular = true; } if (network->IsConnectingOrConnected()) { active.push_back(std::move(*iter)); continue; } - if (network->visible()) { - if (NetworkTypePattern::WiFi().MatchesType(network->type())) - wifi_visible.push_back(std::move(*iter)); - else - non_wifi_visible.push_back(std::move(*iter)); - } else { + if (!network->visible()) { hidden.push_back(std::move(*iter)); + continue; } + if (NetworkTypePattern::WiFi().MatchesType(network->type())) + wifi_visible.push_back(std::move(*iter)); + else + non_wifi_visible.push_back(std::move(*iter)); } - if (ensure_cellular) - EnsureCellularNetwork(&cellular); - // List active non Cellular network first. + + // List active networks first (will always include Ethernet). network_list_ = std::move(active); - // Ethernet is always active so list any Cellular network next. - std::move(cellular.begin(), cellular.end(), - std::back_inserter(network_list_)); - // List any other non WiFi visible networks (i.e. WiMAX). + + // If a default Cellular network is required, add it next. + if (ensure_cellular && cellular_count == 0) { + std::unique_ptr<NetworkState> default_cellular = + MaybeCreateDefaultCellularNetwork(); + if (default_cellular) + network_list_.push_back(std::move(default_cellular)); + } + + // List non wifi visible networks next (Mobile and VPN). std::move(non_wifi_visible.begin(), non_wifi_visible.end(), std::back_inserter(network_list_)); // List WiFi networks last. @@ -1498,6 +1505,11 @@ std::move(new_networks.begin(), new_networks.end(), std::back_inserter(network_list_)); network_list_sorted_ = true; + + // If we have > 1 Cellular NetworkState and we have created a default Cellular + // NetworkState, remove it. + if (ensure_cellular && cellular_count > 1 && have_default_cellular) + RemoveDefaultCellularNetwork(); } void NetworkStateHandler::UpdateNetworkStats() { @@ -1622,40 +1634,30 @@ portal_iter->second.name); } -void NetworkStateHandler::EnsureCellularNetwork( - ManagedStateList* cellular_networks) { +std::unique_ptr<NetworkState> +NetworkStateHandler::MaybeCreateDefaultCellularNetwork() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); CHECK(!notifying_network_observers_); const DeviceState* device = GetDeviceStateByType(NetworkTypePattern::Cellular()); - if (!device) { - cellular_networks->clear(); - return; - } - if (cellular_networks->empty()) { - // If no SIM is present there will not be useful user facing Device - // information, so do not create a default Cellular network. - if (device->IsSimAbsent()) - return; - // Create a default Cellular network. Properties from the associated Device - // will be provided to the UI. - std::unique_ptr<NetworkState> network = - NetworkState::CreateDefaultCellular(device->path()); - network->set_name(device->GetName()); - UpdateGuid(network.get()); - cellular_networks->push_back(std::move(network)); - return; - } - if (cellular_networks->size() == 1) - return; - // If we have > 1 Cellular NetworkState, then Shill provided a Cellular - // Service after the default Cellular NetworkState was created, so remove the - // default state. - for (auto iter = cellular_networks->begin(); iter != cellular_networks->end(); - ++iter) { + // If no SIM is present there will not be useful user facing Device + // information, so do not create a default Cellular network. + if (!device || device->IsSimAbsent()) + return nullptr; + // Create a default Cellular network. Properties from the associated Device + // will be provided to the UI. + std::unique_ptr<NetworkState> network = + NetworkState::CreateDefaultCellular(device->path()); + network->set_name(device->GetName()); + UpdateGuid(network.get()); + return network; +} + +void NetworkStateHandler::RemoveDefaultCellularNetwork() { + for (auto iter = network_list_.begin(); iter != network_list_.end(); ++iter) { if ((*iter)->AsNetworkState()->IsDefaultCellular()) { - cellular_networks->erase(iter); - break; // There will only ever be one default Cellular network. + network_list_.erase(iter); + return; // There will only ever be one default Cellular network. } } }
diff --git a/chromeos/network/network_state_handler.h b/chromeos/network/network_state_handler.h index 89010fe..d7837990 100644 --- a/chromeos/network/network_state_handler.h +++ b/chromeos/network/network_state_handler.h
@@ -479,10 +479,13 @@ void UpdateCaptivePortalProvider(NetworkState* network); // Cellular networks may not have an associated Shill Service (e.g. when the - // SIM is locked or a mobile network is not available). To simplify the UI, - // if a Cellular Device exists |cellular_networks| will be modified to contain - // exactly one network, creating a default network if necessary. - void EnsureCellularNetwork(ManagedStateList* cellular_networks); + // SIM is locked or a mobile network is not available). This returns a new + // default cellular network if necessary. + std::unique_ptr<NetworkState> MaybeCreateDefaultCellularNetwork(); + + // Removes the default Cellular network if it exists. Called when there is + // more than one Cellular network in the list. + void RemoveDefaultCellularNetwork(); // Sends NetworkListChanged() to observers and logs an event. void NotifyNetworkListChanged();
diff --git a/chromeos/network/shill_property_handler_unittest.cc b/chromeos/network/shill_property_handler_unittest.cc index 6b991e4..a9f19bf 100644 --- a/chromeos/network/shill_property_handler_unittest.cc +++ b/chromeos/network/shill_property_handler_unittest.cc
@@ -388,12 +388,12 @@ EXPECT_EQ(1, listener_->property_updates( shill::kServiceCompleteListProperty)[kTestServicePath]); - // Change the visibility of a service. This will trigger a service list - // updates. + // Set the state of the service to Connected. This will trigger a service list + // update. listener_->reset_list_updates(); DBusThreadManager::Get()->GetShillServiceClient()->SetProperty( - dbus::ObjectPath(kTestServicePath), shill::kVisibleProperty, - base::Value(false), base::DoNothing(), + dbus::ObjectPath(kTestServicePath), shill::kStateProperty, + base::Value(shill::kStateReady), base::DoNothing(), base::Bind(&ErrorCallbackFunction)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(1, listener_->list_updates(shill::kServiceCompleteListProperty));
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.cc b/chromeos/services/assistant/assistant_manager_service_impl.cc index 9a52559..6a71654d4 100644 --- a/chromeos/services/assistant/assistant_manager_service_impl.cc +++ b/chromeos/services/assistant/assistant_manager_service_impl.cc
@@ -972,7 +972,7 @@ void AssistantManagerServiceImpl::OnShowNotificationOnMainThread( const mojom::AssistantNotificationPtr& notification) { - service_->assistant_notification_controller()->AddNotification( + service_->assistant_notification_controller()->AddOrUpdateNotification( notification.Clone()); }
diff --git a/chromeos/services/assistant/public/features.cc b/chromeos/services/assistant/public/features.cc index 3ebcb11f..86e511f 100644 --- a/chromeos/services/assistant/public/features.cc +++ b/chromeos/services/assistant/public/features.cc
@@ -28,6 +28,9 @@ const base::Feature kTimerNotification{"ChromeOSAssistantTimerNotification", base::FEATURE_ENABLED_BY_DEFAULT}; +const base::Feature kTimerTicks{"ChromeOSAssistantTimerTicks", + base::FEATURE_DISABLED_BY_DEFAULT}; + bool IsDspHotwordEnabled() { return base::FeatureList::IsEnabled(kEnableDspHotword); } @@ -40,6 +43,10 @@ return base::FeatureList::IsEnabled(kTimerNotification); } +bool IsTimerTicksEnabled() { + return base::FeatureList::IsEnabled(kTimerTicks); +} + bool IsWarmerWelcomeEnabled() { return base::FeatureList::IsEnabled(kAssistantWarmerWelcomeFeature); }
diff --git a/chromeos/services/assistant/public/features.h b/chromeos/services/assistant/public/features.h index b18d976..1e52c89 100644 --- a/chromeos/services/assistant/public/features.h +++ b/chromeos/services/assistant/public/features.h
@@ -36,12 +36,22 @@ COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) extern const base::Feature kTimerNotification; +// Enables timer ticks. This feature causes alarms/timers tracked by the +// AssistantAlarmTimerController to tick at a fixed interval, delivering updates +// to AssistantAlarmTimerModelObservers of time remaining/elapsed since expiry. +// When enabled in conjunction with |kTimerNotification|, Assistant alarm/timer +// notifications will be updated at each tick. +COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) +extern const base::Feature kTimerTicks; + COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) bool IsDspHotwordEnabled(); COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) bool IsStereoAudioInputEnabled(); COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) bool IsTimerNotificationEnabled(); +COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) bool IsTimerTicksEnabled(); + COMPONENT_EXPORT(ASSISTANT_SERVICE_PUBLIC) bool IsWarmerWelcomeEnabled(); } // namespace features
diff --git a/chromeos/test/data/network/policy/shill_managed_wifi1.json b/chromeos/test/data/network/policy/shill_managed_wifi1.json index 469251c..4a4cc69 100644 --- a/chromeos/test/data/network/policy/shill_managed_wifi1.json +++ b/chromeos/test/data/network/policy/shill_managed_wifi1.json
@@ -5,6 +5,7 @@ "GUID": "policy2_wifi1", "Mode": "managed", "Passphrase": "user's passphrase", + "PassphraseRequired": false, "Profile": "/profile/user1/shill", "Security": "802_1x", "Type": "wifi",
diff --git a/chromeos/test/data/network/policy/shill_policy_autoconnect_on_unconfigured_wifi1.json b/chromeos/test/data/network/policy/shill_policy_autoconnect_on_unconfigured_wifi1.json index 3253959..e032113 100644 --- a/chromeos/test/data/network/policy/shill_policy_autoconnect_on_unconfigured_wifi1.json +++ b/chromeos/test/data/network/policy/shill_policy_autoconnect_on_unconfigured_wifi1.json
@@ -6,6 +6,7 @@ "Mode": "managed", "Name": "policy_wifi1", "Passphrase": "policy's passphrase", + "PassphraseRequired": false, "Profile": "/profile/user1/shill", "SSID": "policy_wifi1", "SecurityClass": "psk",
diff --git a/chromeos/test/data/network/policy/shill_policy_on_unconfigured_wifi1.json b/chromeos/test/data/network/policy/shill_policy_on_unconfigured_wifi1.json index e507d31..f824e36 100644 --- a/chromeos/test/data/network/policy/shill_policy_on_unconfigured_wifi1.json +++ b/chromeos/test/data/network/policy/shill_policy_on_unconfigured_wifi1.json
@@ -4,6 +4,7 @@ "Mode": "managed", "Name": "policy_wifi1", "Passphrase": "policy's passphrase", + "PassphraseRequired": false, "Profile": "/profile/user1/shill", "SSID": "policy_wifi1", "SecurityClass": "psk",
diff --git a/chromeos/test/data/network/policy/shill_policy_on_unmanaged_wifi1.json b/chromeos/test/data/network/policy/shill_policy_on_unmanaged_wifi1.json index 3f856a1..14b198d 100644 --- a/chromeos/test/data/network/policy/shill_policy_on_unmanaged_wifi1.json +++ b/chromeos/test/data/network/policy/shill_policy_on_unmanaged_wifi1.json
@@ -4,6 +4,7 @@ "Mode": "managed", "Name": "policy_wifi1", "Passphrase": "user's passphrase", + "PassphraseRequired": false, "Profile": "/profile/user1/shill", "SSID": "policy_wifi1", "SecurityClass": "psk",
diff --git a/chromeos/test/data/network/policy/shill_unmanaged_wifi1.json b/chromeos/test/data/network/policy/shill_unmanaged_wifi1.json index 9467416..04d564f 100644 --- a/chromeos/test/data/network/policy/shill_unmanaged_wifi1.json +++ b/chromeos/test/data/network/policy/shill_unmanaged_wifi1.json
@@ -2,6 +2,7 @@ "GUID": "{unmanaged_user_wifi1}", "Mode": "managed", "Passphrase": "user's passphrase", + "PassphraseRequired": false, "Profile": "/profile/user1/shill", "WiFi.HexSSID": "7769666931", // "wifi1" "SecurityClass": "psk",
diff --git a/chromeos/test/data/network/policy/shill_unmanaged_wifi2.json b/chromeos/test/data/network/policy/shill_unmanaged_wifi2.json index b86da65..2c877e1 100644 --- a/chromeos/test/data/network/policy/shill_unmanaged_wifi2.json +++ b/chromeos/test/data/network/policy/shill_unmanaged_wifi2.json
@@ -3,6 +3,7 @@ "GUID": "wifi2", "Mode": "managed", "Passphrase": "user's passphrase", + "PassphraseRequired": false, "Profile": "/profile/user1/shill", "SecurityClass": "psk", "Type": "wifi",
diff --git a/components/exo/surface_tree_host.cc b/components/exo/surface_tree_host.cc index bc3fc31..362668b8 100644 --- a/components/exo/surface_tree_host.cc +++ b/components/exo/surface_tree_host.cc
@@ -220,7 +220,6 @@ &presentation_callbacks_); frame.metadata.frame_token = ++next_token_; if (!presentation_callbacks_.empty()) { - frame.metadata.request_presentation_feedback = true; DCHECK_EQ(active_presentation_callbacks_.count(*next_token_), 0u); active_presentation_callbacks_[*next_token_] = std::move(presentation_callbacks_);
diff --git a/components/safe_browsing/base_ui_manager.h b/components/safe_browsing/base_ui_manager.h index 2321da8a..77a7ec8 100644 --- a/components/safe_browsing/base_ui_manager.h +++ b/components/safe_browsing/base_ui_manager.h
@@ -46,6 +46,12 @@ // protocol buffer. virtual void SendSerializedThreatDetails(const std::string& serialized); + // Updates the whitelist URL set for |web_contents|. Called on the UI thread. + void AddToWhitelistUrlSet(const GURL& whitelist_url, + content::WebContents* web_contents, + bool is_pending, + SBThreatType threat_type); + // This is a no-op in the base class, but should be overridden to report hits // to the unsafe contents (malware, phishing, unsafe download URL) // to the server. Can only be called on UI thread. Will only upload a hit @@ -102,12 +108,6 @@ friend class ChromePasswordProtectionService; virtual ~BaseUIManager(); - // Updates the whitelist URL set for |web_contents|. Called on the UI thread. - void AddToWhitelistUrlSet(const GURL& whitelist_url, - content::WebContents* web_contents, - bool is_pending, - SBThreatType threat_type); - // Removes |whitelist_url| from the whitelist for |web_contents|. // Called on the UI thread. void RemoveWhitelistUrlSet(const GURL& whitelist_url,
diff --git a/components/vector_icons/BUILD.gn b/components/vector_icons/BUILD.gn index 1d7b421..f6c6984 100644 --- a/components/vector_icons/BUILD.gn +++ b/components/vector_icons/BUILD.gn
@@ -16,6 +16,7 @@ "close.icon", "close_rounded.icon", "edit.icon", + "error.icon", "ethernet.icon", "folder.icon", "folder_managed.icon",
diff --git a/components/vector_icons/error.icon b/components/vector_icons/error.icon new file mode 100644 index 0000000..d018788 --- /dev/null +++ b/components/vector_icons/error.icon
@@ -0,0 +1,23 @@ +// Copyright 2018 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. + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 8, 0.91f, +CUBIC_TO, 4.07f, 0.91f, 0.89f, 4.1f, 0.89f, 8.03f, +CUBIC_TO, 0.89f, 11.96f, 4.07f, 15.14f, 8, 15.14f, +CUBIC_TO, 11.93f, 15.14f, 15.11f, 11.96f, 15.11f, 8.03f, +CUBIC_TO, 15.11f, 4.1f, 11.93f, 0.91f, 8, 0.91f, +CLOSE, +MOVE_TO, 8.89f, 11.55f, +LINE_TO, 7.11f, 11.55f, +LINE_TO, 7.11f, 9.78f, +LINE_TO, 8.89f, 9.78f, +CLOSE, +MOVE_TO, 8.89f, 8.89f, +LINE_TO, 7.11f, 8.89f, +LINE_TO, 7.11f, 4.45f, +LINE_TO, 8.89f, 4.45f, +CLOSE, +MOVE_TO, 8.89f, 8.89f, +CLOSE
diff --git a/components/viz/common/quads/compositor_frame_metadata.h b/components/viz/common/quads/compositor_frame_metadata.h index 63411ee..e2f3fbc 100644 --- a/components/viz/common/quads/compositor_frame_metadata.h +++ b/components/viz/common/quads/compositor_frame_metadata.h
@@ -137,11 +137,6 @@ // wants to do something after a particular frame is processed. bool send_frame_token_to_embedder = false; - // Once the display compositor presents a frame with - // |request_presentation_feedback| flag turned on, a presentation feedback - // will be provided to CompositorFrameSinkClient. - bool request_presentation_feedback = true; - // These limits can be used together with the scroll/scale fields above to // determine if scrolling/scaling in a particular direction is possible. float min_page_scale_factor = 0.f;
diff --git a/components/viz/host/host_frame_sink_manager_unittest.cc b/components/viz/host/host_frame_sink_manager_unittest.cc index 703b16d4..9fcb12a7 100644 --- a/components/viz/host/host_frame_sink_manager_unittest.cc +++ b/components/viz/host/host_frame_sink_manager_unittest.cc
@@ -271,7 +271,6 @@ TEST_F(HostFrameSinkManagerLocalTest, CommunicateFrameToken) { FakeHostFrameSinkClient host_client_parent; FakeHostFrameSinkClient host_client_child; - uint32_t frame_token1 = 10u; FrameSinkId kParentFrameSink(3, 0); FrameSinkId kChildFrameSink1(65563, 0); const SurfaceId child_id1 = MakeSurfaceId(kChildFrameSink1, 1); @@ -285,10 +284,11 @@ CompositorFrame compositor_frame = CompositorFrameBuilder() .AddDefaultRenderPass() - .SetFrameToken(frame_token1) .SetSendFrameTokenToEmbedder(true) .SetActivationDependencies({child_id1}) .Build(); + uint32_t frame_token = compositor_frame.metadata.frame_token; + ASSERT_NE(frame_token, 0u); support->SubmitCompositorFrame(parent_id1.local_surface_id(), std::move(compositor_frame)); @@ -306,7 +306,7 @@ EXPECT_FALSE(parent_surface->HasPendingFrame()); // Since the frame is now activated, |frame_token| is sent to // HostFrameSinkClient. - EXPECT_EQ(10u, host_client_parent.last_frame_token_seen()); + EXPECT_EQ(frame_token, host_client_parent.last_frame_token_seen()); } // Verify that that creating two CompositorFrameSinkSupports works.
diff --git a/components/viz/service/display/direct_renderer.cc b/components/viz/service/display/direct_renderer.cc index 53618df..dcf7c638 100644 --- a/components/viz/service/display/direct_renderer.cc +++ b/components/viz/service/display/direct_renderer.cc
@@ -397,18 +397,17 @@ if (!skip_drawing_root_render_pass) DrawRenderPassAndExecuteCopyRequests(root_render_pass); - // Use a fence to synchronize display of the overlays. Note that gpu_fence_id - // may have the special value 0 ("no fence") if fences are not supported. In - // that case synchronization will happen through other means on the service - // side. We are currently using the output surface fence for all the overlays, - // which is functionally correct due to the position of this fence in the - // command stream. + // Use a fence to synchronize display of the main fb used by the output + // surface. Note that gpu_fence_id may have the special value 0 ("no fence") + // if fences are not supported. In that case synchronization will happen + // through other means on the service side. // TODO(afrantzis): Consider using per-overlay fences instead of the one // associated with the output surface when possible. if (!current_frame()->overlay_list.empty()) { - auto gpu_fence_id = output_surface_->UpdateGpuFence(); - for (auto& overlay : current_frame()->overlay_list) - overlay.gpu_fence_id = gpu_fence_id; + for (auto& overlay : current_frame()->overlay_list) { + if (overlay.use_output_surface_for_resource) + overlay.gpu_fence_id = output_surface_->UpdateGpuFence(); + } } FinishDrawingFrame();
diff --git a/components/viz/service/display/display_unittest.cc b/components/viz/service/display/display_unittest.cc index 5223eaf6..f0f3ebc0 100644 --- a/components/viz/service/display/display_unittest.cc +++ b/components/viz/service/display/display_unittest.cc
@@ -3282,7 +3282,6 @@ CompositorFrame frame = CompositorFrameBuilder() .AddRenderPass(gfx::Rect(sub_surface_size), gfx::Rect()) - .SetRequestPresentationFeedback(true) .Build(); EXPECT_CALL(sub_client, DidReceiveCompositorFrameAck(_)).Times(1); frame_token_1 = frame.metadata.frame_token; @@ -3332,7 +3331,6 @@ CompositorFrame frame = CompositorFrameBuilder() .AddRenderPass(gfx::Rect(sub_surface_size), gfx::Rect(sub_surface_size)) - .SetRequestPresentationFeedback(true) .Build(); frame_token_2 = frame.metadata.frame_token; @@ -3352,7 +3350,6 @@ CompositorFrame frame = CompositorFrameBuilder() .AddRenderPass(gfx::Rect(sub_surface_size), gfx::Rect()) - .SetRequestPresentationFeedback(true) .Build(); EXPECT_CALL(sub_client, DidReceiveCompositorFrameAck(_)).Times(1);
diff --git a/components/viz/service/display/gl_renderer_unittest.cc b/components/viz/service/display/gl_renderer_unittest.cc index 75dd5c9..3c24c62 100644 --- a/components/viz/service/display/gl_renderer_unittest.cc +++ b/components/viz/service/display/gl_renderer_unittest.cc
@@ -4092,6 +4092,7 @@ static constexpr unsigned kSurfaceOverlayTextureId = 33; static constexpr unsigned kGpuFenceId = 66; + static constexpr unsigned kGpuNoFenceId = 0; TestContextSupport* test_context_support_; @@ -4105,7 +4106,7 @@ MockOverlayScheduler overlay_scheduler; }; -TEST_F(GLRendererWithGpuFenceTest, GpuFenceIdIsUsedWithRootRenderPass) { +TEST_F(GLRendererWithGpuFenceTest, GpuFenceIdIsUsedWithRootRenderPassOverlay) { gfx::Size viewport_size(100, 100); RenderPass* root_pass = cc::AddRenderPass( &render_passes_in_draw_order_, 1, gfx::Rect(viewport_size), @@ -4119,7 +4120,8 @@ DrawFrame(renderer_.get(), viewport_size); } -TEST_F(GLRendererWithGpuFenceTest, GpuFenceIdIsUsedWithoutRootRenderPass) { +TEST_F(GLRendererWithGpuFenceTest, + GpuFenceIdIsUsedOnlyForRootRenderPassOverlay) { gfx::Size viewport_size(100, 100); RenderPass* root_pass = cc::AddRenderPass( &render_passes_in_draw_order_, 1, gfx::Rect(viewport_size), @@ -4134,14 +4136,12 @@ gfx::PointF uv_top_left(0, 0); gfx::PointF uv_bottom_right(1, 1); - // Add a draw quad covering the whole viewport. This causes the root - // render pass to be skipped. TextureDrawQuad* overlay_quad = root_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); SharedQuadState* shared_state = root_pass->CreateAndAppendSharedQuadState(); shared_state->SetAll(gfx::Transform(), gfx::Rect(viewport_size), - gfx::Rect(viewport_size), gfx::Rect(viewport_size), - false, false, 1, SkBlendMode::kSrcOver, 0); + gfx::Rect(50, 50), gfx::Rect(viewport_size), false, + false, 1, SkBlendMode::kSrcOver, 0); overlay_quad->SetNew( shared_state, gfx::Rect(viewport_size), gfx::Rect(viewport_size), needs_blending, create_overlay_resource(), premultiplied_alpha, @@ -4155,7 +4155,7 @@ .Times(1); EXPECT_CALL(overlay_scheduler, Schedule(1, gfx::OVERLAY_TRANSFORM_NONE, _, - gfx::Rect(viewport_size), _, _, kGpuFenceId)) + gfx::Rect(viewport_size), _, _, kGpuNoFenceId)) .Times(1); DrawFrame(renderer_.get(), viewport_size); }
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc index 68f25c8..4851019 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -414,7 +414,7 @@ shared_image_representation_factory_->ProduceSkia( metadata.mailbox_holder.mailbox); DCHECK(shared_image); - if (!shared_image->BeginReadAccess(backend_texture)) { + if (!shared_image->BeginReadAccess(sk_surface_.get(), backend_texture)) { DLOG(ERROR) << "Failed to begin read access for SharedImageRepresentationSkia"; return;
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc index baf56be..77454aa71 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
@@ -360,10 +360,10 @@ ++ack_pending_count_; - base::ScopedClosureRunner frame_rejected_callback(base::BindOnce( - &CompositorFrameSinkSupport::DidRejectCompositorFrame, - weak_factory_.GetWeakPtr(), frame.metadata.frame_token, - frame.metadata.request_presentation_feedback, frame.resource_list)); + base::ScopedClosureRunner frame_rejected_callback( + base::BindOnce(&CompositorFrameSinkSupport::DidRejectCompositorFrame, + weak_factory_.GetWeakPtr(), frame.metadata.frame_token, + frame.resource_list)); compositor_frame_callback_ = std::move(callback); if (compositor_frame_callback_) { @@ -488,11 +488,8 @@ bool result = current_surface->QueueFrame( std::move(frame), frame_index, std::move(frame_rejected_callback), - frame.metadata.request_presentation_feedback - ? base::BindOnce( - &CompositorFrameSinkSupport::DidPresentCompositorFrame, - weak_factory_.GetWeakPtr(), frame.metadata.frame_token) - : Surface::PresentedCallback()); + base::BindOnce(&CompositorFrameSinkSupport::DidPresentCompositorFrame, + weak_factory_.GetWeakPtr(), frame.metadata.frame_token)); if (!result) { TRACE_EVENT_INSTANT0("viz", "QueueFrame failed", TRACE_EVENT_SCOPE_THREAD); return SubmitResult::SURFACE_INVARIANTS_VIOLATION; @@ -549,16 +546,13 @@ void CompositorFrameSinkSupport::DidRejectCompositorFrame( uint32_t presentation_token, - bool request_presentation_feedback, std::vector<TransferableResource> frame_resource_list) { std::vector<ReturnedResource> resources = TransferableResource::ReturnResources(frame_resource_list); ReturnResources(resources); DidReceiveCompositorFrameAck(); - if (request_presentation_feedback) { - DidPresentCompositorFrame(presentation_token, - gfx::PresentationFeedback::Failure()); - } + DidPresentCompositorFrame(presentation_token, + gfx::PresentationFeedback::Failure()); } void CompositorFrameSinkSupport::UpdateDisplayRootReference(
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.h b/components/viz/service/frame_sinks/compositor_frame_sink_support.h index 0babe97..ef02c98 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support.h +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.h
@@ -198,7 +198,6 @@ const gfx::PresentationFeedback& feedback); void DidRejectCompositorFrame( uint32_t presentation_token, - bool request_presentation_feedback, std::vector<TransferableResource> frame_resource_list); // Update the display root reference with |surface|.
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc index 11570243..6bc4cf92 100644 --- a/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc +++ b/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc
@@ -1120,12 +1120,12 @@ TEST_F(CompositorFrameSinkSupportTest, OnFrameTokenUpdateAfterFirstSurfaceActivation) { LocalSurfaceId local_surface_id(1, kArbitraryToken); - uint32_t frame_token = 2u; auto frame = CompositorFrameBuilder() .AddDefaultRenderPass() - .SetFrameToken(frame_token) .SetSendFrameTokenToEmbedder(true) .Build(); + uint32_t frame_token = frame.metadata.frame_token; + ASSERT_NE(frame_token, 0u); testing::InSequence sequence; EXPECT_CALL(frame_sink_manager_client_, OnFirstSurfaceActivation(_));
diff --git a/components/viz/service/surfaces/surface_unittest.cc b/components/viz/service/surfaces/surface_unittest.cc index 586b9ccb..7fbec7c 100644 --- a/components/viz/service/surfaces/surface_unittest.cc +++ b/components/viz/service/surfaces/surface_unittest.cc
@@ -35,13 +35,14 @@ auto support = std::make_unique<CompositorFrameSinkSupport>( &client, &frame_sink_manager, kArbitraryFrameSinkId, kIsRoot, kNeedsSyncPoints); + uint32_t frame_token = 0; { CompositorFrame frame = CompositorFrameBuilder() .AddRenderPass(gfx::Rect(kSurfaceSize), kDamageRect) - .SetFrameToken(1) - .SetRequestPresentationFeedback(true) .Build(); + frame_token = frame.metadata.frame_token; + ASSERT_NE(frame_token, 0u); EXPECT_CALL(client, DidReceiveCompositorFrameAck(testing::_)).Times(1); support->SubmitCompositorFrame(local_surface_id, std::move(frame)); testing::Mock::VerifyAndClearExpectations(&client); @@ -53,13 +54,11 @@ CompositorFrame frame = CompositorFrameBuilder() .AddRenderPass(gfx::Rect(kSurfaceSize), kDamageRect) - .SetFrameToken(2) - .SetRequestPresentationFeedback(true) .Build(); EXPECT_CALL(client, DidReceiveCompositorFrameAck(testing::_)).Times(1); support->SubmitCompositorFrame(local_surface_id, std::move(frame)); ASSERT_EQ(1u, support->presentation_feedbacks().size()); - EXPECT_EQ(1u, support->presentation_feedbacks().begin()->first); + EXPECT_EQ(frame_token, support->presentation_feedbacks().begin()->first); testing::Mock::VerifyAndClearExpectations(&client); } }
diff --git a/components/viz/test/compositor_frame_helpers.cc b/components/viz/test/compositor_frame_helpers.cc index 5ec1e0e7..86f6d86 100644 --- a/components/viz/test/compositor_frame_helpers.cc +++ b/components/viz/test/compositor_frame_helpers.cc
@@ -115,12 +115,6 @@ return *this; } -CompositorFrameBuilder& CompositorFrameBuilder::SetFrameToken( - uint32_t frame_token) { - frame_->metadata.frame_token = frame_token; - return *this; -} - CompositorFrameBuilder& CompositorFrameBuilder::SetContentSourceId( uint32_t content_source_id) { frame_->metadata.content_source_id = content_source_id; @@ -134,13 +128,6 @@ return *this; } -CompositorFrameBuilder& CompositorFrameBuilder::SetRequestPresentationFeedback( - bool request) { - DCHECK(frame_->metadata.frame_token); - frame_->metadata.request_presentation_feedback = request; - return *this; -} - CompositorFrame CompositorFrameBuilder::MakeInitCompositorFrame() const { static FrameTokenGenerator next_token; CompositorFrame frame;
diff --git a/components/viz/test/compositor_frame_helpers.h b/components/viz/test/compositor_frame_helpers.h index 04826f41..eae9dfa 100644 --- a/components/viz/test/compositor_frame_helpers.h +++ b/components/viz/test/compositor_frame_helpers.h
@@ -58,10 +58,8 @@ CompositorFrameBuilder& SetActivationDependencies( std::vector<SurfaceId> activation_dependencies); CompositorFrameBuilder& SetDeadline(const FrameDeadline& deadline); - CompositorFrameBuilder& SetFrameToken(uint32_t frame_token); CompositorFrameBuilder& SetContentSourceId(uint32_t content_source_id); CompositorFrameBuilder& SetSendFrameTokenToEmbedder(bool send); - CompositorFrameBuilder& SetRequestPresentationFeedback(bool request); private: CompositorFrame MakeInitCompositorFrame() const;
diff --git a/content/BUILD.gn b/content/BUILD.gn index 0ca39d7..bce6285 100644 --- a/content/BUILD.gn +++ b/content/BUILD.gn
@@ -2,9 +2,9 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//tools/grit/grit_rule.gni") import("//build/config/nacl/config.gni") import("//ppapi/buildflags/buildflags.gni") +import("//tools/grit/grit_rule.gni") # Applied by targets internal to content. config("content_implementation") { @@ -128,7 +128,6 @@ "//content/public/app:plugin_manifest", "//content/public/app:renderer_manifest", "//content/public/app:utility_manifest", - "//services/catalog:manifest", ] }
diff --git a/content/app/content_service_manager_main_delegate.cc b/content/app/content_service_manager_main_delegate.cc index fc86a74..3a6bc4e 100644 --- a/content/app/content_service_manager_main_delegate.cc +++ b/content/app/content_service_manager_main_delegate.cc
@@ -74,9 +74,9 @@ config->is_broker_process = true; } -std::unique_ptr<base::Value> -ContentServiceManagerMainDelegate::CreateServiceCatalog() { - return nullptr; +std::vector<service_manager::Manifest> +ContentServiceManagerMainDelegate::GetServiceManifests() { + return std::vector<service_manager::Manifest>(); } bool ContentServiceManagerMainDelegate::ShouldLaunchAsServiceProcess(
diff --git a/content/app/content_service_manager_main_delegate.h b/content/app/content_service_manager_main_delegate.h index 6f32f97..864f2a5 100644 --- a/content/app/content_service_manager_main_delegate.h +++ b/content/app/content_service_manager_main_delegate.h
@@ -30,7 +30,7 @@ void ShutDownEmbedderProcess() override; service_manager::ProcessType OverrideProcessType() override; void OverrideMojoConfiguration(mojo::core::Configuration* config) override; - std::unique_ptr<base::Value> CreateServiceCatalog() override; + std::vector<service_manager::Manifest> GetServiceManifests() override; bool ShouldLaunchAsServiceProcess( const service_manager::Identity& identity) override; void AdjustServiceProcessCommandLine(
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 4075a29a8..3e4a430 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -872,8 +872,6 @@ "frame_host/navigation_controller_impl.h", "frame_host/navigation_entry_impl.cc", "frame_host/navigation_entry_impl.h", - "frame_host/navigation_entry_screenshot_manager.cc", - "frame_host/navigation_entry_screenshot_manager.h", "frame_host/navigation_handle_impl.cc", "frame_host/navigation_handle_impl.h", "frame_host/navigation_request.cc",
diff --git a/content/browser/child_process_launcher.cc b/content/browser/child_process_launcher.cc index bd16e1b..6b7f72e 100644 --- a/content/browser/child_process_launcher.cc +++ b/content/browser/child_process_launcher.cc
@@ -149,7 +149,7 @@ // static void ChildProcessLauncher::SetRegisteredFilesForService( const std::string& service_name, - catalog::RequiredFileMap required_files) { + std::map<std::string, base::FilePath> required_files) { ChildProcessLauncherHelper::SetRegisteredFilesForService( service_name, std::move(required_files)); }
diff --git a/content/browser/child_process_launcher.h b/content/browser/child_process_launcher.h index 26f1376..415d916d 100644 --- a/content/browser/child_process_launcher.h +++ b/content/browser/child_process_launcher.h
@@ -210,7 +210,7 @@ // for the service |service_name|. static void SetRegisteredFilesForService( const std::string& service_name, - catalog::RequiredFileMap required_files); + std::map<std::string, base::FilePath> required_files); // Resets all files registered by |SetRegisteredFilesForService|. Used to // support multiple shell context creation in unit_tests.
diff --git a/content/browser/child_process_launcher_helper.h b/content/browser/child_process_launcher_helper.h index 4dbac12..9b93e1f 100644 --- a/content/browser/child_process_launcher_helper.h +++ b/content/browser/child_process_launcher_helper.h
@@ -5,6 +5,7 @@ #ifndef CONTENT_BROWSER_CHILD_PROCESS_LAUNCHER_HELPER_H_ #define CONTENT_BROWSER_CHILD_PROCESS_LAUNCHER_HELPER_H_ +#include <map> #include <memory> #include "base/macros.h" @@ -17,7 +18,6 @@ #include "content/public/common/result_codes.h" #include "mojo/public/cpp/platform/platform_channel.h" #include "mojo/public/cpp/system/invitation.h" -#include "services/catalog/public/cpp/manifest_parsing_util.h" #include "services/service_manager/zygote/common/zygote_buildflags.h" #if !defined(OS_FUCHSIA) @@ -182,7 +182,7 @@ static void SetRegisteredFilesForService( const std::string& service_name, - catalog::RequiredFileMap required_files); + std::map<std::string, base::FilePath> required_files); static void ResetRegisteredFilesForTesting();
diff --git a/content/browser/child_process_launcher_helper_android.cc b/content/browser/child_process_launcher_helper_android.cc index caacdf8..04bfd4ac 100644 --- a/content/browser/child_process_launcher_helper_android.cc +++ b/content/browser/child_process_launcher_helper_android.cc
@@ -234,7 +234,7 @@ // static void ChildProcessLauncherHelper::SetRegisteredFilesForService( const std::string& service_name, - catalog::RequiredFileMap required_files) { + std::map<std::string, base::FilePath> required_files) { SetFilesToShareForServicePosix(service_name, std::move(required_files)); }
diff --git a/content/browser/child_process_launcher_helper_fuchsia.cc b/content/browser/child_process_launcher_helper_fuchsia.cc index bd84693..06e1067 100644 --- a/content/browser/child_process_launcher_helper_fuchsia.cc +++ b/content/browser/child_process_launcher_helper_fuchsia.cc
@@ -40,7 +40,7 @@ // static void ChildProcessLauncherHelper::SetRegisteredFilesForService( const std::string& service_name, - catalog::RequiredFileMap required_files) { + std::map<std::string, base::FilePath> required_files) { // TODO(fuchsia): Implement this. (crbug.com/707031) NOTIMPLEMENTED(); }
diff --git a/content/browser/child_process_launcher_helper_linux.cc b/content/browser/child_process_launcher_helper_linux.cc index c981f7f..c715a86d0 100644 --- a/content/browser/child_process_launcher_helper_linux.cc +++ b/content/browser/child_process_launcher_helper_linux.cc
@@ -164,7 +164,7 @@ // static void ChildProcessLauncherHelper::SetRegisteredFilesForService( const std::string& service_name, - catalog::RequiredFileMap required_files) { + std::map<std::string, base::FilePath> required_files) { SetFilesToShareForServicePosix(service_name, std::move(required_files)); }
diff --git a/content/browser/child_process_launcher_helper_mac.cc b/content/browser/child_process_launcher_helper_mac.cc index de7b7ff..d240f93 100644 --- a/content/browser/child_process_launcher_helper_mac.cc +++ b/content/browser/child_process_launcher_helper_mac.cc
@@ -254,7 +254,7 @@ // static void ChildProcessLauncherHelper::SetRegisteredFilesForService( const std::string& service_name, - catalog::RequiredFileMap required_files) { + std::map<std::string, base::FilePath> required_files) { // No file passing from the manifest on Mac yet. DCHECK(required_files.empty()); }
diff --git a/content/browser/child_process_launcher_helper_posix.cc b/content/browser/child_process_launcher_helper_posix.cc index 15a9977..2ca43941 100644 --- a/content/browser/child_process_launcher_helper_posix.cc +++ b/content/browser/child_process_launcher_helper_posix.cc
@@ -16,7 +16,6 @@ #include "content/public/common/content_descriptors.h" #include "content/public/common/content_switches.h" #include "mojo/public/cpp/platform/platform_channel_endpoint.h" -#include "services/catalog/public/cpp/manifest_parsing_util.h" #include "services/service_manager/embedder/shared_file_util.h" #include "services/service_manager/embedder/switches.h" @@ -26,7 +25,7 @@ namespace { using RequiredFilesByServiceMap = - std::map<std::string, catalog::RequiredFileMap>; + std::map<std::string, std::map<std::string, base::FilePath>>; RequiredFilesByServiceMap& GetRequiredFilesByServiceMap() { static auto* required_files_by_service = new RequiredFilesByServiceMap(); @@ -113,7 +112,8 @@ const std::string& service_name = service_name_iter->second; auto files_iter = GetRequiredFilesByServiceMap().find(service_name); if (files_iter != GetRequiredFilesByServiceMap().end()) { - const catalog::RequiredFileMap& required_files_map = files_iter->second; + const std::map<std::string, base::FilePath>& required_files_map = + files_iter->second; base::GlobalDescriptors::Key key = kContentDynamicDescriptorStart; service_manager::SharedFileSwitchValueBuilder file_switch_value_builder; for (const auto& key_path_iter : required_files_map) { @@ -137,8 +137,9 @@ return files_to_register; } -void SetFilesToShareForServicePosix(const std::string& service_name, - catalog::RequiredFileMap required_files) { +void SetFilesToShareForServicePosix( + const std::string& service_name, + std::map<std::string, base::FilePath> required_files) { if (required_files.empty()) return;
diff --git a/content/browser/child_process_launcher_helper_posix.h b/content/browser/child_process_launcher_helper_posix.h index 956c6d3a..9622650 100644 --- a/content/browser/child_process_launcher_helper_posix.h +++ b/content/browser/child_process_launcher_helper_posix.h
@@ -5,11 +5,11 @@ #ifndef CONTENT_BROWSER_CHILD_PROCESS_LAUNCHER_HELPER_POSIX_H_ #define CONTENT_BROWSER_CHILD_PROCESS_LAUNCHER_HELPER_POSIX_H_ +#include <map> #include <memory> #include "base/files/file.h" #include "base/files/memory_mapped_file.h" -#include "services/catalog/public/cpp/manifest_parsing_util.h" namespace base { class CommandLine; @@ -38,8 +38,9 @@ // Called by the service manager to register the files that should be mapped for // a service in the child process. -void SetFilesToShareForServicePosix(const std::string& service_name, - catalog::RequiredFileMap required_files); +void SetFilesToShareForServicePosix( + const std::string& service_name, + std::map<std::string, base::FilePath> required_files); // Called from unit_tests in order to reset all previously registered files. void ResetFilesToShareForTestingPosix();
diff --git a/content/browser/child_process_launcher_helper_win.cc b/content/browser/child_process_launcher_helper_win.cc index 4deb943..4aa0c71 100644 --- a/content/browser/child_process_launcher_helper_win.cc +++ b/content/browser/child_process_launcher_helper_win.cc
@@ -121,7 +121,7 @@ // static void ChildProcessLauncherHelper::SetRegisteredFilesForService( const std::string& service_name, - catalog::RequiredFileMap required_files) { + std::map<std::string, base::FilePath> required_files) { // No file passing from the manifest on Windows yet. DCHECK(required_files.empty()); }
diff --git a/content/browser/child_process_security_policy_impl.cc b/content/browser/child_process_security_policy_impl.cc index 41d7b99..c3c9689 100644 --- a/content/browser/child_process_security_policy_impl.cc +++ b/content/browser/child_process_security_policy_impl.cc
@@ -441,26 +441,8 @@ } void ChildProcessSecurityPolicyImpl::Remove(int child_id) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); base::AutoLock lock(lock_); - - auto state = security_state_.find(child_id); - if (state == security_state_.end()) - return; - - pending_remove_state_[child_id] = std::move(state->second); security_state_.erase(child_id); - - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&ChildProcessSecurityPolicyImpl::RemovePendingIDOnIOThread, - base::Unretained(this), child_id)); -} - -void ChildProcessSecurityPolicyImpl::RemovePendingIDOnIOThread(int child_id) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - base::AutoLock lock(lock_); - pending_remove_state_.erase(child_id); } void ChildProcessSecurityPolicyImpl::RegisterWebSafeScheme( @@ -1169,20 +1151,21 @@ SiteInstanceImpl::DetermineProcessLockURL(nullptr, url); base::AutoLock lock(lock_); - SecurityState* security_state = GetSecurityState(child_id); - - bool can_access = security_state && security_state->CanAccessDataForOrigin( - expected_process_lock); + auto state = security_state_.find(child_id); + if (state == security_state_.end()) { + // TODO(nick): Returning true instead of false here is a temporary + // workaround for https://crbug.com/600441 + return true; + } + bool can_access = + state->second->CanAccessDataForOrigin(expected_process_lock); if (!can_access) { // Returning false here will result in a renderer kill. Set some crash // keys that will help understand the circumstances of that kill. base::debug::SetCrashKeyString(bad_message::GetRequestedSiteURLKey(), expected_process_lock.spec()); - base::debug::SetCrashKeyString(bad_message::GetKilledProcessOriginLockKey(), - security_state - ? security_state->origin_lock().spec() - : "(child id not found)"); + state->second->origin_lock().spec()); static auto* requested_origin_key = base::debug::AllocateCrashKeyString( "requested_origin", base::debug::CrashKeySize::Size64); @@ -1384,22 +1367,4 @@ isolated_origins_.erase(key); } -ChildProcessSecurityPolicyImpl::SecurityState* -ChildProcessSecurityPolicyImpl::GetSecurityState(int child_id) { - auto itr = security_state_.find(child_id); - if (itr != security_state_.end()) - return itr->second.get(); - - if (BrowserThread::CurrentlyOn(BrowserThread::IO)) { - // Checking to see if |child_id| is in the pending removal map since this - // may be a call that was already on the IO thread task queue when the - // Remove() call occurred on the UI thread. - itr = pending_remove_state_.find(child_id); - if (itr != pending_remove_state_.end()) - return itr->second.get(); - } - - return nullptr; -} - } // namespace content
diff --git a/content/browser/child_process_security_policy_impl.h b/content/browser/child_process_security_policy_impl.h index 271a5685..82d5dd4 100644 --- a/content/browser/child_process_security_policy_impl.h +++ b/content/browser/child_process_security_policy_impl.h
@@ -162,10 +162,6 @@ // Upon destruction, child processess should unregister themselves by caling // this method exactly once. - // - // Note: IO thread is expected to keep pre-Remove() permissions until - // RemovePendingIDOnIOThread() runs on the IO thread. The UI thread is - // expected to have no permissions after Remove() returns. void Remove(int child_id); // Whenever the browser processes commands the child process to commit a URL, @@ -371,14 +367,6 @@ const std::string& filesystem_id, int permission); - // Removes |child_id| from |pending_remove_state_| on the IO thread. - void RemovePendingIDOnIOThread(int child_id); - - // Gets the SecurityState object associated with |child_id|. - // Note: Returned object is only valid for the duration the caller holds - // |lock_|. - SecurityState* GetSecurityState(int child_id) EXCLUSIVE_LOCKS_REQUIRED(lock_); - // You must acquire this lock before reading or writing any members of this // class. You must not block while holding this lock. base::Lock lock_; @@ -400,13 +388,6 @@ // not escape this class. SecurityStateMap security_state_ GUARDED_BY(lock_); - // This map holds the SecurityState for a child process after Remove() - // is called on the UI thread and until RemovePendingIDOnIOThread() is - // called on the IO thread. This is necessary to provide consistent - // security decisions and avoid races between the UI & IO threads during - // child process shutdown. - SecurityStateMap pending_remove_state_ GUARDED_BY(lock_); - FileSystemPermissionPolicyMap file_system_policy_map_ GUARDED_BY(lock_); // Tracks origins for which the entire origin should be treated as a site
diff --git a/content/browser/child_process_security_policy_unittest.cc b/content/browser/child_process_security_policy_unittest.cc index 3d43ebc..3101bc1 100644 --- a/content/browser/child_process_security_policy_unittest.cc +++ b/content/browser/child_process_security_policy_unittest.cc
@@ -7,8 +7,6 @@ #include "base/files/file_path.h" #include "base/logging.h" -#include "base/synchronization/waitable_event.h" -#include "base/test/bind_test_util.h" #include "base/test/mock_log.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/site_instance_impl.h" @@ -61,9 +59,7 @@ class ChildProcessSecurityPolicyTest : public testing::Test { public: - ChildProcessSecurityPolicyTest() - : thread_bundle_(TestBrowserThreadBundle::REAL_IO_THREAD), - old_browser_client_(nullptr) {} + ChildProcessSecurityPolicyTest() : old_browser_client_(nullptr) {} void SetUp() override { old_browser_client_ = SetBrowserClientForTesting(&test_browser_client_); @@ -997,85 +993,6 @@ EXPECT_FALSE(p->HasWebUIBindings(kRendererID)); } -TEST_F(ChildProcessSecurityPolicyTest, RemoveRace_CanAccessDataForOrigin) { - ChildProcessSecurityPolicyImpl* p = - ChildProcessSecurityPolicyImpl::GetInstance(); - - GURL url("file:///etc/passwd"); - - p->Add(kRendererID); - - base::WaitableEvent ready_for_remove_event; - base::WaitableEvent remove_called_event; - base::WaitableEvent pending_remove_complete_event; - - bool io_before_remove = false; - bool io_while_remove_pending = false; - bool io_after_remove_complete = false; - bool ui_before_remove = false; - bool ui_while_remove_pending = false; - bool ui_after_remove_complete = false; - - // Post a task that will run on the IO thread before the task that - // Remove() will post to the IO thread. - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, base::BindLambdaForTesting([&]() { - // Capture state on the IO thread before Remove() is called. - io_before_remove = p->CanAccessDataForOrigin(kRendererID, url); - - // Tell the UI thread we are ready for Remove() to be called. - ready_for_remove_event.Signal(); - - // Wait for Remove() to be called on the UI thread. - remove_called_event.Wait(); - - // Capture state after Remove() is called, but before its task on - // the IO thread runs. - io_while_remove_pending = p->CanAccessDataForOrigin(kRendererID, url); - })); - - ready_for_remove_event.Wait(); - - ui_before_remove = p->CanAccessDataForOrigin(kRendererID, url); - - p->Remove(kRendererID); - - // Post a task to run after the task Remove() posted on the IO thread. - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, base::BindLambdaForTesting([&]() { - io_after_remove_complete = p->CanAccessDataForOrigin(kRendererID, url); - - // Tell the UI thread that the task from Remove() has completed on the - // IO thread. - pending_remove_complete_event.Signal(); - })); - - // Capture state after Remove() has been called, but before its IO thread - // task has run. We know the IO thread task hasn't run yet because the - // task we posted before the Remove() call is waiting for us to signal - // |remove_called_event|. - ui_while_remove_pending = p->CanAccessDataForOrigin(kRendererID, url); - - // Unblock the IO thread so the pending remove events can run. - remove_called_event.Signal(); - - pending_remove_complete_event.Wait(); - - ui_after_remove_complete = p->CanAccessDataForOrigin(kRendererID, url); - - // Verify expected states at various parts of the removal. - // Note: IO thread is expected to keep pre-Remove() permissions until its - // remove task runs on the IO thread. The UI thread is expected to have no - // permissions after Remove() returns. - EXPECT_TRUE(io_before_remove); - EXPECT_TRUE(io_while_remove_pending); - EXPECT_FALSE(io_after_remove_complete); - - EXPECT_TRUE(ui_before_remove); - EXPECT_FALSE(ui_while_remove_pending); - EXPECT_FALSE(ui_after_remove_complete); -} - // Test the granting of origin permissions, and their interactions with // granting scheme permissions. TEST_F(ChildProcessSecurityPolicyTest, OriginGranting) {
diff --git a/content/browser/dom_storage/session_storage_context_mojo_unittest.cc b/content/browser/dom_storage/session_storage_context_mojo_unittest.cc index ebf479c..c701b61 100644 --- a/content/browser/dom_storage/session_storage_context_mojo_unittest.cc +++ b/content/browser/dom_storage/session_storage_context_mojo_unittest.cc
@@ -17,7 +17,6 @@ #include "base/test/bind_test_util.h" #include "base/test/scoped_feature_list.h" #include "components/services/leveldb/public/cpp/util.h" -#include "content/browser/child_process_security_policy_impl.h" #include "content/browser/dom_storage/session_storage_database.h" #include "content/browser/dom_storage/test/fake_leveldb_database_error_on_write.h" #include "content/browser/dom_storage/test/fake_leveldb_service.h" @@ -63,13 +62,9 @@ features_.InitAndEnableFeature(blink::features::kOnionSoupDOMStorage); mojo::core::SetDefaultProcessErrorCallback(base::BindRepeating( &SessionStorageContextMojoTest::OnBadMessage, base::Unretained(this))); - - ChildProcessSecurityPolicyImpl::GetInstance()->Add(kTestProcessId); } void TearDown() override { - ChildProcessSecurityPolicyImpl::GetInstance()->Remove(kTestProcessId); - mojo::core::SetDefaultProcessErrorCallback( mojo::core::ProcessErrorCallback()); }
diff --git a/content/browser/dom_storage/test/mojo_test_with_file_service.h b/content/browser/dom_storage/test/mojo_test_with_file_service.h index 8ae2bbb..77d6eae 100644 --- a/content/browser/dom_storage/test/mojo_test_with_file_service.h +++ b/content/browser/dom_storage/test/mojo_test_with_file_service.h
@@ -10,7 +10,7 @@ #include "base/files/file_path.h" #include "base/files/scoped_temp_dir.h" #include "base/macros.h" -#include "content/public/test/test_browser_thread_bundle.h" +#include "base/test/scoped_task_environment.h" #include "services/file/file_service.h" #include "services/service_manager/public/cpp/test/test_connector_factory.h" #include "testing/gtest/include/gtest/gtest.h" @@ -34,10 +34,10 @@ return test_connector_factory_.GetDefaultConnector(); } - void RunUntilIdle() { thread_bundle_.RunUntilIdle(); } + void RunUntilIdle() { scoped_task_environment_.RunUntilIdle(); } private: - TestBrowserThreadBundle thread_bundle_; + base::test::ScopedTaskEnvironment scoped_task_environment_; service_manager::TestConnectorFactory test_connector_factory_; file::FileService file_service_; base::ScopedTempDir temp_path_;
diff --git a/content/browser/fileapi/browser_file_system_helper_unittest.cc b/content/browser/fileapi/browser_file_system_helper_unittest.cc index 67e528b5..1b0cff4 100644 --- a/content/browser/fileapi/browser_file_system_helper_unittest.cc +++ b/content/browser/fileapi/browser_file_system_helper_unittest.cc
@@ -13,7 +13,6 @@ #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/fileapi/browser_file_system_helper.h" #include "content/public/common/drop_data.h" -#include "content/public/test/test_browser_thread_bundle.h" #include "net/base/filename_util.h" #include "storage/browser/fileapi/external_mount_points.h" #include "storage/browser/fileapi/file_system_options.h" @@ -34,7 +33,6 @@ base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); - TestBrowserThreadBundle thread_bundle; ChildProcessSecurityPolicyImpl* p = ChildProcessSecurityPolicyImpl::GetInstance(); p->Add(kRendererID); @@ -138,7 +136,6 @@ base::ScopedTempDir temp_dir; ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); - TestBrowserThreadBundle thread_bundle; ChildProcessSecurityPolicyImpl* p = ChildProcessSecurityPolicyImpl::GetInstance(); p->Add(kRendererID);
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc index 424158e..2a983133 100644 --- a/content/browser/frame_host/navigation_controller_impl.cc +++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -57,7 +57,6 @@ #include "content/browser/frame_host/debug_urls.h" #include "content/browser/frame_host/interstitial_page_impl.h" #include "content/browser/frame_host/navigation_entry_impl.h" -#include "content/browser/frame_host/navigation_entry_screenshot_manager.h" #include "content/browser/frame_host/navigation_handle_impl.h" #include "content/browser/frame_host/navigator.h" #include "content/browser/renderer_host/render_view_host_impl.h" // Temporary @@ -478,7 +477,6 @@ in_navigate_to_pending_entry_(false), pending_reload_(ReloadType::NONE), get_timestamp_callback_(base::Bind(&base::Time::Now)), - screenshot_manager_(new NavigationEntryScreenshotManager(this)), last_committed_reload_type_(ReloadType::NONE) { DCHECK(browser_context_); } @@ -740,18 +738,6 @@ return GetCurrentEntryIndex() + offset; } -void NavigationControllerImpl::TakeScreenshot() { - screenshot_manager_->TakeScreenshot(); -} - -void NavigationControllerImpl::SetScreenshotManager( - std::unique_ptr<NavigationEntryScreenshotManager> manager) { - if (manager.get()) - screenshot_manager_ = std::move(manager); - else - screenshot_manager_.reset(new NavigationEntryScreenshotManager(this)); -} - bool NavigationControllerImpl::CanGoBack() const { return CanGoToOffset(-1); } @@ -2186,10 +2172,6 @@ std::move(request), ReloadType::NONE, RestoreType::NONE); } -void NavigationControllerImpl::ClearAllScreenshots() { - screenshot_manager_->ClearAllScreenshots(); -} - void NavigationControllerImpl::SetSessionStorageNamespace( const std::string& partition_id, SessionStorageNamespace* session_storage_namespace) {
diff --git a/content/browser/frame_host/navigation_controller_impl.h b/content/browser/frame_host/navigation_controller_impl.h index e7e2d32..0023690 100644 --- a/content/browser/frame_host/navigation_controller_impl.h +++ b/content/browser/frame_host/navigation_controller_impl.h
@@ -30,7 +30,6 @@ enum class WasActivatedOption; class FrameTreeNode; class RenderFrameHostImpl; -class NavigationEntryScreenshotManager; class SiteInstance; struct LoadCommittedDetails; @@ -119,8 +118,6 @@ const std::string& extra_headers, scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory); - void ClearAllScreenshots() override; - // Whether this is the initial navigation in an unmodified new tab. In this // case, we know there is no content displayed in the page. bool IsUnmodifiedBlankTab() const; @@ -224,14 +221,6 @@ void SetGetTimestampCallbackForTest( const base::Callback<base::Time()>& get_timestamp_callback); - // Takes a screenshot of the page at the current state. - void TakeScreenshot(); - - // Sets the screenshot manager for this NavigationControllerImpl. Setting a - // NULL manager recreates the default screenshot manager and uses that. - void SetScreenshotManager( - std::unique_ptr<NavigationEntryScreenshotManager> manager); - // Discards only the pending entry. |was_failure| should be set if the pending // entry is being discarded because it failed to load. void DiscardPendingEntry(bool was_failure); @@ -252,8 +241,6 @@ private: friend class RestoreHelper; - FRIEND_TEST_ALL_PREFIXES(NavigationControllerTest, - PurgeScreenshot); FRIEND_TEST_ALL_PREFIXES(TimeSmoother, Basic); FRIEND_TEST_ALL_PREFIXES(TimeSmoother, SingleDuplicate); FRIEND_TEST_ALL_PREFIXES(TimeSmoother, ManyDuplicates); @@ -539,8 +526,6 @@ // the wrong order in the history view. TimeSmoother time_smoother_; - std::unique_ptr<NavigationEntryScreenshotManager> screenshot_manager_; - // Used for tracking consecutive reload requests. If the last user-initiated // navigation (either browser-initiated or renderer-initiated with a user // gesture) was a reload, these hold the ReloadType and timestamp. Otherwise
diff --git a/content/browser/frame_host/navigation_controller_impl_unittest.cc b/content/browser/frame_host/navigation_controller_impl_unittest.cc index 2c11419..e22d7d50 100644 --- a/content/browser/frame_host/navigation_controller_impl_unittest.cc +++ b/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -26,7 +26,6 @@ #include "content/browser/browser_url_handler_impl.h" #include "content/browser/frame_host/frame_navigation_entry.h" #include "content/browser/frame_host/navigation_entry_impl.h" -#include "content/browser/frame_host/navigation_entry_screenshot_manager.h" #include "content/browser/frame_host/navigation_handle_impl.h" #include "content/browser/frame_host/navigation_request.h" #include "content/browser/frame_host/navigator.h" @@ -83,50 +82,6 @@ a_bitmap.computeByteSize()) == 0; } -class MockScreenshotManager : public content::NavigationEntryScreenshotManager { - public: - explicit MockScreenshotManager(content::NavigationControllerImpl* owner) - : content::NavigationEntryScreenshotManager(owner), - encoding_screenshot_in_progress_(false) { - } - - ~MockScreenshotManager() override {} - - void TakeScreenshotFor(content::NavigationEntryImpl* entry) { - SkBitmap bitmap; - bitmap.allocPixels(SkImageInfo::Make( - 1, 1, kAlpha_8_SkColorType, kPremul_SkAlphaType)); - bitmap.eraseARGB(0, 0, 0, 0); - encoding_screenshot_in_progress_ = true; - OnScreenshotTaken(entry->GetUniqueID(), bitmap); - WaitUntilScreenshotIsReady(); - } - - int GetScreenshotCount() { - return content::NavigationEntryScreenshotManager::GetScreenshotCount(); - } - - void WaitUntilScreenshotIsReady() { - if (!encoding_screenshot_in_progress_) - return; - message_loop_runner_ = new content::MessageLoopRunner; - message_loop_runner_->Run(); - } - - private: - void OnScreenshotSet(content::NavigationEntryImpl* entry) override { - encoding_screenshot_in_progress_ = false; - NavigationEntryScreenshotManager::OnScreenshotSet(entry); - if (message_loop_runner_.get()) - message_loop_runner_->Quit(); - } - - scoped_refptr<content::MessageLoopRunner> message_loop_runner_; - bool encoding_screenshot_in_progress_; - - DISALLOW_COPY_AND_ASSIGN(MockScreenshotManager); -}; - int64_t GenerateSequenceNumber() { // Based on how Blink generates sequence numbers. static int64_t next_number = base::Time::Now().ToDoubleT() * 1000000; @@ -4747,93 +4702,6 @@ EXPECT_TRUE(DoImagesMatch(favicon_image, entry->GetFavicon().image)); } -// The test crashes on android: http://crbug.com/170449 -#if defined(OS_ANDROID) -#define MAYBE_PurgeScreenshot DISABLED_PurgeScreenshot -#else -#define MAYBE_PurgeScreenshot PurgeScreenshot -#endif -// Tests that screenshot are purged correctly. -TEST_F(NavigationControllerTest, MAYBE_PurgeScreenshot) { - NavigationControllerImpl& controller = controller_impl(); - - NavigationEntryImpl* entry; - - // Navigate enough times to make sure that some screenshots are purged. - for (int i = 0; i < 12; ++i) { - const GURL url(base::StringPrintf("http://foo%d/", i)); - NavigateAndCommit(url); - EXPECT_EQ(i, controller.GetCurrentEntryIndex()); - } - - MockScreenshotManager* screenshot_manager = - new MockScreenshotManager(&controller); - controller.SetScreenshotManager(base::WrapUnique(screenshot_manager)); - for (int i = 0; i < controller.GetEntryCount(); ++i) { - entry = controller.GetEntryAtIndex(i); - screenshot_manager->TakeScreenshotFor(entry); - EXPECT_TRUE(entry->screenshot().get()); - } - - NavigateAndCommit(GURL("https://foo/")); - EXPECT_EQ(13, controller.GetEntryCount()); - entry = controller.GetEntryAtIndex(11); - screenshot_manager->TakeScreenshotFor(entry); - - for (int i = 0; i < 2; ++i) { - entry = controller.GetEntryAtIndex(i); - EXPECT_FALSE(entry->screenshot().get()) << "Screenshot " << i - << " not purged"; - } - - for (int i = 2; i < controller.GetEntryCount() - 1; ++i) { - entry = controller.GetEntryAtIndex(i); - EXPECT_TRUE(entry->screenshot().get()) << "Screenshot not found for " << i; - } - - // Navigate to index 5 and then try to assign screenshot to all entries. - controller.GoToIndex(5); - contents()->CommitPendingNavigation(); - EXPECT_EQ(5, controller.GetCurrentEntryIndex()); - for (int i = 0; i < controller.GetEntryCount() - 1; ++i) { - entry = controller.GetEntryAtIndex(i); - screenshot_manager->TakeScreenshotFor(entry); - } - - for (int i = 10; i <= 12; ++i) { - entry = controller.GetEntryAtIndex(i); - EXPECT_FALSE(entry->screenshot().get()) << "Screenshot " << i - << " not purged"; - screenshot_manager->TakeScreenshotFor(entry); - } - - // Navigate to index 7 and assign screenshot to all entries. - controller.GoToIndex(7); - contents()->CommitPendingNavigation(); - EXPECT_EQ(7, controller.GetCurrentEntryIndex()); - for (int i = 0; i < controller.GetEntryCount() - 1; ++i) { - entry = controller.GetEntryAtIndex(i); - screenshot_manager->TakeScreenshotFor(entry); - } - - for (int i = 0; i < 2; ++i) { - entry = controller.GetEntryAtIndex(i); - EXPECT_FALSE(entry->screenshot().get()) << "Screenshot " << i - << " not purged"; - } - - // Clear all screenshots. - EXPECT_EQ(13, controller.GetEntryCount()); - EXPECT_EQ(10, screenshot_manager->GetScreenshotCount()); - controller.ClearAllScreenshots(); - EXPECT_EQ(0, screenshot_manager->GetScreenshotCount()); - for (int i = 0; i < controller.GetEntryCount(); ++i) { - entry = controller.GetEntryAtIndex(i); - EXPECT_FALSE(entry->screenshot().get()) << "Screenshot " << i - << " not cleared"; - } -} - TEST_F(NavigationControllerTest, PushStateUpdatesTitleAndFavicon) { // Navigate. NavigationSimulator::NavigateAndCommitFromDocument(GURL("http://foo"),
diff --git a/content/browser/frame_host/navigation_entry_impl.cc b/content/browser/frame_host/navigation_entry_impl.cc index 6a8cdf37..f65390e 100644 --- a/content/browser/frame_host/navigation_entry_impl.cc +++ b/content/browser/frame_host/navigation_entry_impl.cc
@@ -15,7 +15,6 @@ #include "base/files/file_path.h" #include "base/i18n/rtl.h" #include "base/memory/ptr_util.h" -#include "base/metrics/histogram_macros.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" @@ -664,7 +663,6 @@ copy->timestamp_ = timestamp_; copy->http_status_code_ = http_status_code_; // ResetForCommit: post_data_ - copy->screenshot_ = screenshot_; copy->extra_headers_ = extra_headers_; copy->base_url_for_data_url_ = base_url_for_data_url_; #if defined(OS_ANDROID) @@ -925,13 +923,6 @@ } } -void NavigationEntryImpl::SetScreenshotPNGData( - scoped_refptr<base::RefCountedBytes> png_data) { - screenshot_ = png_data; - if (screenshot_.get()) - UMA_HISTOGRAM_MEMORY_KB("Overscroll.ScreenshotSize", screenshot_->size()); -} - GURL NavigationEntryImpl::GetHistoryURLForDataURL() const { return GetBaseURLForDataURL().is_empty() ? GURL() : GetVirtualURL(); }
diff --git a/content/browser/frame_host/navigation_entry_impl.h b/content/browser/frame_host/navigation_entry_impl.h index 61af0b2..89d2fb5 100644 --- a/content/browser/frame_host/navigation_entry_impl.h +++ b/content/browser/frame_host/navigation_entry_impl.h
@@ -370,11 +370,6 @@ should_replace_entry_ = should_replace_entry; } - void SetScreenshotPNGData(scoped_refptr<base::RefCountedBytes> png_data); - const scoped_refptr<base::RefCountedBytes> screenshot() const { - return screenshot_; - } - // Whether this (pending) navigation should clear the session history. Resets // to false after commit. bool should_clear_history_list() const { @@ -463,15 +458,6 @@ // compiler provided copy constructor. Cleared in |ResetForCommit|. scoped_refptr<network::ResourceRequestBody> post_data_; - // This is also a transient member (i.e. is not persisted with session - // restore). The screenshot of a page is taken when navigating away from the - // page. This screenshot is displayed during an overscroll-navigation - // gesture. |screenshot_| will be NULL when the screenshot is not available - // (e.g. after a session restore, or if taking the screenshot of a page - // failed). The UI is responsible for dealing with missing screenshots - // appropriately (e.g. display a placeholder image instead). - scoped_refptr<base::RefCountedBytes> screenshot_; - // This member is not persisted with session restore. std::string extra_headers_;
diff --git a/content/browser/frame_host/navigation_entry_screenshot_manager.cc b/content/browser/frame_host/navigation_entry_screenshot_manager.cc deleted file mode 100644 index 5930c7d..0000000 --- a/content/browser/frame_host/navigation_entry_screenshot_manager.cc +++ /dev/null
@@ -1,272 +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 "content/browser/frame_host/navigation_entry_screenshot_manager.h" - -#include "base/command_line.h" -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/ref_counted_memory.h" -#include "base/task/post_task.h" -#include "content/browser/frame_host/navigation_controller_impl.h" -#include "content/browser/frame_host/navigation_entry_impl.h" -#include "content/browser/renderer_host/render_view_host_impl.h" -#include "content/public/browser/overscroll_configuration.h" -#include "content/public/browser/render_widget_host.h" -#include "content/public/browser/render_widget_host_view.h" -#include "content/public/common/content_switches.h" -#include "third_party/skia/include/core/SkCanvas.h" -#include "third_party/skia/include/core/SkColorFilter.h" -#include "third_party/skia/include/core/SkPaint.h" -#include "third_party/skia/include/effects/SkLumaColorFilter.h" -#include "ui/gfx/codec/png_codec.h" - -namespace { - -// Minimum delay between taking screenshots. -const int kMinScreenshotIntervalMS = 1000; - -} - -namespace content { - -// Encodes the A8 SkBitmap to grayscale PNG in a worker thread. -class ScreenshotData : public base::RefCountedThreadSafe<ScreenshotData> { - public: - ScreenshotData() { - } - - void EncodeScreenshot(const SkBitmap& bitmap, base::OnceClosure callback) { - base::PostTaskWithTraitsAndReply( - FROM_HERE, {base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, - base::BindOnce(&ScreenshotData::EncodeOnWorker, this, bitmap), - std::move(callback)); - } - - scoped_refptr<base::RefCountedBytes> data() const { return data_; } - - private: - friend class base::RefCountedThreadSafe<ScreenshotData>; - virtual ~ScreenshotData() { - } - - void EncodeOnWorker(const SkBitmap& bitmap) { - // Convert |bitmap| to alpha-only |grayscale_bitmap|. - SkBitmap grayscale_bitmap; - if (grayscale_bitmap.tryAllocPixels( - SkImageInfo::MakeA8(bitmap.width(), bitmap.height()))) { - SkCanvas canvas(grayscale_bitmap); -#if defined(MEMORY_SANITIZER) - // This is needed because Skia will operate over uninitialized memory - // outside the visible region (with non-visible effects). - canvas.clear(SK_ColorBLACK); -#endif - SkPaint paint; - paint.setColorFilter(SkLumaColorFilter::Make()); - canvas.drawBitmap(bitmap, SkIntToScalar(0), SkIntToScalar(0), &paint); - canvas.flush(); - } - if (!grayscale_bitmap.readyToDraw()) - return; - - // Encode the A8 bitmap to grayscale PNG treating alpha as color intensity. - std::vector<unsigned char> data; - if (gfx::PNGCodec::EncodeA8SkBitmap(grayscale_bitmap, &data)) - data_ = base::RefCountedBytes::TakeVector(&data); - } - - scoped_refptr<base::RefCountedBytes> data_; - - DISALLOW_COPY_AND_ASSIGN(ScreenshotData); -}; - -NavigationEntryScreenshotManager::NavigationEntryScreenshotManager( - NavigationControllerImpl* owner) - : owner_(owner), - min_screenshot_interval_ms_(kMinScreenshotIntervalMS), - screenshot_factory_(this) { - -} - -NavigationEntryScreenshotManager::~NavigationEntryScreenshotManager() { -} - -void NavigationEntryScreenshotManager::TakeScreenshot() { - if (OverscrollConfig::GetHistoryNavigationMode() != - OverscrollConfig::HistoryNavigationMode::kParallaxUi) { - return; - } - - NavigationEntryImpl* entry = owner_->GetLastCommittedEntry(); - if (!entry) - return; - - if (!owner_->delegate()->CanOverscrollContent()) - return; - - RenderViewHost* render_view_host = owner_->delegate()->GetRenderViewHost(); - DCHECK(render_view_host && render_view_host->GetWidget()); - content::RenderWidgetHostView* view = - render_view_host->GetWidget()->GetView(); - if (!view) - return; - - // Make sure screenshots aren't taken too frequently. - base::Time now = base::Time::Now(); - if (now - last_screenshot_time_ < - base::TimeDelta::FromMilliseconds(min_screenshot_interval_ms_)) { - return; - } - - WillTakeScreenshot(render_view_host); - - last_screenshot_time_ = now; - - // This screenshot is destined for the UI, so size the result to the actual - // on-screen size of the view (and not its device-rendering size). - const gfx::Size view_size_on_screen = view->GetViewBounds().size(); - view->CopyFromSurface( - gfx::Rect(), view_size_on_screen, - base::BindOnce(&NavigationEntryScreenshotManager::OnScreenshotTaken, - screenshot_factory_.GetWeakPtr(), entry->GetUniqueID())); -} - -// Implemented here and not in NavigationEntry because this manager keeps track -// of the total number of screen shots across all entries. -void NavigationEntryScreenshotManager::ClearAllScreenshots() { - int count = owner_->GetEntryCount(); - for (int i = 0; i < count; ++i) { - ClearScreenshot(owner_->GetEntryAtIndex(i)); - } - DCHECK_EQ(GetScreenshotCount(), 0); -} - -void NavigationEntryScreenshotManager::SetMinScreenshotIntervalMS( - int interval_ms) { - DCHECK_GE(interval_ms, 0); - min_screenshot_interval_ms_ = interval_ms; -} - -void NavigationEntryScreenshotManager::OnScreenshotTaken( - int unique_id, - const SkBitmap& bitmap) { - NavigationEntryImpl* entry = owner_->GetEntryWithUniqueID(unique_id); - if (!entry) { - LOG(ERROR) << "Invalid entry with unique id: " << unique_id; - return; - } - - if (bitmap.drawsNothing()) { - if (!ClearScreenshot(entry)) - OnScreenshotSet(entry); - return; - } - - scoped_refptr<ScreenshotData> screenshot = new ScreenshotData(); - screenshot->EncodeScreenshot( - bitmap, base::BindOnce( - &NavigationEntryScreenshotManager::OnScreenshotEncodeComplete, - screenshot_factory_.GetWeakPtr(), unique_id, screenshot)); -} - -int NavigationEntryScreenshotManager::GetScreenshotCount() const { - int screenshot_count = 0; - int entry_count = owner_->GetEntryCount(); - for (int i = 0; i < entry_count; ++i) { - NavigationEntryImpl* entry = owner_->GetEntryAtIndex(i); - if (entry->screenshot().get()) - screenshot_count++; - } - return screenshot_count; -} - -void NavigationEntryScreenshotManager::OnScreenshotEncodeComplete( - int unique_id, - scoped_refptr<ScreenshotData> screenshot) { - NavigationEntryImpl* entry = owner_->GetEntryWithUniqueID(unique_id); - if (!entry) - return; - scoped_refptr<base::RefCountedBytes> data = screenshot->data(); - if (!data) - return; - entry->SetScreenshotPNGData(std::move(data)); - OnScreenshotSet(entry); -} - -void NavigationEntryScreenshotManager::OnScreenshotSet( - NavigationEntryImpl* entry) { - if (entry->screenshot().get()) - PurgeScreenshotsIfNecessary(); -} - -bool NavigationEntryScreenshotManager::ClearScreenshot( - NavigationEntryImpl* entry) { - if (!entry->screenshot().get()) - return false; - - entry->SetScreenshotPNGData(nullptr); - return true; -} - -void NavigationEntryScreenshotManager::PurgeScreenshotsIfNecessary() { - // Allow only a certain number of entries to keep screenshots. - const int kMaxScreenshots = 10; - int screenshot_count = GetScreenshotCount(); - if (screenshot_count < kMaxScreenshots) - return; - - const int current = owner_->GetCurrentEntryIndex(); - const int num_entries = owner_->GetEntryCount(); - int available_slots = kMaxScreenshots; - if (owner_->GetEntryAtIndex(current)->screenshot().get()) { - --available_slots; - } - - // Keep screenshots closer to the current navigation entry, and purge the ones - // that are farther away from it. So in each step, look at the entries at - // each offset on both the back and forward history, and start counting them - // to make sure that the correct number of screenshots are kept in memory. - // Note that it is possible for some entries to be missing screenshots (e.g. - // when taking the screenshot failed for some reason). So there may be a state - // where there are a lot of entries in the back history, but none of them has - // any screenshot. In such cases, keep the screenshots for |kMaxScreenshots| - // entries in the forward history list. - int back = current - 1; - int forward = current + 1; - while (available_slots > 0 && (back >= 0 || forward < num_entries)) { - if (back >= 0) { - NavigationEntryImpl* entry = owner_->GetEntryAtIndex(back); - if (entry->screenshot().get()) - --available_slots; - --back; - } - - if (available_slots > 0 && forward < num_entries) { - NavigationEntryImpl* entry = owner_->GetEntryAtIndex(forward); - if (entry->screenshot().get()) - --available_slots; - ++forward; - } - } - - // Purge any screenshot at |back| or lower indices, and |forward| or higher - // indices. - while (screenshot_count > kMaxScreenshots && back >= 0) { - NavigationEntryImpl* entry = owner_->GetEntryAtIndex(back); - if (ClearScreenshot(entry)) - --screenshot_count; - --back; - } - - while (screenshot_count > kMaxScreenshots && forward < num_entries) { - NavigationEntryImpl* entry = owner_->GetEntryAtIndex(forward); - if (ClearScreenshot(entry)) - --screenshot_count; - ++forward; - } - CHECK_GE(screenshot_count, 0); - CHECK_LE(screenshot_count, kMaxScreenshots); -} - -} // namespace content
diff --git a/content/browser/frame_host/navigation_entry_screenshot_manager.h b/content/browser/frame_host/navigation_entry_screenshot_manager.h deleted file mode 100644 index dab9e99..0000000 --- a/content/browser/frame_host/navigation_entry_screenshot_manager.h +++ /dev/null
@@ -1,91 +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 CONTENT_BROWSER_FRAME_HOST_NAVIGATION_ENTRY_SCREENSHOT_MANAGER_H_ -#define CONTENT_BROWSER_FRAME_HOST_NAVIGATION_ENTRY_SCREENSHOT_MANAGER_H_ - -#include "base/compiler_specific.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/time/time.h" -#include "content/common/content_export.h" - -class SkBitmap; - -namespace content { - -class NavigationControllerImpl; -class NavigationEntryImpl; -class RenderViewHost; -class ScreenshotData; - -// NavigationEntryScreenshotManager takes care of taking image-captures for the -// current navigation entry of a NavigationControllerImpl, and managing these -// captured images. These image-captures are used for history navigation using -// overscroll gestures. -class CONTENT_EXPORT NavigationEntryScreenshotManager { - public: - explicit NavigationEntryScreenshotManager( - NavigationControllerImpl* controller); - virtual ~NavigationEntryScreenshotManager(); - - // Takes a screenshot of the last-committed entry of the controller. - void TakeScreenshot(); - - // Clears screenshots of all navigation entries. - void ClearAllScreenshots(); - - protected: - // Overridden by tests to be notified when a screenshot will be taken. Tests - // can override OnScreenshotSet() to be notified after the screenshot is - // taken. - virtual void WillTakeScreenshot(RenderViewHost* host) {} - - // Called after a screenshot has been set on an NavigationEntryImpl. - // Overridden in tests to get notified of when a screenshot is set. - virtual void OnScreenshotSet(NavigationEntryImpl* entry); - - NavigationControllerImpl* owner() { return owner_; } - - void SetMinScreenshotIntervalMS(int interval_ms); - - // The callback invoked when taking the screenshot of the page is complete. - // This sets the screenshot on the navigation entry. - void OnScreenshotTaken(int unique_id, const SkBitmap& bitmap); - - // Returns the number of entries with screenshots. - int GetScreenshotCount() const; - - private: - // This is called when the screenshot data has beene encoded to PNG in a - // worker thread. - void OnScreenshotEncodeComplete(int unique_id, - scoped_refptr<ScreenshotData> data); - - // Removes the screenshot for the entry, returning true if the entry had a - // screenshot. - bool ClearScreenshot(NavigationEntryImpl* entry); - - // The screenshots in the NavigationEntryImpls can accumulate and consume a - // large amount of memory. This function makes sure that the memory - // consumption is within a certain limit. - void PurgeScreenshotsIfNecessary(); - - // The navigation controller that owns this screenshot-manager. - NavigationControllerImpl* owner_; - - base::Time last_screenshot_time_; - int min_screenshot_interval_ms_; - - // Taking a screenshot and encoding them can be async. So use a weakptr for - // the callback to make sure that the screenshot/encoding completion callback - // does not trigger on a destroyed NavigationEntryScreenshotManager. - base::WeakPtrFactory<NavigationEntryScreenshotManager> screenshot_factory_; - - DISALLOW_COPY_AND_ASSIGN(NavigationEntryScreenshotManager); -}; - -} // namespace content - -#endif // CONTENT_BROWSER_FRAME_HOST_NAVIGATION_ENTRY_SCREENSHOT_MANAGER_H_
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index 69dacd0f..f4c38a2 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc
@@ -197,21 +197,6 @@ if (ui::PageTransitionIsMainFrame(params.transition)) { if (delegate_) { - // When overscroll navigation gesture is enabled, a screenshot of the page - // in its current state is taken so that it can be used during the - // nav-gesture. It is necessary to take the screenshot here, before - // calling RenderFrameHostManager::DidNavigateMainFrame, because that can - // change WebContents::GetRenderViewHost to return the new host, instead - // of the one that may have just been swapped out. - if (delegate_->CanOverscrollContent()) { - // Don't take screenshots if we are staying on the same document. We - // want same-document navigations to be super fast, and taking a - // screenshot currently blocks GPU for a longer time than we are willing - // to tolerate in this use case. - if (!was_within_same_document) - controller_->TakeScreenshot(); - } - // Run tasks that must execute just before the commit. delegate_->DidNavigateMainFramePreCommit(is_same_document_navigation); }
diff --git a/content/browser/network_service_client_unittest.cc b/content/browser/network_service_client_unittest.cc index de2c0047..5d6e02160 100644 --- a/content/browser/network_service_client_unittest.cc +++ b/content/browser/network_service_client_unittest.cc
@@ -13,7 +13,6 @@ #include "base/test/test_file_util.h" #include "build/build_config.h" #include "content/browser/child_process_security_policy_impl.h" -#include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" namespace content { @@ -77,7 +76,7 @@ } protected: - TestBrowserThreadBundle scoped_task_environment_; + base::test::ScopedTaskEnvironment scoped_task_environment_; network::mojom::NetworkServiceClientPtr client_ptr_; NetworkServiceClient client_; base::ScopedTempDir temp_dir_;
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 1499d28..cca56202 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -3083,7 +3083,6 @@ switches::kVModule, // Please keep these in alphabetical order. Compositor switches here should // also be added to chrome/browser/chromeos/login/chrome_restart_request.cc. - cc::switches::kAlwaysRequestPresentationTime, cc::switches::kCheckDamageEarly, cc::switches::kDisableCheckerImaging, cc::switches::kDisableCompositedAntialiasing,
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc index 7a77e94..6ebfa9c 100644 --- a/content/browser/renderer_host/render_widget_host_unittest.cc +++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -2076,7 +2076,6 @@ // Check that if messages of a frame arrive earlier than the frame itself, we // queue the messages until the frame arrives and then process them. TEST_F(RenderWidgetHostTest, FrameToken_MessageThenFrame) { - const uint32_t frame_token = 99; const viz::LocalSurfaceId local_surface_id(1, base::UnguessableToken::Create()); std::vector<IPC::Message> messages; @@ -2085,16 +2084,17 @@ EXPECT_EQ(0u, host_->frame_token_message_queue_->size()); EXPECT_EQ(0u, host_->processed_frame_messages_count()); + auto frame = viz::CompositorFrameBuilder() + .AddDefaultRenderPass() + .SetSendFrameTokenToEmbedder(true) + .Build(); + const uint32_t frame_token = frame.metadata.frame_token; + host_->OnMessageReceived( WidgetHostMsg_FrameSwapMessages(0, frame_token, messages)); EXPECT_EQ(1u, host_->frame_token_message_queue_->size()); EXPECT_EQ(0u, host_->processed_frame_messages_count()); - auto frame = viz::CompositorFrameBuilder() - .AddDefaultRenderPass() - .SetFrameToken(frame_token) - .SetSendFrameTokenToEmbedder(true) - .Build(); host_->SubmitCompositorFrame(local_surface_id, std::move(frame), base::nullopt, 0); EXPECT_EQ(0u, host_->frame_token_message_queue_->size()); @@ -2104,7 +2104,6 @@ // Check that if a frame arrives earlier than its messages, we process the // messages immedtiately. TEST_F(RenderWidgetHostTest, FrameToken_FrameThenMessage) { - const uint32_t frame_token = 99; const viz::LocalSurfaceId local_surface_id(1, base::UnguessableToken::Create()); std::vector<IPC::Message> messages; @@ -2115,9 +2114,9 @@ auto frame = viz::CompositorFrameBuilder() .AddDefaultRenderPass() - .SetFrameToken(frame_token) .SetSendFrameTokenToEmbedder(true) .Build(); + const uint32_t frame_token = frame.metadata.frame_token; host_->SubmitCompositorFrame(local_surface_id, std::move(frame), base::nullopt, 0); EXPECT_EQ(0u, host_->frame_token_message_queue_->size()); @@ -2132,8 +2131,6 @@ // Check that if messages of multiple frames arrive before the frames, we // process each message once it frame arrives. TEST_F(RenderWidgetHostTest, FrameToken_MultipleMessagesThenTokens) { - const uint32_t frame_token1 = 99; - const uint32_t frame_token2 = 100; const viz::LocalSurfaceId local_surface_id(1, base::UnguessableToken::Create()); std::vector<IPC::Message> messages1; @@ -2144,6 +2141,17 @@ EXPECT_EQ(0u, host_->frame_token_message_queue_->size()); EXPECT_EQ(0u, host_->processed_frame_messages_count()); + auto frame1 = viz::CompositorFrameBuilder() + .AddDefaultRenderPass() + .SetSendFrameTokenToEmbedder(true) + .Build(); + const uint32_t frame_token1 = frame1.metadata.frame_token; + auto frame2 = viz::CompositorFrameBuilder() + .AddDefaultRenderPass() + .SetSendFrameTokenToEmbedder(true) + .Build(); + const uint32_t frame_token2 = frame2.metadata.frame_token; + host_->OnMessageReceived( WidgetHostMsg_FrameSwapMessages(0, frame_token1, messages1)); EXPECT_EQ(1u, host_->frame_token_message_queue_->size()); @@ -2154,22 +2162,11 @@ EXPECT_EQ(2u, host_->frame_token_message_queue_->size()); EXPECT_EQ(0u, host_->processed_frame_messages_count()); - auto frame = viz::CompositorFrameBuilder() - .AddDefaultRenderPass() - .SetFrameToken(frame_token1) - .SetSendFrameTokenToEmbedder(true) - .Build(); - host_->SubmitCompositorFrame(local_surface_id, std::move(frame), + host_->SubmitCompositorFrame(local_surface_id, std::move(frame1), base::nullopt, 0); EXPECT_EQ(1u, host_->frame_token_message_queue_->size()); EXPECT_EQ(1u, host_->processed_frame_messages_count()); - - frame = viz::CompositorFrameBuilder() - .AddDefaultRenderPass() - .SetFrameToken(frame_token2) - .SetSendFrameTokenToEmbedder(true) - .Build(); - host_->SubmitCompositorFrame(local_surface_id, std::move(frame), + host_->SubmitCompositorFrame(local_surface_id, std::move(frame2), base::nullopt, 0); EXPECT_EQ(0u, host_->frame_token_message_queue_->size()); EXPECT_EQ(2u, host_->processed_frame_messages_count()); @@ -2178,8 +2175,6 @@ // Check that if multiple frames arrive before their messages, each message is // processed immediately as soon as it arrives. TEST_F(RenderWidgetHostTest, FrameToken_MultipleTokensThenMessages) { - const uint32_t frame_token1 = 99; - const uint32_t frame_token2 = 100; const viz::LocalSurfaceId local_surface_id(1, base::UnguessableToken::Create()); std::vector<IPC::Message> messages1; @@ -2192,9 +2187,9 @@ auto frame = viz::CompositorFrameBuilder() .AddDefaultRenderPass() - .SetFrameToken(frame_token1) .SetSendFrameTokenToEmbedder(true) .Build(); + const uint32_t frame_token1 = frame.metadata.frame_token; host_->SubmitCompositorFrame(local_surface_id, std::move(frame), base::nullopt, 0); EXPECT_EQ(0u, host_->frame_token_message_queue_->size()); @@ -2202,9 +2197,9 @@ frame = viz::CompositorFrameBuilder() .AddDefaultRenderPass() - .SetFrameToken(frame_token2) .SetSendFrameTokenToEmbedder(true) .Build(); + const uint32_t frame_token2 = frame.metadata.frame_token; host_->SubmitCompositorFrame(local_surface_id, std::move(frame), base::nullopt, 0); EXPECT_EQ(0u, host_->frame_token_message_queue_->size()); @@ -2224,8 +2219,7 @@ // Check that if one frame is lost but its messages arrive, we process the // messages on the arrival of the next frame. TEST_F(RenderWidgetHostTest, FrameToken_DroppedFrame) { - const uint32_t frame_token1 = 99; - const uint32_t frame_token2 = 100; + const uint32_t frame_token1 = 1; const viz::LocalSurfaceId local_surface_id(1, base::UnguessableToken::Create()); std::vector<IPC::Message> messages1; @@ -2241,16 +2235,16 @@ EXPECT_EQ(1u, host_->frame_token_message_queue_->size()); EXPECT_EQ(0u, host_->processed_frame_messages_count()); + auto frame = viz::CompositorFrameBuilder() + .AddDefaultRenderPass() + .SetSendFrameTokenToEmbedder(true) + .Build(); + const uint32_t frame_token2 = frame.metadata.frame_token; host_->OnMessageReceived( WidgetHostMsg_FrameSwapMessages(0, frame_token2, messages2)); EXPECT_EQ(2u, host_->frame_token_message_queue_->size()); EXPECT_EQ(0u, host_->processed_frame_messages_count()); - auto frame = viz::CompositorFrameBuilder() - .AddDefaultRenderPass() - .SetFrameToken(frame_token2) - .SetSendFrameTokenToEmbedder(true) - .Build(); host_->SubmitCompositorFrame(local_surface_id, std::move(frame), base::nullopt, 0); EXPECT_EQ(0u, host_->frame_token_message_queue_->size()); @@ -2260,9 +2254,6 @@ // Check that if the renderer crashes, we drop all queued messages and allow // smaller frame tokens to be sent by the renderer. TEST_F(RenderWidgetHostTest, FrameToken_RendererCrash) { - const uint32_t frame_token1 = 99; - const uint32_t frame_token2 = 50; - const uint32_t frame_token3 = 30; const viz::LocalSurfaceId local_surface_id(1, base::UnguessableToken::Create()); std::vector<IPC::Message> messages1; @@ -2282,6 +2273,11 @@ // then a crash occurs when we attempt to destroy it again in TearDown(). host_->SetView(nullptr); + auto frame = viz::CompositorFrameBuilder() + .AddDefaultRenderPass() + .SetSendFrameTokenToEmbedder(true) + .Build(); + const uint32_t frame_token1 = frame.metadata.frame_token; host_->OnMessageReceived( WidgetHostMsg_FrameSwapMessages(0, frame_token1, messages1)); EXPECT_EQ(1u, host_->frame_token_message_queue_->size()); @@ -2292,11 +2288,11 @@ EXPECT_EQ(0u, host_->processed_frame_messages_count()); host_->Init(); - auto frame = viz::CompositorFrameBuilder() - .AddDefaultRenderPass() - .SetFrameToken(frame_token2) - .SetSendFrameTokenToEmbedder(true) - .Build(); + frame = viz::CompositorFrameBuilder() + .AddDefaultRenderPass() + .SetSendFrameTokenToEmbedder(true) + .Build(); + const uint32_t frame_token2 = frame.metadata.frame_token; host_->SubmitCompositorFrame(local_surface_id, std::move(frame), base::nullopt, 0); EXPECT_EQ(0u, host_->frame_token_message_queue_->size()); @@ -2309,13 +2305,12 @@ host_->Init(); host_->OnMessageReceived( - WidgetHostMsg_FrameSwapMessages(0, frame_token3, messages3)); + WidgetHostMsg_FrameSwapMessages(0, frame_token2, messages3)); EXPECT_EQ(1u, host_->frame_token_message_queue_->size()); EXPECT_EQ(0u, host_->processed_frame_messages_count()); frame = viz::CompositorFrameBuilder() .AddDefaultRenderPass() - .SetFrameToken(frame_token3) .SetSendFrameTokenToEmbedder(true) .Build(); host_->SubmitCompositorFrame(local_surface_id, std::move(frame),
diff --git a/content/browser/service_manager/service_manager_context.cc b/content/browser/service_manager/service_manager_context.cc index 0f8d4ba4..5d5630c 100644 --- a/content/browser/service_manager/service_manager_context.cc +++ b/content/browser/service_manager/service_manager_context.cc
@@ -56,8 +56,6 @@ #include "mojo/public/cpp/system/invitation.h" #include "services/audio/public/mojom/constants.mojom.h" #include "services/audio/service_factory.h" -#include "services/catalog/public/cpp/manifest_parsing_util.h" -#include "services/catalog/public/mojom/constants.mojom.h" #include "services/data_decoder/public/mojom/constants.mojom.h" #include "services/device/device_service.h" #include "services/device/public/mojom/constants.mojom.h" @@ -73,7 +71,6 @@ #include "services/resource_coordinator/public/mojom/service_constants.mojom.h" #include "services/resource_coordinator/resource_coordinator_service.h" #include "services/service_manager/connect_params.h" -#include "services/service_manager/embedder/manifest_utils.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/constants.h" #include "services/service_manager/public/cpp/manifest.h" @@ -564,7 +561,6 @@ {mojom::kPluginServiceName, IDR_MOJO_CONTENT_PLUGIN_MANIFEST}, {mojom::kRendererServiceName, IDR_MOJO_CONTENT_RENDERER_MANIFEST}, {mojom::kUtilityServiceName, IDR_MOJO_CONTENT_UTILITY_MANIFEST}, - {catalog::mojom::kServiceName, IDR_MOJO_CATALOG_MANIFEST}, }; std::vector<service_manager::Manifest> manifests; for (const auto& manifest_info : kManifestInfo) {
diff --git a/content/content_resources.grd b/content/content_resources.grd index 6578475..44307b2 100644 --- a/content/content_resources.grd +++ b/content/content_resources.grd
@@ -26,7 +26,6 @@ <include name="IDR_INDEXED_DB_INTERNALS_CSS" file="browser/resources/indexed_db/indexeddb_internals.css" flattenhtml="true" compress="gzip" type="BINDATA" /> <include name="IDR_MEDIA_INTERNALS_HTML" file="browser/resources/media/media_internals.html" flattenhtml="true" allowexternalscript="true" compress="gzip" type="BINDATA" /> <include name="IDR_MEDIA_INTERNALS_JS" file="browser/resources/media/media_internals.js" flattenhtml="true" compress="gzip" type="BINDATA" /> - <include name="IDR_MOJO_CATALOG_MANIFEST" file="../services/catalog/manifest.json" type="BINDATA" /> <include name="IDR_MOJO_CONTENT_BROWSER_MANIFEST" file="${root_gen_dir}/content/public/app/browser_manifest.json" use_base_dir="false" type="BINDATA" /> <include name="IDR_MOJO_CONTENT_GPU_MANIFEST" file="${root_gen_dir}/content/public/app/gpu_manifest.json" use_base_dir="false" type="BINDATA" /> <include name="IDR_MOJO_CONTENT_PACKAGED_SERVICES_MANIFEST" file="${root_gen_dir}/content/public/app/packaged_services_manifest.json" use_base_dir="false" type="BINDATA" />
diff --git a/content/public/browser/navigation_controller.h b/content/public/browser/navigation_controller.h index f5bf19a..75bda56 100644 --- a/content/public/browser/navigation_controller.h +++ b/content/public/browser/navigation_controller.h
@@ -480,10 +480,6 @@ virtual void DeleteNavigationEntries( const DeletionPredicate& deletionPredicate) = 0; - // Clears all screenshots associated with navigation entries in this - // controller. Useful to reduce memory consumption in low-memory situations. - virtual void ClearAllScreenshots() = 0; - private: // This interface should only be implemented inside content. friend class NavigationControllerImpl;
diff --git a/content/renderer/compositor/layer_tree_view.cc b/content/renderer/compositor/layer_tree_view.cc index e2364d4..263bd26 100644 --- a/content/renderer/compositor/layer_tree_view.cc +++ b/content/renderer/compositor/layer_tree_view.cc
@@ -110,10 +110,8 @@ void ReportTimeSwapPromise::WillSwap(viz::CompositorFrameMetadata* metadata) { DCHECK_GT(metadata->frame_token, 0u); - // Request a presentation timestamp for this frame. The interval between the - // current swap and its presentation time is reported in UMA (see - // corresponding code in DidSwap() below). - metadata->request_presentation_feedback = true; + // The interval between the current swap and its presentation time is reported + // in UMA (see corresponding code in DidSwap() below). frame_token_ = metadata->frame_token; }
diff --git a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc index ba4ac31..15514e08 100644 --- a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc +++ b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.cc
@@ -138,6 +138,7 @@ void GpuVideoAcceleratorFactoriesImpl::OnSupportedDecoderConfigs( std::vector<media::mojom::SupportedVideoDecoderConfigPtr> supported_configs) { + base::AutoLock lock(supported_decoder_configs_lock_); supported_decoder_configs_ = std::move(supported_configs); video_decoder_.reset(); } @@ -191,6 +192,8 @@ bool GpuVideoAcceleratorFactoriesImpl::IsDecoderConfigSupported( const media::VideoDecoderConfig& config) { + base::AutoLock lock(supported_decoder_configs_lock_); + // If GetSupportedConfigs() has not completed (or was never started), report // that all configs are supported. Clients will find out that configs are not // supported when VideoDecoder::Initialize() fails.
diff --git a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h index 7190217..4239d7f 100644 --- a/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h +++ b/content/renderer/media/gpu/gpu_video_accelerator_factories_impl.h
@@ -16,6 +16,7 @@ #include "base/memory/weak_ptr.h" #include "base/optional.h" #include "base/single_thread_task_runner.h" +#include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" #include "base/unguessable_token.h" #include "content/child/thread_safe_sender.h" @@ -191,8 +192,9 @@ // SupportedDecoderConfigs state. mojo::InterfacePtr<media::mojom::VideoDecoder> video_decoder_; + base::Lock supported_decoder_configs_lock_; base::Optional<std::vector<media::mojom::SupportedVideoDecoderConfigPtr>> - supported_decoder_configs_; + supported_decoder_configs_ GUARDED_BY(supported_decoder_configs_lock_); // For sending requests to allocate shared memory in the Browser process. scoped_refptr<ThreadSafeSender> thread_safe_sender_;
diff --git a/content/renderer/media/stream/apply_constraints_processor.cc b/content/renderer/media/stream/apply_constraints_processor.cc index 53694fc9..a69f106 100644 --- a/content/renderer/media/stream/apply_constraints_processor.cc +++ b/content/renderer/media/stream/apply_constraints_processor.cc
@@ -110,13 +110,8 @@ const MediaStreamDevice& device_info = video_source_->device(); if (device_info.type == MEDIA_DEVICE_VIDEO_CAPTURE) { ProcessVideoDeviceRequest(); - } else if (video_source_->GetCurrentFormat()) { - // Non-device capture just requires adjusting track settings. - FinalizeVideoRequest(); } else { - // It is impossible to enforce minimum constraints for sources that do not - // provide the video format, so reject applyConstraints() in this case. - CannotApplyConstraints("applyConstraints not supported for this track"); + FinalizeVideoRequest(); } } @@ -222,9 +217,14 @@ if (AbortIfVideoRequestStateInvalid()) return; - DCHECK(video_source_->GetCurrentFormat()); - VideoCaptureSettings settings = - SelectVideoSettings({*video_source_->GetCurrentFormat()}); + media::VideoCaptureFormat format; + if (video_source_->GetCurrentFormat()) { + format = *video_source_->GetCurrentFormat(); + } else { + format = GetCurrentVideoTrack()->GetComputedSourceFormat(); + } + VideoCaptureSettings settings = SelectVideoSettings({format}); + if (settings.HasValue()) { video_source_->ReconfigureTrack(GetCurrentVideoTrack(), settings.track_adapter_settings()); @@ -254,7 +254,6 @@ : media::MEDIA_VIDEO_FACING_NONE; device_capabilities->formats = std::move(formats); - DCHECK(video_source_->GetCurrentCaptureParams()); VideoDeviceCaptureCapabilities video_capabilities; video_capabilities.noise_reduction_capabilities.push_back( GetCurrentVideoTrack()->noise_reduction());
diff --git a/content/renderer/media/stream/media_stream_types.h b/content/renderer/media/stream/media_stream_types.h index beab906..fd6d60cd 100644 --- a/content/renderer/media/stream/media_stream_types.h +++ b/content/renderer/media/stream/media_stream_types.h
@@ -5,10 +5,15 @@ #ifndef CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_TYPES_H_ #define CONTENT_RENDERER_MEDIA_STREAM_MEDIA_STREAM_TYPES_H_ +#include "media/capture/video_capture_types.h" + namespace content { using VideoTrackSettingsCallback = - base::RepeatingCallback<void(int width, int height, double frame_rate)>; + base::RepeatingCallback<void(gfx::Size frame_size, double frame_rate)>; + +using VideoTrackFormatCallback = + base::RepeatingCallback<void(const media::VideoCaptureFormat&)>; } // namespace content
diff --git a/content/renderer/media/stream/media_stream_video_source.cc b/content/renderer/media/stream/media_stream_video_source.cc index d4e3b1f..a42d09d 100644 --- a/content/renderer/media/stream/media_stream_video_source.cc +++ b/content/renderer/media/stream/media_stream_video_source.cc
@@ -49,6 +49,7 @@ const VideoTrackAdapterSettings& track_adapter_settings, const VideoCaptureDeliverFrameCB& frame_callback, const VideoTrackSettingsCallback& settings_callback, + const VideoTrackFormatCallback& format_callback, const ConstraintsCallback& callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(!base::ContainsValue(tracks_, track)); @@ -56,7 +57,7 @@ secure_tracker_.Add(track, true); pending_tracks_.push_back(PendingTrackInfo( - track, frame_callback, settings_callback, + track, frame_callback, settings_callback, format_callback, std::make_unique<VideoTrackAdapterSettings>(track_adapter_settings), callback)); @@ -368,6 +369,7 @@ if (result == MEDIA_DEVICE_OK) { track_adapter_->AddTrack(track_info.track, track_info.frame_callback, track_info.settings_callback, + track_info.format_callback, *track_info.adapter_settings); UpdateTrackSettings(track_info.track, *track_info.adapter_settings); } @@ -434,11 +436,13 @@ MediaStreamVideoTrack* track, const VideoCaptureDeliverFrameCB& frame_callback, const VideoTrackSettingsCallback& settings_callback, + const VideoTrackFormatCallback& format_callback, std::unique_ptr<VideoTrackAdapterSettings> adapter_settings, const ConstraintsCallback& callback) : track(track), frame_callback(frame_callback), settings_callback(settings_callback), + format_callback(format_callback), adapter_settings(std::move(adapter_settings)), callback(callback) {}
diff --git a/content/renderer/media/stream/media_stream_video_source.h b/content/renderer/media/stream/media_stream_video_source.h index 2c130f3b..dca07686 100644 --- a/content/renderer/media/stream/media_stream_video_source.h +++ b/content/renderer/media/stream/media_stream_video_source.h
@@ -70,6 +70,7 @@ const VideoTrackAdapterSettings& track_adapter_settings, const VideoCaptureDeliverFrameCB& frame_callback, const VideoTrackSettingsCallback& settings_callback, + const VideoTrackFormatCallback& format_callback, const ConstraintsCallback& callback); void RemoveTrack(MediaStreamVideoTrack* track, base::OnceClosure callback); @@ -272,6 +273,7 @@ MediaStreamVideoTrack* track, const VideoCaptureDeliverFrameCB& frame_callback, const VideoTrackSettingsCallback& settings_callback, + const VideoTrackFormatCallback& format_callback, std::unique_ptr<VideoTrackAdapterSettings> adapter_settings, const ConstraintsCallback& callback); PendingTrackInfo(PendingTrackInfo&& other); @@ -281,6 +283,7 @@ MediaStreamVideoTrack* track; VideoCaptureDeliverFrameCB frame_callback; VideoTrackSettingsCallback settings_callback; + VideoTrackFormatCallback format_callback; // TODO(guidou): Make |adapter_settings| a regular field instead of a // unique_ptr. std::unique_ptr<VideoTrackAdapterSettings> adapter_settings;
diff --git a/content/renderer/media/stream/media_stream_video_track.cc b/content/renderer/media/stream/media_stream_video_track.cc index 094eccf..73969fd2 100644 --- a/content/renderer/media/stream/media_stream_video_track.cc +++ b/content/renderer/media/stream/media_stream_video_track.cc
@@ -270,6 +270,9 @@ media::BindToCurrentLoop(base::BindRepeating( &MediaStreamVideoTrack::SetSizeAndComputedFrameRate, weak_factory_.GetWeakPtr())), + media::BindToCurrentLoop(base::BindRepeating( + &MediaStreamVideoTrack::set_computed_source_format, + weak_factory_.GetWeakPtr())), callback); } @@ -299,6 +302,9 @@ media::BindToCurrentLoop(base::BindRepeating( &MediaStreamVideoTrack::SetSizeAndComputedFrameRate, weak_factory_.GetWeakPtr())), + media::BindToCurrentLoop(base::BindRepeating( + &MediaStreamVideoTrack::set_computed_source_format, + weak_factory_.GetWeakPtr())), callback); } @@ -430,4 +436,9 @@ adapter_settings_ = std::make_unique<VideoTrackAdapterSettings>(settings); } +media::VideoCaptureFormat MediaStreamVideoTrack::GetComputedSourceFormat() { + DCHECK_CALLED_ON_VALID_THREAD(main_render_thread_checker_); + return computed_source_format_; +} + } // namespace content
diff --git a/content/renderer/media/stream/media_stream_video_track.h b/content/renderer/media/stream/media_stream_video_track.h index 6e0d9993..97530ee8 100644 --- a/content/renderer/media/stream/media_stream_video_track.h +++ b/content/renderer/media/stream/media_stream_video_track.h
@@ -110,14 +110,24 @@ // Setting information about the track size. // Passed as callback on MediaStreamVideoTrack::AddTrack, and run from // VideoFrameResolutionAdapter on frame delivery to update track settings. - void SetSizeAndComputedFrameRate(int width, int height, double frame_rate) { - width_ = width; - height_ = height; + void SetSizeAndComputedFrameRate(gfx::Size frame_size, double frame_rate) { + width_ = frame_size.width(); + height_ = frame_size.height(); computed_frame_rate_ = frame_rate; } + // Setting information about the source format. The format is computed based + // on incoming frames and it's used for applying constraints for remote video + // tracks. Passed as callback on MediaStreamVideoTrack::AddTrack, and run from + // VideoFrameResolutionAdapter on frame delivery. + void set_computed_source_format(const media::VideoCaptureFormat& format) { + computed_source_format_ = format; + } + void SetTrackAdapterSettings(const VideoTrackAdapterSettings& settings); + media::VideoCaptureFormat GetComputedSourceFormat(); + MediaStreamVideoSource* source() const { return source_.get(); } private: @@ -166,6 +176,7 @@ int height_ = 0; double frame_rate_ = 0.0; base::Optional<double> computed_frame_rate_; + media::VideoCaptureFormat computed_source_format_; base::WeakPtrFactory<MediaStreamVideoTrack> weak_factory_;
diff --git a/content/renderer/media/stream/video_track_adapter.cc b/content/renderer/media/stream/video_track_adapter.cc index 02a07e91..196117f 100644 --- a/content/renderer/media/stream/video_track_adapter.cc +++ b/content/renderer/media/stream/video_track_adapter.cc
@@ -47,6 +47,15 @@ const double kFrameRateChangeRate = 0.01; const double kFrameRateUpdateIntervalInSeconds = 5; +struct ComputedSettings { + gfx::Size frame_size; + double frame_rate = MediaStreamVideoSource::kDefaultFrameRate; + double last_updated_frame_rate = MediaStreamVideoSource::kDefaultFrameRate; + base::TimeDelta prev_frame_timestamp = base::TimeDelta::Max(); + base::TimeTicks new_frame_rate_timestamp; + base::TimeTicks last_update_timestamp; +}; + // Empty method used for keeping a reference to the original media::VideoFrame // in VideoFrameResolutionAdapter::DeliverFrame if cropping is needed. // The reference to |frame| is kept in the closure that calls this method. @@ -57,6 +66,53 @@ std::max(0, dimension)); } +void ComputeFrameRate(const base::TimeDelta& frame_timestamp, + double* frame_rate, + base::TimeDelta* prev_frame_timestamp) { + const double delta_ms = + (frame_timestamp - *prev_frame_timestamp).InMillisecondsF(); + *prev_frame_timestamp = frame_timestamp; + if (delta_ms < 0) + return; + + *frame_rate = 200 / delta_ms + 0.8 * *frame_rate; +} + +// Controls the frequency of settings updates based on frame rate changes. +// Returns |true| if over the last second the computed frame rate is +// consistently kFrameRateChangeRate different than the last reported value, +// or if there hasn't been any update in the last +// kFrameRateUpdateIntervalInSeconds seconds. +bool MaybeUpdateFrameRate(ComputedSettings* settings) { + base::TimeTicks now = base::TimeTicks::Now(); + + // Update frame rate if over the last second the computed frame rate has been + // consistently kFrameRateChangeIntervalInSeconds different than the last + // reported value. + if (std::abs(settings->frame_rate - settings->last_updated_frame_rate) > + settings->last_updated_frame_rate * kFrameRateChangeRate) { + if ((now - settings->new_frame_rate_timestamp).InSecondsF() > + kFrameRateChangeIntervalInSeconds) { + settings->new_frame_rate_timestamp = now; + settings->last_update_timestamp = now; + settings->last_updated_frame_rate = settings->frame_rate; + return true; + } + } else { + settings->new_frame_rate_timestamp = now; + } + + // Update frame rate if it hasn't been updated in the last + // kFrameRateUpdateIntervalInSeconds seconds. + if ((now - settings->last_update_timestamp).InSecondsF() > + kFrameRateUpdateIntervalInSeconds) { + settings->last_update_timestamp = now; + settings->last_updated_frame_rate = settings->frame_rate; + return true; + } + return false; +} + } // anonymous namespace // VideoFrameResolutionAdapter is created on and lives on the IO-thread. It does @@ -68,6 +124,7 @@ struct VideoTrackCallbacks { VideoCaptureDeliverFrameCB frame_callback; VideoTrackSettingsCallback settings_callback; + VideoTrackFormatCallback format_callback; }; // Setting |max_frame_rate| to 0.0, means that no frame rate limitation // will be done. @@ -80,7 +137,8 @@ // |frame_callback| will however be released on the main render thread. void AddCallbacks(const MediaStreamVideoTrack* track, VideoCaptureDeliverFrameCB frame_callback, - VideoTrackSettingsCallback settings_callback); + VideoTrackSettingsCallback settings_callback, + VideoTrackFormatCallback format_callback); // Removes the callbacks associated with |track| if |track| has been added. It // is ok to call RemoveCallbacks() even if |track| has not been added. @@ -122,14 +180,9 @@ const VideoTrackSettingsCallback& settings_callback, const scoped_refptr<media::VideoFrame>& frame); - void ComputeFrameRate(const base::TimeDelta& frame_timestamp); - - // Controls the frequency of track settings updates based on frame rate - // changes. Returns |true| if over the last second the computed frame rate - // is consistently kFrameRateChangeRate different than the last reported - // value, or if there hasn't been any update in the last - // kFrameRateUpdateIntervalInSeconds seconds. - bool MaybeUpdateFrameRate(); + // Updates computed source format for all tracks if either frame width, height + // or frame rate have changed since last update. + void MaybeUpdateTracksFormat(const scoped_refptr<media::VideoFrame>& frame); // Bound to the IO-thread. THREAD_CHECKER(io_thread_checker_); @@ -143,12 +196,8 @@ base::TimeDelta last_time_stamp_; double keep_frame_counter_; - gfx::Size frame_size_; - double computed_frame_rate_; - double last_updated_frame_rate_; - base::TimeDelta prev_frame_timestamp_; - base::TimeTicks new_frame_rate_timestamp_; - base::TimeTicks last_update_timestamp_; + ComputedSettings track_settings_; + ComputedSettings source_format_settings_; base::flat_map<const MediaStreamVideoTrack*, VideoTrackCallbacks> callbacks_; @@ -162,10 +211,7 @@ settings_(settings), frame_rate_(MediaStreamVideoSource::kDefaultFrameRate), last_time_stamp_(base::TimeDelta::Max()), - keep_frame_counter_(0.0), - computed_frame_rate_(MediaStreamVideoSource::kDefaultFrameRate), - last_updated_frame_rate_(MediaStreamVideoSource::kDefaultFrameRate), - prev_frame_timestamp_(base::TimeDelta::Max()) { + keep_frame_counter_(0.0) { DCHECK(renderer_task_runner_.get()); DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); CHECK_NE(0, settings_.max_aspect_ratio()); @@ -194,10 +240,12 @@ void VideoTrackAdapter::VideoFrameResolutionAdapter::AddCallbacks( const MediaStreamVideoTrack* track, VideoCaptureDeliverFrameCB frame_callback, - VideoTrackSettingsCallback settings_callback) { + VideoTrackSettingsCallback settings_callback, + VideoTrackFormatCallback format_callback) { DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); - callbacks_.insert( - {track, {std::move(frame_callback), std::move(settings_callback)}}); + callbacks_.insert({track, + {std::move(frame_callback), std::move(settings_callback), + std::move(format_callback)}}); } void VideoTrackAdapter::VideoFrameResolutionAdapter::RemoveCallbacks( @@ -231,6 +279,10 @@ return; } + ComputeFrameRate(frame->timestamp(), &source_format_settings_.frame_rate, + &source_format_settings_.prev_frame_timestamp); + MaybeUpdateTracksFormat(frame); + double frame_rate; if (!frame->metadata()->GetDouble(media::VideoFrameMetadata::FRAME_RATE, &frame_rate)) { @@ -359,62 +411,33 @@ const VideoTrackSettingsCallback& settings_callback, const scoped_refptr<media::VideoFrame>& frame) { DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); - ComputeFrameRate(frame->timestamp()); - if (MaybeUpdateFrameRate() || frame->natural_size() != frame_size_) { - frame_size_ = frame->natural_size(); - settings_callback.Run(frame_size_.width(), frame_size_.height(), - computed_frame_rate_); + ComputeFrameRate(frame->timestamp(), &track_settings_.frame_rate, + &track_settings_.prev_frame_timestamp); + if (MaybeUpdateFrameRate(&track_settings_) || + frame->natural_size() != track_settings_.frame_size) { + track_settings_.frame_size = frame->natural_size(); + settings_callback.Run(track_settings_.frame_size, + track_settings_.frame_rate); } } - -void VideoTrackAdapter::VideoFrameResolutionAdapter::ComputeFrameRate( - const base::TimeDelta& frame_timestamp) { +void VideoTrackAdapter::VideoFrameResolutionAdapter::MaybeUpdateTracksFormat( + const scoped_refptr<media::VideoFrame>& frame) { DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); - const double delta_ms = - (frame_timestamp - prev_frame_timestamp_).InMillisecondsF(); - prev_frame_timestamp_ = frame_timestamp; - if (delta_ms < 0) - return; - - computed_frame_rate_ = 200 / delta_ms + 0.8 * computed_frame_rate_; -} - -bool VideoTrackAdapter::VideoFrameResolutionAdapter::MaybeUpdateFrameRate() { - DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); - base::TimeTicks now = base::TimeTicks::Now(); - - // Update frame rate if over the last second the computed frame rate has been - // consistently kFrameRateChangeIntervalInSeconds different than the last - // reported value. - if (std::abs(computed_frame_rate_ - last_updated_frame_rate_) > - last_updated_frame_rate_ * kFrameRateChangeRate) { - if ((now - new_frame_rate_timestamp_).InSecondsF() > - kFrameRateChangeIntervalInSeconds) { - new_frame_rate_timestamp_ = now; - last_update_timestamp_ = now; - last_updated_frame_rate_ = computed_frame_rate_; - return true; - } - } else { - new_frame_rate_timestamp_ = now; + if (MaybeUpdateFrameRate(&source_format_settings_) || + frame->natural_size() != track_settings_.frame_size) { + source_format_settings_.frame_size = frame->natural_size(); + media::VideoCaptureFormat source_format; + source_format.frame_size = source_format_settings_.frame_size; + source_format.frame_rate = source_format_settings_.frame_rate; + for (const auto& callback : callbacks_) + callback.second.format_callback.Run(source_format); } - - // Update frame rate if it hasn't been updated in the last - // kFrameRateUpdateIntervalInSeconds seconds. - if ((now - last_update_timestamp_).InSecondsF() > - kFrameRateUpdateIntervalInSeconds) { - last_update_timestamp_ = now; - last_updated_frame_rate_ = computed_frame_rate_; - return true; - } - return false; } void VideoTrackAdapter::VideoFrameResolutionAdapter::ResetFrameRate() { DCHECK_CALLED_ON_VALID_THREAD(io_thread_checker_); for (const auto& callback : callbacks_) { - callback.second.settings_callback.Run(frame_size_.width(), - frame_size_.height(), 0.0); + callback.second.settings_callback.Run(track_settings_.frame_size, 0.0); } } @@ -479,19 +502,22 @@ void VideoTrackAdapter::AddTrack(const MediaStreamVideoTrack* track, VideoCaptureDeliverFrameCB frame_callback, VideoTrackSettingsCallback settings_callback, + VideoTrackFormatCallback format_callback, const VideoTrackAdapterSettings& settings) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); io_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&VideoTrackAdapter::AddTrackOnIO, this, track, - std::move(frame_callback), - std::move(settings_callback), settings)); + FROM_HERE, + base::BindOnce(&VideoTrackAdapter::AddTrackOnIO, this, track, + std::move(frame_callback), std::move(settings_callback), + std::move(format_callback), settings)); } void VideoTrackAdapter::AddTrackOnIO( const MediaStreamVideoTrack* track, VideoCaptureDeliverFrameCB frame_callback, VideoTrackSettingsCallback settings_callback, + VideoTrackFormatCallback format_callback, const VideoTrackAdapterSettings& settings) { DCHECK(io_task_runner_->BelongsToCurrentThread()); scoped_refptr<VideoFrameResolutionAdapter> adapter; @@ -507,7 +533,8 @@ } adapter->AddCallbacks(track, std::move(frame_callback), - std::move(settings_callback)); + std::move(settings_callback), + std::move(format_callback)); } void VideoTrackAdapter::RemoveTrack(const MediaStreamVideoTrack* track) { @@ -680,7 +707,8 @@ // If the track was found, re-add it with new settings. if (!track_callbacks.frame_callback.is_null()) AddTrackOnIO(track, std::move(track_callbacks.frame_callback), - std::move(track_callbacks.settings_callback), settings); + std::move(track_callbacks.settings_callback), + std::move(track_callbacks.format_callback), settings); } void VideoTrackAdapter::DeliverFrameOnIO(
diff --git a/content/renderer/media/stream/video_track_adapter.h b/content/renderer/media/stream/video_track_adapter.h index 8bc2ee20..e2922996 100644 --- a/content/renderer/media/stream/video_track_adapter.h +++ b/content/renderer/media/stream/video_track_adapter.h
@@ -93,6 +93,7 @@ void AddTrack(const MediaStreamVideoTrack* track, VideoCaptureDeliverFrameCB frame_callback, VideoTrackSettingsCallback settings_callback, + VideoTrackFormatCallback track_callback, const VideoTrackAdapterSettings& settings); void RemoveTrack(const MediaStreamVideoTrack* track); void ReconfigureTrack(const MediaStreamVideoTrack* track, @@ -134,6 +135,7 @@ void AddTrackOnIO(const MediaStreamVideoTrack* track, VideoCaptureDeliverFrameCB frame_callback, VideoTrackSettingsCallback settings_callback, + VideoTrackFormatCallback track_callback, const VideoTrackAdapterSettings& settings); void RemoveTrackOnIO(const MediaStreamVideoTrack* track); void ReconfigureTrackOnIO(const MediaStreamVideoTrack* track,
diff --git a/content/renderer/media/webrtc/rtc_video_decoder_adapter.cc b/content/renderer/media/webrtc/rtc_video_decoder_adapter.cc index cf9da60..d92d292c 100644 --- a/content/renderer/media/webrtc/rtc_video_decoder_adapter.cc +++ b/content/renderer/media/webrtc/rtc_video_decoder_adapter.cc
@@ -24,6 +24,7 @@ #include "media/base/media_log.h" #include "media/base/media_util.h" #include "media/base/overlay_info.h" +#include "media/base/video_decoder_config.h" #include "media/base/video_types.h" #include "media/video/gpu_video_accelerator_factories.h" #include "third_party/webrtc/api/video/video_frame.h" @@ -140,15 +141,25 @@ } #endif // defined(OS_WIN) - // Short circuit known-unsupported codecs. + // Bail early for unknown codecs. if (ToVideoCodec(video_codec_type) == media::kUnknownVideoCodec) return nullptr; - std::unique_ptr<RTCVideoDecoderAdapter> rtc_video_decoder_adapter = - base::WrapUnique(new RTCVideoDecoderAdapter(gpu_factories, format)); + // Avoid the thread hop if the decoder is known not to support the config. + // TODO(sandersd): Predict size from level. + media::VideoDecoderConfig config( + ToVideoCodec(webrtc::PayloadStringToCodecType(format.name)), + GuessVideoCodecProfile(format), kDefaultPixelFormat, + media::VideoColorSpace(), media::VIDEO_ROTATION_0, kDefaultSize, + gfx::Rect(kDefaultSize), kDefaultSize, media::EmptyExtraData(), + media::Unencrypted()); + if (!gpu_factories->IsDecoderConfigSupported(config)) + return nullptr; // Synchronously verify that the decoder can be initialized. - if (!rtc_video_decoder_adapter->InitializeSync()) { + std::unique_ptr<RTCVideoDecoderAdapter> rtc_video_decoder_adapter = + base::WrapUnique(new RTCVideoDecoderAdapter(gpu_factories, format)); + if (!rtc_video_decoder_adapter->InitializeSync(config)) { gpu_factories->GetTaskRunner()->DeleteSoon( FROM_HERE, std::move(rtc_video_decoder_adapter)); return nullptr; @@ -174,7 +185,8 @@ DCHECK(media_task_runner_->BelongsToCurrentThread()); } -bool RTCVideoDecoderAdapter::InitializeSync() { +bool RTCVideoDecoderAdapter::InitializeSync( + const media::VideoDecoderConfig& config) { DVLOG(3) << __func__; DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_); @@ -186,7 +198,8 @@ if (media_task_runner_->PostTask( FROM_HERE, base::BindOnce(&RTCVideoDecoderAdapter::InitializeOnMediaThread, - base::Unretained(this), std::move(init_cb)))) { + base::Unretained(this), base::ConstRef(config), + base::ConstRef(init_cb)))) { waiter.Wait(); } return result; @@ -290,7 +303,8 @@ } void RTCVideoDecoderAdapter::InitializeOnMediaThread( - media::VideoDecoder::InitCB init_cb) { + const media::VideoDecoderConfig& config, + const media::VideoDecoder::InitCB& init_cb) { DVLOG(3) << __func__; DCHECK(media_task_runner_->BelongsToCurrentThread()); @@ -307,14 +321,6 @@ return; } - // We don't know much about the media that is coming. - media::VideoDecoderConfig config( - ToVideoCodec(webrtc::PayloadStringToCodecType(format_.name)), - GuessVideoCodecProfile(format_), kDefaultPixelFormat, - media::VideoColorSpace(), media::VIDEO_ROTATION_0, kDefaultSize, - gfx::Rect(kDefaultSize), kDefaultSize, media::EmptyExtraData(), - media::Unencrypted()); - // In practice this is ignored by hardware decoders. bool low_delay = true; @@ -324,8 +330,8 @@ media::VideoDecoder::OutputCB output_cb = base::BindRepeating(&RTCVideoDecoderAdapter::OnOutput, weak_this_); - video_decoder_->Initialize(config, low_delay, cdm_context, std::move(init_cb), - std::move(output_cb), base::DoNothing()); + video_decoder_->Initialize(config, low_delay, cdm_context, init_cb, output_cb, + base::DoNothing()); } void RTCVideoDecoderAdapter::DecodeOnMediaThread() {
diff --git a/content/renderer/media/webrtc/rtc_video_decoder_adapter.h b/content/renderer/media/webrtc/rtc_video_decoder_adapter.h index ef54cca1..22a1933a 100644 --- a/content/renderer/media/webrtc/rtc_video_decoder_adapter.h +++ b/content/renderer/media/webrtc/rtc_video_decoder_adapter.h
@@ -30,6 +30,7 @@ class DecoderBuffer; class GpuVideoAcceleratorFactories; class MediaLog; +class VideoDecoderConfig; class VideoFrame; } // namespace media @@ -85,8 +86,9 @@ RTCVideoDecoderAdapter(media::GpuVideoAcceleratorFactories* gpu_factories, const webrtc::SdpVideoFormat& format); - bool InitializeSync(); - void InitializeOnMediaThread(media::VideoDecoder::InitCB init_cb); + bool InitializeSync(const media::VideoDecoderConfig& config); + void InitializeOnMediaThread(const media::VideoDecoderConfig& config, + const media::VideoDecoder::InitCB& init_cb); void DecodeOnMediaThread(); void OnDecodeDone(media::DecodeStatus status); void OnOutput(const scoped_refptr<media::VideoFrame>& frame);
diff --git a/content/renderer/media/webrtc/rtc_video_decoder_adapter_unittest.cc b/content/renderer/media/webrtc/rtc_video_decoder_adapter_unittest.cc index e3959c3..b0c26eb 100644 --- a/content/renderer/media/webrtc/rtc_video_decoder_adapter_unittest.cc +++ b/content/renderer/media/webrtc/rtc_video_decoder_adapter_unittest.cc
@@ -100,6 +100,10 @@ .WillByDefault(Return(media_thread_.task_runner())); EXPECT_CALL(gpu_factories_, GetTaskRunner()).Times(AtLeast(0)); + ON_CALL(gpu_factories_, IsDecoderConfigSupported(_)) + .WillByDefault(Return(true)); + EXPECT_CALL(gpu_factories_, IsDecoderConfigSupported(_)).Times(AtLeast(0)); + ON_CALL(gpu_factories_, CreateVideoDecoder(_, _, _)) .WillByDefault( [this](media::MediaLog* media_log, @@ -199,9 +203,10 @@ base::RepeatingCallback<void(const webrtc::VideoFrame&)>>> decoded_cb_; - private: StrictMock<media::MockGpuVideoAcceleratorFactories> gpu_factories_; std::unique_ptr<RTCVideoDecoderAdapter> rtc_video_decoder_adapter_; + + private: std::unique_ptr<StrictMock<MockVideoDecoder>> owned_video_decoder_; DecodedImageCallback decoded_image_callback_; media::VideoDecoder::OutputCB output_cb_; @@ -209,6 +214,22 @@ DISALLOW_COPY_AND_ASSIGN(RTCVideoDecoderAdapterTest); }; +TEST_F(RTCVideoDecoderAdapterTest, Create_UnknownFormat) { + rtc_video_decoder_adapter_ = RTCVideoDecoderAdapter::Create( + &gpu_factories_, webrtc::SdpVideoFormat(webrtc::CodecTypeToPayloadString( + webrtc::kVideoCodecGeneric))); + ASSERT_FALSE(rtc_video_decoder_adapter_); +} + +TEST_F(RTCVideoDecoderAdapterTest, Create_UnsupportedFormat) { + EXPECT_CALL(gpu_factories_, IsDecoderConfigSupported(_)) + .WillOnce(Return(false)); + rtc_video_decoder_adapter_ = RTCVideoDecoderAdapter::Create( + &gpu_factories_, webrtc::SdpVideoFormat(webrtc::CodecTypeToPayloadString( + webrtc::kVideoCodecVP9))); + ASSERT_FALSE(rtc_video_decoder_adapter_); +} + TEST_F(RTCVideoDecoderAdapterTest, Lifecycle) { ASSERT_TRUE(BasicSetup()); ASSERT_TRUE(BasicTeardown());
diff --git a/content/renderer/media/webrtc/rtc_video_decoder_factory.cc b/content/renderer/media/webrtc/rtc_video_decoder_factory.cc index e4d58d40..db9e4a4 100644 --- a/content/renderer/media/webrtc/rtc_video_decoder_factory.cc +++ b/content/renderer/media/webrtc/rtc_video_decoder_factory.cc
@@ -157,6 +157,11 @@ media::GpuVideoAcceleratorFactories* gpu_factories) : gpu_factories_(gpu_factories) { DVLOG(2) << __func__; + + // RTCVideoDecoderAdapter does not use |supported_formats_|. + if (base::FeatureList::IsEnabled(media::kRTCVideoDecoderAdapter)) + return; + const media::VideoDecodeAccelerator::SupportedProfiles profiles = gpu_factories_->GetVideoDecodeAcceleratorCapabilities() .supported_profiles; @@ -170,6 +175,7 @@ std::vector<webrtc::SdpVideoFormat> RTCVideoDecoderFactory::GetSupportedFormats() const { + DCHECK(!base::FeatureList::IsEnabled(media::kRTCVideoDecoderAdapter)); return supported_formats_; }
diff --git a/content/renderer/media/webrtc/video_codec_factory.cc b/content/renderer/media/webrtc/video_codec_factory.cc index 89446fe6..9be9ec9 100644 --- a/content/renderer/media/webrtc/video_codec_factory.cc +++ b/content/renderer/media/webrtc/video_codec_factory.cc
@@ -6,11 +6,13 @@ #include "base/base_switches.h" #include "base/command_line.h" +#include "base/feature_list.h" #include "base/memory/ptr_util.h" #include "build/build_config.h" #include "content/public/common/content_switches.h" #include "content/renderer/media/webrtc/rtc_video_decoder_factory.h" #include "content/renderer/media/webrtc/rtc_video_encoder_factory.h" +#include "media/base/media_switches.h" #include "third_party/webrtc/api/video_codecs/video_decoder_software_fallback_wrapper.h" #include "third_party/webrtc/api/video_codecs/video_encoder_software_fallback_wrapper.h" #include "third_party/webrtc/media/base/codec.h" @@ -61,6 +63,11 @@ std::unique_ptr<webrtc::VideoDecoder> CreateDecoder( webrtc::VideoDecoderFactory* factory, const webrtc::SdpVideoFormat& format) { + if (base::FeatureList::IsEnabled(media::kRTCVideoDecoderAdapter)) + return factory ? factory->CreateVideoDecoder(format) : nullptr; + + // TODO(sandersd): Remove calls to GetSupportedFormats() once the + // RTCVideoDecoder path is gone. return IsFormatSupported(factory, format) ? factory->CreateVideoDecoder(format) : nullptr;
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 1dedf10..934203f 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -6706,15 +6706,7 @@ bool RenderFrameImpl::CreatePlaceholderDocumentLoader( const blink::WebNavigationInfo& info) { - auto navigation_params = blink::WebNavigationParams::CreateFromInfo(info); - // We need the provider to be non-null, otherwise Blink crashes, even though - // the provider should not be used for any actual networking. - navigation_params->service_worker_network_provider = - BuildServiceWorkerNetworkProviderForNavigation( - nullptr /* request_params */, - nullptr /* controller_service_worker_info */); - return frame_->CreatePlaceholderDocumentLoader( - std::move(navigation_params), info.navigation_type, BuildDocumentState()); + return frame_->CreatePlaceholderDocumentLoader(info, BuildDocumentState()); } void RenderFrameImpl::BeginNavigationInternal(
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 35051fe0..99357db 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -2890,9 +2890,6 @@ settings.enable_image_animation_resync = !cmd.HasSwitch(switches::kDisableImageAnimationResync); - settings.always_request_presentation_time = - cmd.HasSwitch(cc::switches::kAlwaysRequestPresentationTime); - settings.send_compositor_frame_ack = false; return settings;
diff --git a/content/test/data/accessibility/aria/aria-col-attr-expected-blink.txt b/content/test/data/accessibility/aria/aria-col-attr-expected-blink.txt index b25eb1e6..40dc2f72 100644 --- a/content/test/data/accessibility/aria/aria-col-attr-expected-blink.txt +++ b/content/test/data/accessibility/aria/aria-col-attr-expected-blink.txt
@@ -10,7 +10,7 @@ ++++++columnHeader name='cell 5' ariaCellColumnIndex=5 selected=false ++++++++staticText name='cell 5' ++++++++++inlineTextBox name='cell 5' -++++row selected=false +++++row ariaCellColumnIndex=2 selected=false ++++++cell name='cell 2' ariaCellColumnIndex=2 selected=false ++++++++staticText name='cell 2' ++++++++++inlineTextBox name='cell 2'
diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn index 73f1cd7..697d74c 100644 --- a/gpu/command_buffer/service/BUILD.gn +++ b/gpu/command_buffer/service/BUILD.gn
@@ -4,8 +4,8 @@ import("//build/config/jumbo.gni") import("//build/config/ui.gni") -import("//third_party/protobuf/proto_library.gni") import("//gpu/vulkan/features.gni") +import("//third_party/protobuf/proto_library.gni") group("service") { if (is_component_build) { @@ -258,15 +258,6 @@ "wrapped_sk_image.h", ] - if (is_android) { - sources += [ - "ahardwarebuffer_utils.cc", - "ahardwarebuffer_utils.h", - "shared_image_backing_factory_ahardwarebuffer.cc", - "shared_image_backing_factory_ahardwarebuffer.h", - ] - } - configs += [ "//build/config:precompiled_headers", "//gpu:gpu_gles2_implementation", @@ -322,10 +313,31 @@ ] } - if (is_android && !is_debug) { - # On Android optimize more since this component can be a bottleneck. - configs -= [ "//build/config/compiler:default_optimization" ] - configs += [ "//build/config/compiler:optimize_max" ] + if (is_android) { + if (!is_debug) { + # On Android optimize more since this component can be a bottleneck. + configs -= [ "//build/config/compiler:default_optimization" ] + configs += [ "//build/config/compiler:optimize_max" ] + } + sources += [ + "ahardwarebuffer_utils.cc", + "ahardwarebuffer_utils.h", + "shared_image_backing_factory_ahardwarebuffer.cc", + "shared_image_backing_factory_ahardwarebuffer.h", + ] + + # TODO(cblume): http://crbug.com/911313 + # Abstract out the platform specific defines. Right now we need the android + # platform specific define here to be able to include android specific + # functions. + defines = [ "VK_USE_PLATFORM_ANDROID_KHR" ] + deps += [ "//third_party/libsync" ] + if (enable_vulkan) { + deps += [ + "//gpu/ipc/common:android_image_reader_utils", + "//gpu/vulkan:vulkan", + ] + } } }
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc index 93fdae99..cb4b858 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc
@@ -4,9 +4,12 @@ #include "gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.h" +#include <sync/sync.h> + #include "base/android/android_hardware_buffer_compat.h" #include "base/android/scoped_hardware_buffer_handle.h" #include "base/logging.h" +#include "components/viz/common/gpu/vulkan_context_provider.h" #include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/resource_sizes.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" @@ -15,20 +18,86 @@ #include "gpu/command_buffer/service/gles2_cmd_decoder.h" #include "gpu/command_buffer/service/mailbox_manager.h" #include "gpu/command_buffer/service/memory_tracking.h" +#include "gpu/command_buffer/service/raster_decoder_context_state.h" #include "gpu/command_buffer/service/shared_image_backing.h" #include "gpu/command_buffer/service/shared_image_representation.h" #include "gpu/command_buffer/service/skia_utils.h" #include "gpu/command_buffer/service/texture_manager.h" +#include "gpu/ipc/common/android/android_image_reader_utils.h" +#include "gpu/vulkan/vulkan_device_queue.h" +#include "gpu/vulkan/vulkan_function_pointers.h" +#include "gpu/vulkan/vulkan_implementation.h" +#include "third_party/skia/include/gpu/GrBackendSemaphore.h" #include "third_party/skia/include/gpu/GrBackendSurface.h" #include "ui/gfx/color_space.h" #include "ui/gfx/geometry/size.h" #include "ui/gl/gl_context.h" +#include "ui/gl/gl_fence_android_native_fence_sync.h" #include "ui/gl/gl_gl_api_implementation.h" #include "ui/gl/gl_image_ahardwarebuffer.h" #include "ui/gl/gl_version_info.h" namespace gpu { +// Implementation of SharedImageBacking that holds an AHardwareBuffer. This +// can be used to create a GL texture or a VK Image from the AHardwareBuffer +// backing. +class SharedImageBackingAHB : public SharedImageBacking { + public: + SharedImageBackingAHB(const Mailbox& mailbox, + viz::ResourceFormat format, + const gfx::Size& size, + const gfx::ColorSpace& color_space, + uint32_t usage, + base::android::ScopedHardwareBufferHandle handle, + size_t estimated_size, + raster::RasterDecoderContextState* context_state); + + ~SharedImageBackingAHB() override; + + bool IsCleared() const override; + void SetCleared() override; + void Update() override; + bool ProduceLegacyMailbox(MailboxManager* mailbox_manager) override; + void Destroy() override; + raster::RasterDecoderContextState* GetContextState() const; + base::ScopedFD TakeGLWriteSyncFd(); + base::ScopedFD TakeVkReadSyncFd(); + base::android::ScopedHardwareBufferHandle GetAhbHandle(); + void SetGLWriteSyncFd(base::ScopedFD fd); + void SetVkReadSyncFd(base::ScopedFD fd); + + protected: + std::unique_ptr<SharedImageRepresentationGLTexture> ProduceGLTexture( + SharedImageManager* manager, + MemoryTypeTracker* tracker) override; + + std::unique_ptr<SharedImageRepresentationSkia> ProduceSkia( + SharedImageManager* manager, + MemoryTypeTracker* tracker) override; + + private: + bool GenGLTexture(); + base::android::ScopedHardwareBufferHandle hardware_buffer_handle_; + + // This texture will be lazily initialised/created when ProduceGLTexture is + // called. + gles2::Texture* texture_ = nullptr; + + // TODO(vikassoni): In future when we add begin/end write support, we will + // need to properly use this flag to pass the is_cleared_ information to + // the GL texture representation while begin write and back to this class from + // the GL texture represntation after end write. This is because this class + // will not know if SetCleared() arrives during begin write happening on GL + // texture representation. + bool is_cleared_ = false; + raster::RasterDecoderContextState* context_state_ = nullptr; + base::ScopedFD gl_write_sync_fd_; + base::ScopedFD vk_read_sync_fd_; + + DISALLOW_COPY_AND_ASSIGN(SharedImageBackingAHB); +}; + // Representation of a SharedImageBackingAHB as a GL Texture. class SharedImageRepresentationGLTextureAHB : public SharedImageRepresentationGLTexture { @@ -42,15 +111,52 @@ gles2::Texture* GetTexture() override { return texture_; } + bool BeginAccess(GLenum mode) override { + // TODO(vikassoni): Currently Skia Vk backing never does a write. So GL read + // do not need to wait for the Vk write to finish. Eventually when Vk starts + // writing, we will need to TakeVkWriteSyncFd() and wait on it for mode = + // GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM. + + // Wait on Vk read if GL is going to write. + // TODO(vikassoni): GL writes should wait on both Vk read and Vk writes. + if (mode == GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM) { + base::ScopedFD sync_fd = ahb_backing()->TakeVkReadSyncFd(); + + // Create an egl fence sync and do a server side wait. + if (!InsertEglFenceAndWait(std::move(sync_fd))) + return false; + } + mode_ = mode; + return true; + } + + void EndAccess() override { + // TODO(vikassoni): Currently Skia Vk backing never does a write. So Vk + // writes do not need to wait on GL to finish the read. Eventually when Vk + // starts writing, we will need to create and set a GLReadSyncFd for mode = + // GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM for Vk to wait on it. + if (mode_ == GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM) { + base::ScopedFD sync_fd = CreateEglFenceAndExportFd(); + if (!sync_fd.is_valid()) + return; + + // Pass this fd to its backing. + ahb_backing()->SetGLWriteSyncFd(std::move(sync_fd)); + } + } + private: + SharedImageBackingAHB* ahb_backing() { + return static_cast<SharedImageBackingAHB*>(backing()); + } + gles2::Texture* texture_; + GLenum mode_ = GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM; DISALLOW_COPY_AND_ASSIGN(SharedImageRepresentationGLTextureAHB); }; // GL backed Skia representation of SharedImageBackingAHB. -// TODO(vikassoni): Add follow up patch to add a vulkan backed skia -// representation. class SharedImageRepresentationSkiaGLAHB : public SharedImageRepresentationSkia { public: @@ -69,9 +175,19 @@ GrContext* gr_context, int final_msaa_count, const SkSurfaceProps& surface_props) override { + // if there is already a write_surface_, it means previous BeginWriteAccess + // doesn't have a corresponding EndWriteAccess. if (write_surface_) return nullptr; + // Synchronise this access with the Vk reads. + // TODO(vikassoni): SkiaGL writes should wait on both Vk read and Vk writes. + base::ScopedFD sync_fd = ahb_backing()->TakeVkReadSyncFd(); + + // Create an egl fence sync and do a server side wait. + if (!InsertEglFenceAndWait(std::move(sync_fd))) + return nullptr; + GrBackendTexture backend_texture; if (!GetGrBackendTexture(gl::GLContext::GetCurrent()->GetVersionInfo(), target_, size(), service_id_, format(), @@ -93,9 +209,22 @@ DCHECK(surface->unique()); // TODO(ericrk): Keep the surface around for re-use. write_surface_ = nullptr; + + // Insert a gl fence to signal the write completion. Vulkan representation + // needs to wait on this signal before it can read from this. + base::ScopedFD sync_fd = CreateEglFenceAndExportFd(); + if (!sync_fd.is_valid()) + return; + + // Pass this fd to its backing. + ahb_backing()->SetGLWriteSyncFd(std::move(sync_fd)); } - bool BeginReadAccess(GrBackendTexture* backend_texture) override { + bool BeginReadAccess(SkSurface* sk_surface, + GrBackendTexture* backend_texture) override { + // TODO(vikassoni): Currently Skia Vk backing never does a write. So this + // read do not need to wait for the Vk write to finish. Eventually when Vk + // starts writing, we might need to TakeVkWriteSyncFd() and wait on it. if (!GetGrBackendTexture(gl::GLContext::GetCurrent()->GetVersionInfo(), target_, size(), service_id_, format(), backend_texture)) { @@ -105,193 +234,376 @@ } void EndReadAccess() override { + // TODO(vikassoni): Currently Skia Vk backing never does a write. So Vk + // writes do not need to wait on this read to finish. Eventually when Vk + // starts writing, we will need to create and set a SkiaGLReadSyncFd. // TODO(ericrk): Handle begin/end correctness checks. } private: + SharedImageBackingAHB* ahb_backing() { + return static_cast<SharedImageBackingAHB*>(backing()); + } + GLenum target_; GLuint service_id_; - SkSurface* write_surface_ = nullptr; }; -// Implementation of SharedImageBacking that holds an AHardwareBuffer. This -// can be used to create a GL texture or a VK Image from the AHardwareBuffer -// backing. -class SharedImageBackingAHB : public SharedImageBacking { +// Vk backed Skia representation of SharedImageBackingAHB. +class SharedImageRepresentationSkiaVkAHB + : public SharedImageRepresentationSkia { public: - SharedImageBackingAHB(const Mailbox& mailbox, - viz::ResourceFormat format, - const gfx::Size& size, - const gfx::ColorSpace& color_space, - uint32_t usage, - base::android::ScopedHardwareBufferHandle handle, - size_t estimated_size) - : SharedImageBacking(mailbox, - format, - size, - color_space, - usage, - estimated_size), - hardware_buffer_handle_(std::move(handle)) { - DCHECK(hardware_buffer_handle_.is_valid()); + SharedImageRepresentationSkiaVkAHB(SharedImageManager* manager, + SharedImageBacking* backing) + : SharedImageRepresentationSkia(manager, backing, nullptr) { + SharedImageBackingAHB* ahb_backing = + static_cast<SharedImageBackingAHB*>(backing); + DCHECK(ahb_backing); + raster::RasterDecoderContextState* context_state = + ahb_backing->GetContextState(); + DCHECK(context_state); + DCHECK(context_state->vk_context_provider); + + vk_device_ = + context_state->vk_context_provider->GetDeviceQueue()->GetVulkanDevice(); + vk_phy_device_ = context_state->vk_context_provider->GetDeviceQueue() + ->GetVulkanPhysicalDevice(); + vk_implementation_ = + context_state->vk_context_provider->GetVulkanImplementation(); } - ~SharedImageBackingAHB() override { - // Check to make sure buffer is explicitly destroyed using Destroy() api - // before this destructor is called. - DCHECK(!hardware_buffer_handle_.is_valid()); - DCHECK(!texture_); + ~SharedImageRepresentationSkiaVkAHB() override { DCHECK(!read_surface_); } + + sk_sp<SkSurface> BeginWriteAccess( + GrContext* gr_context, + int final_msaa_count, + const SkSurfaceProps& surface_props) override { + NOTIMPLEMENTED(); + return nullptr; } - bool IsCleared() const override { - if (texture_) - return texture_->IsLevelCleared(texture_->target(), 0); - return is_cleared_; - } + void EndWriteAccess(sk_sp<SkSurface> surface) override { NOTIMPLEMENTED(); } - void SetCleared() override { - if (texture_) - texture_->SetLevelCleared(texture_->target(), 0, true); - is_cleared_ = true; - } - - void Update() override {} - - bool ProduceLegacyMailbox(MailboxManager* mailbox_manager) override { - DCHECK(hardware_buffer_handle_.is_valid()); - if (!GenGLTexture()) + bool BeginReadAccess(SkSurface* sk_surface, + GrBackendTexture* backend_texture) override { + // If previous read access has not ended. + if (read_surface_) return false; - DCHECK(texture_); - mailbox_manager->ProduceTexture(mailbox(), texture_); + DCHECK(sk_surface); + DCHECK(backend_texture); + + // Synchronise the read access with the GL writes. + base::ScopedFD sync_fd = ahb_backing()->TakeGLWriteSyncFd(); + + // We need to wait only if there is a valid fd. + if (sync_fd.is_valid()) { + // Do a client side wait for now. + // TODO(vikassoni): There seems to be a skia bug - + // https://bugs.chromium.org/p/chromium/issues/detail?id=916812 currently + // where wait() on the sk surface crashes. Remove the sync_wait() and + // apply CL mentioned in the bug when the issue is fixed. + static const int InfiniteSyncWaitTimeout = -1; + if (sync_wait(sync_fd.get(), InfiniteSyncWaitTimeout) < 0) { + LOG(ERROR) << "Failed while waiting on GL Write sync fd"; + return false; + } + } + + // Create a VkImage and import AHB. + VkImage vk_image; + VkImageCreateInfo vk_image_info; + VkDeviceMemory vk_device_memory; + VkDeviceSize mem_allocation_size; + if (!vk_implementation_->CreateVkImageAndImportAHB( + vk_device_, vk_phy_device_, size(), ahb_backing()->GetAhbHandle(), + &vk_image, &vk_image_info, &vk_device_memory, + &mem_allocation_size)) { + return false; + } + + // Create backend texture from the VkImage. + GrVkAlloc alloc = {vk_device_memory, 0, mem_allocation_size, 0}; + GrVkImageInfo vk_info = {vk_image, + alloc, + vk_image_info.tiling, + vk_image_info.initialLayout, + vk_image_info.format, + vk_image_info.mipLevels}; + *backend_texture = + GrBackendTexture(size().width(), size().height(), vk_info); + if (!backend_texture->isValid()) { + vkDestroyImage(vk_device_, vk_image, nullptr); + vkFreeMemory(vk_device_, vk_device_memory, nullptr); + return false; + } + + // Cache the sk surface in the representation so that it can be used in the + // EndReadAccess. Also make sure previous read_surface_ have been consumed + // by EndReadAccess() call. + read_surface_ = sk_surface; return true; } - void Destroy() override { - DCHECK(hardware_buffer_handle_.is_valid()); - if (texture_) { - texture_->RemoveLightweightRef(have_context()); - texture_ = nullptr; + void EndReadAccess() override { + // There should be a read_surface_ from the BeginReadAccess(). + DCHECK(read_surface_); + + // Create a vk semaphore which can be exported. + VkExportSemaphoreCreateInfo export_info; + export_info.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO; + export_info.pNext = nullptr; + export_info.handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT; + + VkSemaphore vk_semaphore; + VkSemaphoreCreateInfo sem_info; + sem_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + sem_info.pNext = &export_info; + sem_info.flags = 0; + bool result = + vkCreateSemaphore(vk_device_, &sem_info, nullptr, &vk_semaphore); + if (result != VK_SUCCESS) { + // TODO(vikassoni): add more error handling rather than just return ? + LOG(ERROR) << "vkCreateSemaphore failed"; + read_surface_ = nullptr; + return; } - hardware_buffer_handle_.reset(); - } + GrBackendSemaphore gr_semaphore; + gr_semaphore.initVulkan(vk_semaphore); - protected: - std::unique_ptr<SharedImageRepresentationGLTexture> ProduceGLTexture( - SharedImageManager* manager, - MemoryTypeTracker* tracker) override { - // Use same texture for all the texture representations generated from same - // backing. - if (!GenGLTexture()) - return nullptr; + // If GrSemaphoresSubmitted::kNo is returned, the GPU back-end did not + // create or add any semaphores to signal on the GPU; the caller should not + // instruct the GPU to wait on any of the semaphores. + if (read_surface_->flushAndSignalSemaphores(1, &gr_semaphore) == + GrSemaphoresSubmitted::kNo) { + vkDestroySemaphore(vk_device_, vk_semaphore, nullptr); + read_surface_ = nullptr; + return; + } + read_surface_ = nullptr; - DCHECK(texture_); - return std::make_unique<SharedImageRepresentationGLTextureAHB>( - manager, this, tracker, texture_); - } + // All the pending SkSurface commands to the GPU-backed API are issued and + // any SkSurface MSAA are resolved. After issuing all commands, + // signalSemaphores of count numSemaphores semaphores are signaled by the + // GPU. The caller must delete the semaphores created. + // Export a sync fd from the semaphore. + base::ScopedFD sync_fd; + vk_implementation_->GetSemaphoreFdKHR(vk_device_, vk_semaphore, &sync_fd); - std::unique_ptr<SharedImageRepresentationSkia> ProduceSkia( - SharedImageManager* manager, - MemoryTypeTracker* tracker) override { - // TODO(vikassoni): Currently we only have a GL backed skia representation. - // Follow up patch will add support to check whether we are in Vulkan mode - // OR GL mode and accordingly create Skia representation. - if (!GenGLTexture()) - return nullptr; + // pass this sync fd to the backing. + ahb_backing()->SetVkReadSyncFd(std::move(sync_fd)); - DCHECK(texture_); - return std::make_unique<SharedImageRepresentationSkiaGLAHB>( - manager, this, tracker, texture_->target(), texture_->service_id()); + // TODO(vikassoni): We need to wait for the queue submission to complete + // before we can destroy the semaphore. This will decrease the performance. + // Add a future patch to handle this in more efficient way. Keep semaphores + // in a STL queue instead of destroying it. Later use a fence to check if + // the batch that refers the semaphore has completed execution. Delete the + // semaphore once the fence is signalled. + vkDeviceWaitIdle(vk_device_); + vkDestroySemaphore(vk_device_, vk_semaphore, nullptr); } private: - bool GenGLTexture() { - if (texture_) - return true; - - DCHECK(hardware_buffer_handle_.is_valid()); - - // Target for AHB backed egl images. - // Note that we are not using GL_TEXTURE_EXTERNAL_OES target since sksurface - // doesnt supports it. As per the egl documentation - - // https://www.khronos.org/registry/OpenGL/extensions/OES/OES_EGL_image_external.txt - // if GL_OES_EGL_image is supported then <target> may also be TEXTURE_2D. - GLenum target = GL_TEXTURE_2D; - GLenum get_target = GL_TEXTURE_BINDING_2D; - - // Create a gles2 texture using the AhardwareBuffer. - gl::GLApi* api = gl::g_current_gl_context; - GLuint service_id = 0; - api->glGenTexturesFn(1, &service_id); - GLint old_texture_binding = 0; - api->glGetIntegervFn(get_target, &old_texture_binding); - api->glBindTextureFn(target, service_id); - api->glTexParameteriFn(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - api->glTexParameteriFn(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - api->glTexParameteriFn(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - api->glTexParameteriFn(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - // Create an egl image using AHardwareBuffer. - auto egl_image = base::MakeRefCounted<gl::GLImageAHardwareBuffer>(size()); - if (!egl_image->Initialize(hardware_buffer_handle_.get(), false)) { - LOG(ERROR) << "Failed to create EGL image "; - api->glBindTextureFn(target, old_texture_binding); - api->glDeleteTexturesFn(1, &service_id); - return false; - } - if (!egl_image->BindTexImage(target)) { - LOG(ERROR) << "Failed to bind egl image"; - api->glBindTextureFn(target, old_texture_binding); - api->glDeleteTexturesFn(1, &service_id); - return false; - } - - // Create a gles2 Texture. - texture_ = new gles2::Texture(service_id); - texture_->SetLightweightRef(); - texture_->SetTarget(target, 1); - texture_->sampler_state_.min_filter = GL_LINEAR; - texture_->sampler_state_.mag_filter = GL_LINEAR; - texture_->sampler_state_.wrap_t = GL_CLAMP_TO_EDGE; - texture_->sampler_state_.wrap_s = GL_CLAMP_TO_EDGE; - - // If the backing is already cleared, no need to clear it again. - gfx::Rect cleared_rect; - if (is_cleared_) - cleared_rect = gfx::Rect(size()); - - GLenum gl_format = viz::GLDataFormat(format()); - GLenum gl_type = viz::GLDataType(format()); - texture_->SetLevelInfo(target, 0, egl_image->GetInternalFormat(), - size().width(), size().height(), 1, 0, gl_format, - gl_type, cleared_rect); - texture_->SetLevelImage(target, 0, egl_image.get(), gles2::Texture::BOUND); - texture_->SetImmutable(true); - api->glBindTextureFn(target, old_texture_binding); - DCHECK_EQ(egl_image->GetInternalFormat(), gl_format); - return true; + SharedImageBackingAHB* ahb_backing() { + return static_cast<SharedImageBackingAHB*>(backing()); } - base::android::ScopedHardwareBufferHandle hardware_buffer_handle_; - - // This texture will be lazily initialised/created when ProduceGLTexture is - // called. - gles2::Texture* texture_ = nullptr; - - // TODO(vikassoni): In future when we add begin/end write support, we will - // need to properly use this flag to pass the is_cleared_ information to - // the GL texture representation while begin write and back to this class from - // the GL texture represntation after end write. This is because this class - // will not know if SetCleared() arrives during begin write happening on GL - // texture representation. - bool is_cleared_ = false; - - DISALLOW_COPY_AND_ASSIGN(SharedImageBackingAHB); + SkSurface* read_surface_ = nullptr; + gpu::VulkanImplementation* vk_implementation_ = nullptr; + VkDevice vk_device_ = VK_NULL_HANDLE; + VkPhysicalDevice vk_phy_device_ = VK_NULL_HANDLE; }; +SharedImageBackingAHB::SharedImageBackingAHB( + const Mailbox& mailbox, + viz::ResourceFormat format, + const gfx::Size& size, + const gfx::ColorSpace& color_space, + uint32_t usage, + base::android::ScopedHardwareBufferHandle handle, + size_t estimated_size, + raster::RasterDecoderContextState* context_state) + : SharedImageBacking(mailbox, + format, + size, + color_space, + usage, + estimated_size), + hardware_buffer_handle_(std::move(handle)), + context_state_(context_state) { + DCHECK(hardware_buffer_handle_.is_valid()); +} + +SharedImageBackingAHB::~SharedImageBackingAHB() { + // Check to make sure buffer is explicitly destroyed using Destroy() api + // before this destructor is called. + DCHECK(!hardware_buffer_handle_.is_valid()); + DCHECK(!texture_); +} + +bool SharedImageBackingAHB::IsCleared() const { + if (texture_) + return texture_->IsLevelCleared(texture_->target(), 0); + return is_cleared_; +} + +void SharedImageBackingAHB::SetCleared() { + if (texture_) + texture_->SetLevelCleared(texture_->target(), 0, true); + is_cleared_ = true; +} + +void SharedImageBackingAHB::Update() {} + +bool SharedImageBackingAHB::ProduceLegacyMailbox( + MailboxManager* mailbox_manager) { + DCHECK(hardware_buffer_handle_.is_valid()); + if (!GenGLTexture()) + return false; + DCHECK(texture_); + mailbox_manager->ProduceTexture(mailbox(), texture_); + return true; +} + +void SharedImageBackingAHB::Destroy() { + DCHECK(hardware_buffer_handle_.is_valid()); + if (texture_) { + texture_->RemoveLightweightRef(have_context()); + texture_ = nullptr; + } + hardware_buffer_handle_.reset(); +} + +raster::RasterDecoderContextState* SharedImageBackingAHB::GetContextState() + const { + return context_state_; +} + +base::ScopedFD SharedImageBackingAHB::TakeGLWriteSyncFd() { + return std::move(gl_write_sync_fd_); +} + +void SharedImageBackingAHB::SetGLWriteSyncFd(base::ScopedFD fd) { + gl_write_sync_fd_ = std::move(fd); +} + +base::ScopedFD SharedImageBackingAHB::TakeVkReadSyncFd() { + return std::move(vk_read_sync_fd_); +} + +void SharedImageBackingAHB::SetVkReadSyncFd(base::ScopedFD fd) { + vk_read_sync_fd_ = std::move(fd); +} + +base::android::ScopedHardwareBufferHandle +SharedImageBackingAHB::GetAhbHandle() { + return hardware_buffer_handle_.Clone(); +} + +std::unique_ptr<SharedImageRepresentationGLTexture> +SharedImageBackingAHB::ProduceGLTexture(SharedImageManager* manager, + MemoryTypeTracker* tracker) { + // Use same texture for all the texture representations generated from same + // backing. + if (!GenGLTexture()) + return nullptr; + + DCHECK(texture_); + return std::make_unique<SharedImageRepresentationGLTextureAHB>( + manager, this, tracker, texture_); +} + +std::unique_ptr<SharedImageRepresentationSkia> +SharedImageBackingAHB::ProduceSkia(SharedImageManager* manager, + MemoryTypeTracker* tracker) { + DCHECK(context_state_); + + // Check whether we are in Vulkan mode OR GL mode and accordingly create + // Skia representation. + if (context_state_->use_vulkan_gr_context) { + return std::make_unique<SharedImageRepresentationSkiaVkAHB>(manager, this); + } + + if (!GenGLTexture()) + return nullptr; + + DCHECK(texture_); + return std::make_unique<SharedImageRepresentationSkiaGLAHB>( + manager, this, tracker, texture_->target(), texture_->service_id()); +} + +bool SharedImageBackingAHB::GenGLTexture() { + if (texture_) + return true; + + DCHECK(hardware_buffer_handle_.is_valid()); + + // Target for AHB backed egl images. + // Note that we are not using GL_TEXTURE_EXTERNAL_OES target since sksurface + // doesn't supports it. As per the egl documentation - + // https://www.khronos.org/registry/OpenGL/extensions/OES/OES_EGL_image_external.txt + // if GL_OES_EGL_image is supported then <target> may also be TEXTURE_2D. + GLenum target = GL_TEXTURE_2D; + GLenum get_target = GL_TEXTURE_BINDING_2D; + + // Create a gles2 texture using the AhardwareBuffer. + gl::GLApi* api = gl::g_current_gl_context; + GLuint service_id = 0; + api->glGenTexturesFn(1, &service_id); + GLint old_texture_binding = 0; + api->glGetIntegervFn(get_target, &old_texture_binding); + api->glBindTextureFn(target, service_id); + api->glTexParameteriFn(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + api->glTexParameteriFn(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + api->glTexParameteriFn(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + api->glTexParameteriFn(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + // Create an egl image using AHardwareBuffer. + auto egl_image = base::MakeRefCounted<gl::GLImageAHardwareBuffer>(size()); + if (!egl_image->Initialize(hardware_buffer_handle_.get(), false)) { + LOG(ERROR) << "Failed to create EGL image "; + api->glBindTextureFn(target, old_texture_binding); + api->glDeleteTexturesFn(1, &service_id); + return false; + } + if (!egl_image->BindTexImage(target)) { + LOG(ERROR) << "Failed to bind egl image"; + api->glBindTextureFn(target, old_texture_binding); + api->glDeleteTexturesFn(1, &service_id); + return false; + } + + // Create a gles2 Texture. + texture_ = new gles2::Texture(service_id); + texture_->SetLightweightRef(); + texture_->SetTarget(target, 1); + texture_->sampler_state_.min_filter = GL_LINEAR; + texture_->sampler_state_.mag_filter = GL_LINEAR; + texture_->sampler_state_.wrap_t = GL_CLAMP_TO_EDGE; + texture_->sampler_state_.wrap_s = GL_CLAMP_TO_EDGE; + + // If the backing is already cleared, no need to clear it again. + gfx::Rect cleared_rect; + if (is_cleared_) + cleared_rect = gfx::Rect(size()); + + GLenum gl_format = viz::GLDataFormat(format()); + GLenum gl_type = viz::GLDataType(format()); + texture_->SetLevelInfo(target, 0, egl_image->GetInternalFormat(), + size().width(), size().height(), 1, 0, gl_format, + gl_type, cleared_rect); + texture_->SetLevelImage(target, 0, egl_image.get(), gles2::Texture::BOUND); + texture_->SetImmutable(true); + api->glBindTextureFn(target, old_texture_binding); + DCHECK_EQ(egl_image->GetInternalFormat(), gl_format); + return true; +} + SharedImageBackingFactoryAHB::SharedImageBackingFactoryAHB( const GpuDriverBugWorkarounds& workarounds, - const GpuFeatureInfo& gpu_feature_info) { + const GpuFeatureInfo& gpu_feature_info, + raster::RasterDecoderContextState* context_state) + : context_state_(context_state) { scoped_refptr<gles2::FeatureInfo> feature_info = new gles2::FeatureInfo(workarounds, gpu_feature_info); feature_info->Initialize(ContextType::CONTEXT_TYPE_OPENGLES2, false, @@ -314,7 +626,8 @@ info.ahb_format = AHardwareBufferFormat(format); // TODO(vikassoni): In future when we use GL_TEXTURE_EXTERNAL_OES target - // with AHB, we need to check if oes_egl_image_external is supported or not. + // with AHB, we need to check if oes_egl_image_external is supported or + // not. if (!is_egl_image_supported) continue; @@ -325,11 +638,8 @@ GLenum gl_format = viz::GLDataFormat(format); GLenum gl_type = viz::GLDataType(format); - // GLImageAHardwareBuffer currently supports internal format GL_RGBA only. - // TODO(vikassoni): Pass the AHBuffer format while GLImageAHardwareBuffer - // creation and based on that return the equivalent internal format as - // GL_RGBA or GL_RGB. - if (internal_format != GL_RGBA) + // GLImageAHardwareBuffer supports internal format GL_RGBA and GL_RGB. + if (internal_format != GL_RGBA && internal_format != GL_RGB) continue; // Validate if GL format, type and internal format is supported. @@ -344,12 +654,13 @@ } // TODO(vikassoni): We are using below GL api calls for now as Vulkan mode // doesn't exist. Once we have vulkan support, we shouldn't query GL in this - // code until we are asked to make a GL representation (or allocate a backing - // for import into GL)? We may use an AHardwareBuffer exclusively with Vulkan, - // where there is no need to require that a GL context is current. Maybe we - // can lazy init this if someone tries to create an AHardwareBuffer with - // SHARED_IMAGE_USAGE_GLES2 || !gpu_preferences.enable_vulkan. When in Vulkan - // mode, we should only need this with GLES2. + // code until we are asked to make a GL representation (or allocate a + // backing for import into GL)? We may use an AHardwareBuffer exclusively + // with Vulkan, where there is no need to require that a GL context is + // current. Maybe we can lazy init this if someone tries to create an + // AHardwareBuffer with SHARED_IMAGE_USAGE_GLES2 || + // !gpu_preferences.enable_vulkan. When in Vulkan mode, we should only need + // this with GLES2. gl::GLApi* api = gl::g_current_gl_context; api->glGetIntegervFn(GL_MAX_TEXTURE_SIZE, &max_gl_texture_size_); @@ -381,16 +692,16 @@ } // SHARED_IMAGE_USAGE_RASTER is set when we want to write on Skia - // representation and SHARED_IMAGE_USAGE_DISPLAY is used for cases we want to - // read from skia representation. - // TODO(vikassoni): Also check gpu_preferences.enable_vulkan to figure out if - // skia is using vulkan backing or GL backing. + // representation and SHARED_IMAGE_USAGE_DISPLAY is used for cases we want + // to read from skia representation. + // TODO(vikassoni): Also check gpu_preferences.enable_vulkan to figure out + // if skia is using vulkan backing or GL backing. const bool use_gles2 = (usage & (SHARED_IMAGE_USAGE_GLES2 | SHARED_IMAGE_USAGE_RASTER | SHARED_IMAGE_USAGE_DISPLAY)); - // If usage flags indicated this backing can be used as a GL texture, then do - // below gl related checks. + // If usage flags indicated this backing can be used as a GL texture, then + // do below gl related checks. if (use_gles2) { // Check if the GL texture can be created from AHB with this format. if (!format_info.gl_supported) { @@ -449,7 +760,8 @@ auto backing = std::make_unique<SharedImageBackingAHB>( mailbox, format, size, color_space, usage, - base::android::ScopedHardwareBufferHandle::Adopt(buffer), estimated_size); + base::android::ScopedHardwareBufferHandle::Adopt(buffer), estimated_size, + context_state_); return backing; }
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.h b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.h index 4988f47e..fba257a 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.h +++ b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.h
@@ -22,13 +22,19 @@ struct GpuFeatureInfo; struct Mailbox; +namespace raster { +struct RasterDecoderContextState; +} // namespace raster + // Implementation of SharedImageBackingFactory that produces AHardwareBuffer // backed SharedImages. This is meant to be used on Android only. class GPU_GLES2_EXPORT SharedImageBackingFactoryAHB : public SharedImageBackingFactory { public: - SharedImageBackingFactoryAHB(const GpuDriverBugWorkarounds& workarounds, - const GpuFeatureInfo& gpu_feature_info); + SharedImageBackingFactoryAHB( + const GpuDriverBugWorkarounds& workarounds, + const GpuFeatureInfo& gpu_feature_info, + raster::RasterDecoderContextState* context_state); ~SharedImageBackingFactoryAHB() override; // SharedImageBackingFactory implementation. @@ -77,6 +83,7 @@ // Used to limit the max size of AHardwareBuffer. int32_t max_gl_texture_size_ = 0; + raster::RasterDecoderContextState* context_state_ = nullptr; DISALLOW_COPY_AND_ASSIGN(SharedImageBackingFactoryAHB); };
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer_unittest.cc b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer_unittest.cc index 354a0c6c..746605e 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer_unittest.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer_unittest.cc
@@ -49,8 +49,6 @@ GpuDriverBugWorkarounds workarounds; workarounds.max_texture_size = INT_MAX - 1; - backing_factory_ = std::make_unique<SharedImageBackingFactoryAHB>( - workarounds, GpuFeatureInfo()); scoped_refptr<gl::GLShareGroup> share_group = new gl::GLShareGroup(); context_state_ = new raster::RasterDecoderContextState( @@ -61,6 +59,9 @@ base::MakeRefCounted<gles2::FeatureInfo>(workarounds, GpuFeatureInfo()); context_state_->InitializeGL(std::move(feature_info)); + backing_factory_ = std::make_unique<SharedImageBackingFactoryAHB>( + workarounds, GpuFeatureInfo(), context_state_.get()); + memory_type_tracker_ = std::make_unique<MemoryTypeTracker>(nullptr); shared_image_representation_factory_ = std::make_unique<SharedImageRepresentationFactory>( @@ -149,7 +150,7 @@ EXPECT_EQ(size.height(), surface->height()); skia_representation->EndWriteAccess(std::move(surface)); GrBackendTexture backend_texture; - EXPECT_TRUE(skia_representation->BeginReadAccess(&backend_texture)); + EXPECT_TRUE(skia_representation->BeginReadAccess(nullptr, &backend_texture)); EXPECT_EQ(size.width(), backend_texture.width()); EXPECT_EQ(size.width(), backend_texture.width()); skia_representation->EndReadAccess(); @@ -209,7 +210,7 @@ shared_image_representation_factory_->ProduceSkia(mailbox); EXPECT_TRUE(skia_representation); GrBackendTexture backend_texture; - EXPECT_TRUE(skia_representation->BeginReadAccess(&backend_texture)); + EXPECT_TRUE(skia_representation->BeginReadAccess(nullptr, &backend_texture)); EXPECT_EQ(size.width(), backend_texture.width()); EXPECT_EQ(size.width(), backend_texture.width());
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc index 257ad55f..0ccfee8 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture.cc
@@ -269,7 +269,8 @@ write_surface_ = nullptr; } - bool BeginReadAccess(GrBackendTexture* backend_texture) override { + bool BeginReadAccess(SkSurface* sk_surface, + GrBackendTexture* backend_texture) override { if (!GetGrBackendTexture(gl::GLContext::GetCurrent()->GetVersionInfo(), target_, size(), service_id_, format(), backend_texture)) { @@ -814,24 +815,23 @@ gfx::BufferFormat format, SurfaceHandle surface_handle, const gfx::Size& size) { + if (handle.type == gfx::SHARED_MEMORY_BUFFER) { + if (!base::IsValueInRangeForNumericType<size_t>(handle.stride)) + return nullptr; + auto image = base::MakeRefCounted<gl::GLImageSharedMemory>(size); + if (!image->Initialize(handle.region, handle.id, format, handle.offset, + handle.stride)) { + return nullptr; + } + + return image; + } + if (!image_factory_) return nullptr; - switch (handle.type) { - case gfx::SHARED_MEMORY_BUFFER: { - if (!base::IsValueInRangeForNumericType<size_t>(handle.stride)) - return nullptr; - auto image = base::MakeRefCounted<gl::GLImageSharedMemory>(size); - if (!image->Initialize(handle.region, handle.id, format, handle.offset, - handle.stride)) { - return nullptr; - } - return image; - } - default: - return image_factory_->CreateImageForGpuMemoryBuffer( - std::move(handle), size, format, client_id, surface_handle); - } + return image_factory_->CreateImageForGpuMemoryBuffer( + std::move(handle), size, format, client_id, surface_handle); } std::unique_ptr<SharedImageBacking>
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc index 9b1a5b4..3d58a1b 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_gl_texture_unittest.cc
@@ -186,7 +186,7 @@ EXPECT_EQ(size.height(), surface->height()); skia_representation->EndWriteAccess(std::move(surface)); GrBackendTexture backend_texture; - EXPECT_TRUE(skia_representation->BeginReadAccess(&backend_texture)); + EXPECT_TRUE(skia_representation->BeginReadAccess(nullptr, &backend_texture)); EXPECT_EQ(size.width(), backend_texture.width()); EXPECT_EQ(size.width(), backend_texture.width()); skia_representation->EndReadAccess(); @@ -270,7 +270,7 @@ EXPECT_EQ(size.height(), surface->height()); skia_representation->EndWriteAccess(std::move(surface)); GrBackendTexture backend_texture; - EXPECT_TRUE(skia_representation->BeginReadAccess(&backend_texture)); + EXPECT_TRUE(skia_representation->BeginReadAccess(nullptr, &backend_texture)); EXPECT_EQ(size.width(), backend_texture.width()); EXPECT_EQ(size.width(), backend_texture.width()); skia_representation->EndReadAccess();
diff --git a/gpu/command_buffer/service/shared_image_representation.h b/gpu/command_buffer/service/shared_image_representation.h index 8a1f962..5a1ea6b 100644 --- a/gpu/command_buffer/service/shared_image_representation.h +++ b/gpu/command_buffer/service/shared_image_representation.h
@@ -112,7 +112,8 @@ int final_msaa_count, const SkSurfaceProps& surface_props) = 0; virtual void EndWriteAccess(sk_sp<SkSurface> surface) = 0; - virtual bool BeginReadAccess(GrBackendTexture* backend_texture_out) = 0; + virtual bool BeginReadAccess(SkSurface* sk_surface, + GrBackendTexture* backend_texture_out) = 0; virtual void EndReadAccess() = 0; };
diff --git a/gpu/command_buffer/service/wrapped_sk_image.cc b/gpu/command_buffer/service/wrapped_sk_image.cc index 4b24e0f..f5c9c38 100644 --- a/gpu/command_buffer/service/wrapped_sk_image.cc +++ b/gpu/command_buffer/service/wrapped_sk_image.cc
@@ -205,7 +205,8 @@ write_surface_ = nullptr; } - bool BeginReadAccess(GrBackendTexture* backend_texture) override { + bool BeginReadAccess(SkSurface* sk_surface, + GrBackendTexture* backend_texture) override { if (!wrapped_sk_image()->GetGrBackendTexture(backend_texture)) return false; return true;
diff --git a/gpu/ipc/service/direct_composition_surface_win.cc b/gpu/ipc/service/direct_composition_surface_win.cc index a833540bc..46710ba 100644 --- a/gpu/ipc/service/direct_composition_surface_win.cc +++ b/gpu/ipc/service/direct_composition_surface_win.cc
@@ -1026,8 +1026,28 @@ RECT target_rect = gfx::Rect(swap_chain_size).ToRECT(); decode_swap_chain_->SetTargetRect(&target_rect); - // TODO(sunnyps): Set color space on swap chain. Setting Rec 709 color space - // on the swap chain seems to produce incorrect colors. + gfx::ColorSpace color_space = image_dxgi->color_space(); + if (!color_space.IsValid()) + color_space = gfx::ColorSpace::CreateREC709(); + + // TODO(sunnyps): Move this to gfx::ColorSpaceWin helper where we can access + // internal color space state and do a better job. + // Common color spaces have primaries and transfer function similar to BT 709 + // and there are no other choices anyway. + int flags = DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAG_BT709; + // Proper Rec 709 and 601 have limited or nominal color range. + if (color_space == gfx::ColorSpace::CreateREC709() || + color_space == gfx::ColorSpace::CreateREC601()) { + flags |= DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAG_NOMINAL_RANGE; + } + // xvYCC allows colors outside nominal range to encode negative colors that + // allows for a wider gamut. + if (color_space.FullRangeEncodedValues()) { + flags |= DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAG_xvYCC; + } + decode_swap_chain_->SetColorSpace( + static_cast<DXGI_MULTIPLANE_OVERLAY_YCbCr_FLAGS>(flags)); + HRESULT hr = decode_swap_chain_->PresentBuffer(image_dxgi->level(), 1, 0); base::UmaHistogramSparse("GPU.DirectComposition.DecodeSwapChainPresentResult", hr);
diff --git a/ios/chrome/browser/prerender/preload_controller.mm b/ios/chrome/browser/prerender/preload_controller.mm index 9042d96bb..0b27cd0 100644 --- a/ios/chrome/browser/prerender/preload_controller.mm +++ b/ios/chrome/browser/prerender/preload_controller.mm
@@ -348,9 +348,10 @@ return nil; } -- (CGFloat)nativeContentHeaderHeightForWebState:(web::WebState*)webState { - return [delegate_ nativeContentHeaderHeightForPreloadController:self - webState:webState]; +- (UIEdgeInsets)nativeContentInsetForWebState:(web::WebState*)webState { + // |-controllerForURL:webState:| short-circuits the native controller + // presentation flow, so the insets are never used. + return UIEdgeInsetsZero; } #pragma mark -
diff --git a/ios/chrome/browser/prerender/preload_controller_delegate.h b/ios/chrome/browser/prerender/preload_controller_delegate.h index aa905cf..c1dc4fb 100644 --- a/ios/chrome/browser/prerender/preload_controller_delegate.h +++ b/ios/chrome/browser/prerender/preload_controller_delegate.h
@@ -18,12 +18,6 @@ // Returns YES if the given |url| should be backed by a native controller. - (BOOL)preloadHasNativeControllerForURL:(const GURL&)url; -// Called to retrieve the height of any header that is overlaying on top of the -// native content. -- (CGFloat) -nativeContentHeaderHeightForPreloadController:(PreloadController*)controller - webState:(web::WebState*)webState; - @end #endif // IOS_CHROME_BROWSER_PRERENDER_PRELOAD_CONTROLLER_DELEGATE_H_
diff --git a/ios/chrome/browser/ui/alert_coordinator/repost_form_coordinator.h b/ios/chrome/browser/ui/alert_coordinator/repost_form_coordinator.h index 25d5e822..abc1498 100644 --- a/ios/chrome/browser/ui/alert_coordinator/repost_form_coordinator.h +++ b/ios/chrome/browser/ui/alert_coordinator/repost_form_coordinator.h
@@ -17,10 +17,10 @@ // Initializes a coordinator for displaying an alert on this |viewController|. // |dialogLocation| is a point where the repost form dialog should be presented -// on iPad. |webState| must not be null and must be owned by the caller. -// |completionHandler| will be called with YES when Continue button is tapped -// and with NO when Cancel button is tapped. |completionHandler| can not be -// null. +// on iPad (in |viewController|'s coordinate space). |webState| must not be null +// and must be owned by the caller. |completionHandler| will be called with YES +// when Continue button is tapped and with NO when Cancel button is tapped. +// |completionHandler| can not be null. - (instancetype)initWithBaseViewController:(UIViewController*)viewController dialogLocation:(CGPoint)dialogLocation webState:(web::WebState*)webState
diff --git a/ios/chrome/browser/ui/alert_coordinator/repost_form_coordinator.mm b/ios/chrome/browser/ui/alert_coordinator/repost_form_coordinator.mm index 210fc20..d94fbeb 100644 --- a/ios/chrome/browser/ui/alert_coordinator/repost_form_coordinator.mm +++ b/ios/chrome/browser/ui/alert_coordinator/repost_form_coordinator.mm
@@ -48,7 +48,7 @@ _webState = webState; CGRect sourceRect = CGRectMake(dialogLocation.x, dialogLocation.y, 1, 1); _dialogController = - [[self class] newDialogControllerForSourceView:webState->GetView() + [[self class] newDialogControllerForSourceView:viewController.view sourceRect:sourceRect completionHandler:completionHandler]; // The dialog may be dimissed when a new navigation starts while the dialog @@ -66,7 +66,8 @@ return; // Check to see if an action sheet can be shown. - if ([_webState->GetView() window]) { + if (self.baseViewController.view.window && + !self.baseViewController.presentedViewController) { [self.baseViewController presentViewController:_dialogController animated:YES completion:nil];
diff --git a/ios/chrome/browser/ui/alert_coordinator/repost_form_coordinator_unittest.mm b/ios/chrome/browser/ui/alert_coordinator/repost_form_coordinator_unittest.mm index 6b2f860..7f2ee8d4 100644 --- a/ios/chrome/browser/ui/alert_coordinator/repost_form_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/alert_coordinator/repost_form_coordinator_unittest.mm
@@ -31,9 +31,6 @@ protected: RepostFormCoordinatorTest() { view_controller_ = [[UIViewController alloc] init]; - [scoped_key_window_.Get() setRootViewController:view_controller_]; - UIView* view = [[UIView alloc] initWithFrame:view_controller_.view.bounds]; - web_state_.SetView(view); CGPoint dialogLocation = CGPointMake(kDialogHorizontalLocation, kDialogVerticalLocation); @@ -52,7 +49,7 @@ // Coordinator will not present the dialog until view is added to the window. void AddViewToWindow() { - [view_controller_.view addSubview:web_state_.GetView()]; + [scoped_key_window_.Get() setRootViewController:view_controller_]; } RepostFormCoordinator* coordinator_;
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index de05eb0..5adefbf 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -2486,15 +2486,20 @@ } - (CGRect)ntpFrameForWebState:(web::WebState*)webState { - UIEdgeInsets headerInset = UIEdgeInsetsMake( - [self nativeContentHeaderHeightForWebState:webState], 0, 0, 0); - return UIEdgeInsetsInsetRect(self.contentArea.bounds, headerInset); + NewTabPageTabHelper* NTPHelper = NewTabPageTabHelper::FromWebState(webState); + if (!NTPHelper || !NTPHelper->IsActive()) + return CGRectZero; + // NTP expects to be laid out behind the bottom toolbar. It uses + // |contentInset| to push content above the toolbar. + UIEdgeInsets viewportInsets = [self viewportInsetsForView:self.contentArea]; + viewportInsets.bottom = 0.0; + return UIEdgeInsetsInsetRect(self.contentArea.bounds, viewportInsets); } - (CGRect)visibleFrameForTab:(Tab*)tab { - UIEdgeInsets headerInset = UIEdgeInsetsMake( - [self nativeContentHeaderHeightForWebState:tab.webState], 0, 0, 0); - return UIEdgeInsetsInsetRect([self viewForTab:tab].bounds, headerInset); + UIView* tabView = [self viewForTab:tab]; + return UIEdgeInsetsInsetRect(tabView.bounds, + [self viewportInsetsForView:tabView]); } - (void)setFramesForHeaders:(NSArray<HeaderDefinition*>*)headers @@ -3019,19 +3024,6 @@ CGRectGetHeight(_downloadManagerCoordinator.viewController.view.frame); } -// Returns a vertical voice search bar offset relative to the tab content. -- (CGFloat)voiceSearchOverlayYOffsetForTab:(Tab*)tab { - if (tab != self.tabModel.currentTab) { - // There is no UI representation for non-current tabs or there is - // no visible voice search. Return offset outside of tab. - return CGRectGetMaxY(self.view.frame); - } else { - // The voice search bar on iPhone is displayed at the bottom of a tab. - CGRect visibleFrame = [self visibleFrameForTab:self.tabModel.currentTab]; - return CGRectGetMaxY(visibleFrame); - } -} - #pragma mark - PasswordControllerDelegate methods - (BOOL)displaySignInNotification:(UIViewController*)viewController @@ -3336,9 +3328,9 @@ runRepostFormDialogWithCompletionHandler:(void (^)(BOOL))handler { // Display the action sheet with the arrow pointing at the top center of the // web contents. - UIView* view = webState->GetView(); + CGRect bounds = self.view.bounds; CGPoint dialogLocation = CGPointMake( - CGRectGetMidX(view.frame), CGRectGetMinY(view.frame) + self.headerHeight); + CGRectGetMidX(bounds), CGRectGetMinY(bounds) + self.headerHeight); auto* helper = RepostFormTabHelper::FromWebState(webState); helper->PresentDialog(dialogLocation, base::BindOnce(^(bool shouldContinue) { handler(shouldContinue); @@ -3627,15 +3619,8 @@ return nativeController; } -- (CGFloat)nativeContentHeaderHeightForWebState:(web::WebState*)webState { - if (IsVisibleURLNewTabPage(webState) && ![self canShowTabStrip]) { - if (self.usesFullscreenContainer) - return 0; - // Also subtract the top safe area so the view will appear as full screen. - // TODO(crbug.com/826369) Remove this once NTP is out of native content. - return -self.view.safeAreaInsets.top; - } - return self.headerHeight; +- (UIEdgeInsets)nativeContentInsetForWebState:(web::WebState*)webState { + return [self viewportInsetsForView:webState->GetView()]; } #pragma mark - DialogPresenterDelegate methods @@ -3654,7 +3639,9 @@ - (CGFloat)collapsedTopToolbarHeight { if (base::FeatureList::IsEnabled(web::features::kOutOfWebFullscreen) && - IsVisibleURLNewTabPage(self.currentWebState)) { + IsVisibleURLNewTabPage(self.currentWebState) && ![self canShowTabStrip]) { + // When the NTP is displayed in a horizontally compact environment, the top + // toolbars are hidden. return 0; } CGFloat collapsedToolbarHeight = @@ -3670,7 +3657,9 @@ - (CGFloat)expandedTopToolbarHeight { if (base::FeatureList::IsEnabled(web::features::kOutOfWebFullscreen) && - IsVisibleURLNewTabPage(self.currentWebState)) { + IsVisibleURLNewTabPage(self.currentWebState) && ![self canShowTabStrip]) { + // When the NTP is displayed in a horizontally compact environment, the top + // toolbars are hidden. return 0; } return [self primaryToolbarHeightWithInset] + @@ -3679,10 +3668,6 @@ } - (CGFloat)bottomToolbarHeight { - if (base::FeatureList::IsEnabled(web::features::kOutOfWebFullscreen) && - IsVisibleURLNewTabPage(self.currentWebState)) { - return 0; - } return [self secondaryToolbarHeightWithInset]; } @@ -3875,6 +3860,23 @@ return -(topHeader.frame.origin.y - self.headerOffset); } +// Returns the insets into |view| that result in the visible viewport. +- (UIEdgeInsets)viewportInsetsForView:(UIView*)view { + DCHECK(view); + UIEdgeInsets viewportInsets = FullscreenControllerFactory::GetInstance() + ->GetForBrowserState(_browserState) + ->GetCurrentViewportInsets(); + // TODO(crbug.com/917548): Use BVC for viewport inset coordinate space rather + // than the content area. + CGRect viewportFrame = [view + convertRect:UIEdgeInsetsInsetRect(self.contentArea.bounds, viewportInsets) + fromView:self.contentArea]; + return UIEdgeInsetsMake( + CGRectGetMinY(viewportFrame), CGRectGetMinX(viewportFrame), + CGRectGetMaxY(view.bounds) - CGRectGetMaxY(viewportFrame), + CGRectGetMaxX(view.bounds) - CGRectGetMaxX(viewportFrame)); +} + #pragma mark - KeyCommandsPlumbing - (BOOL)isOffTheRecord { @@ -4967,12 +4969,6 @@ return [self hasControllerForURL:url]; } -- (CGFloat) -nativeContentHeaderHeightForPreloadController:(PreloadController*)controller - webState:(web::WebState*)webState { - return [self nativeContentHeaderHeightForWebState:webState]; -} - #pragma mark - NetExportTabHelperDelegate - (void)netExportTabHelper:(NetExportTabHelper*)tabHelper
diff --git a/ios/chrome/browser/ui/open_in_controller.mm b/ios/chrome/browser/ui/open_in_controller.mm index af43388..ed86ab2 100644 --- a/ios/chrome/browser/ui/open_in_controller.mm +++ b/ios/chrome/browser/ui/open_in_controller.mm
@@ -311,7 +311,7 @@ OpenInToolbar* openInToolbar = [self openInToolbar]; if (!isOpenInToolbarDisplayed_) { - openInToolbar.bottomMarginConstraint.active = YES; + [openInToolbar updateBottomMarginHeight]; [UIView animateWithDuration:kOpenInToolbarAnimationDuration animations:^{ [openInToolbar setAlpha:1.0];
diff --git a/ios/chrome/browser/ui/open_in_toolbar.h b/ios/chrome/browser/ui/open_in_toolbar.h index 1584594..4e017b44 100644 --- a/ios/chrome/browser/ui/open_in_toolbar.h +++ b/ios/chrome/browser/ui/open_in_toolbar.h
@@ -11,8 +11,8 @@ - (instancetype)initWithTarget:(id)target action:(SEL)action; -// Constraint to have the open in toolbar be displayed above the bottom toolbar. -@property(nonatomic, strong) NSLayoutConstraint* bottomMarginConstraint; +// Updates the constraint managing the bottom margin height using NamedGuides. +- (void)updateBottomMarginHeight; @end
diff --git a/ios/chrome/browser/ui/open_in_toolbar.mm b/ios/chrome/browser/ui/open_in_toolbar.mm index 45b42f2..fd3213a3 100644 --- a/ios/chrome/browser/ui/open_in_toolbar.mm +++ b/ios/chrome/browser/ui/open_in_toolbar.mm
@@ -57,6 +57,9 @@ // https://crbug.com/857371. @property(nonatomic, strong) UIView* bottomMargin; +// Constraint to have the open in toolbar be displayed above the bottom toolbar. +@property(nonatomic, strong) NSLayoutConstraint* bottomMarginConstraint; + // Relayout the frame of the Open In toolbar, based on its superview and the // bottom margin. - (void)relayout; @@ -162,6 +165,27 @@ return _topBorder; } +- (void)setBottomMarginConstraint:(NSLayoutConstraint*)bottomMarginConstraint { + if (_bottomMarginConstraint == bottomMarginConstraint) + return; + + _bottomMarginConstraint.active = NO; + _bottomMarginConstraint = bottomMarginConstraint; + _bottomMarginConstraint.active = YES; +} + +#pragma mark Public + +- (void)updateBottomMarginHeight { + NSLayoutDimension* marginHeightAnchor = self.bottomMargin.heightAnchor; + NamedGuide* guide = [NamedGuide guideWithName:kSecondaryToolbarGuide + view:self]; + self.bottomMarginConstraint = + guide ? [marginHeightAnchor constraintEqualToAnchor:guide.heightAnchor] + : [marginHeightAnchor constraintEqualToConstant:0]; + [self relayout]; +} + #pragma mark Layout - (CGSize)sizeThatFits:(CGSize)size { @@ -172,21 +196,7 @@ } - (void)didMoveToWindow { - if (!self.window) { - self.bottomMarginConstraint = nil; - return; - } - - self.bottomMarginConstraint.active = NO; - // If the bottom toolbar isn't present on screen, guide is nil and then - // bottomMarginConstraint is also nil. - NamedGuide* guide = - [NamedGuide guideWithName:kSecondaryToolbarGuide view:self]; - self.bottomMarginConstraint = [guide.heightAnchor - constraintEqualToAnchor:self.bottomMargin.heightAnchor]; - self.bottomMarginConstraint.active = YES; - - [self relayout]; + [self updateBottomMarginHeight]; } - (void)relayout {
diff --git a/ios/components/io_thread/DEPS b/ios/components/io_thread/DEPS index c088928..89b16ff94 100644 --- a/ios/components/io_thread/DEPS +++ b/ios/components/io_thread/DEPS
@@ -7,4 +7,8 @@ "+components/version_info", "+ios/web/public", "+net", + + # Temporarily allow WebThreadImpl until TaskExecutor functionality is moved + # into a new file in ios/web/public. + "+ios/web/web_thread_impl.h" ]
diff --git a/ios/components/io_thread/ios_io_thread_unittest.mm b/ios/components/io_thread/ios_io_thread_unittest.mm index cc1580d..3915f21 100644 --- a/ios/components/io_thread/ios_io_thread_unittest.mm +++ b/ios/components/io_thread/ios_io_thread_unittest.mm
@@ -4,16 +4,16 @@ #include "ios/components/io_thread/ios_io_thread.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "components/prefs/pref_registry_simple.h" -#include "components/prefs/pref_service.h" -#include "components/prefs/pref_service_factory.h" -#include "components/prefs/testing_pref_store.h" +#include <memory> + +#include "base/test/scoped_task_environment.h" +#include "components/prefs/testing_pref_service.h" #include "components/proxy_config/pref_proxy_config_tracker_impl.h" -#include "ios/web/public/test/test_web_thread_bundle.h" -#include "net/test/url_request/url_request_failed_job.h" -#include "net/url_request/url_request_filter.h" +#import "ios/web/public/test/fakes/test_web_client.h" +#include "ios/web/public/test/scoped_testing_web_client.h" +#include "ios/web/public/test/test_web_thread.h" +#include "ios/web/web_thread_impl.h" +#include "net/base/network_delegate.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest_mac.h" #include "testing/platform_test.h" @@ -42,32 +42,43 @@ class IOSIOThreadTest : public PlatformTest { public: - IOSIOThreadTest() : thread_bundle_(web::TestWebThreadBundle::IO_MAINLOOP) { - net::URLRequestFailedJob::AddUrlHandler(); + IOSIOThreadTest() : web_client_(std::make_unique<web::TestWebClient>()) { + web::WebThreadImpl::CreateTaskExecutor(); + + ui_thread_ = std::make_unique<web::TestWebThread>( + web::WebThread::UI, scoped_task_environment_.GetMainThreadTaskRunner()); } ~IOSIOThreadTest() override { - net::URLRequestFilter::GetInstance()->ClearHandlers(); + web::WebThreadImpl::ResetTaskExecutorForTesting(); } - private: - web::TestWebThreadBundle thread_bundle_; + protected: + base::test::ScopedTaskEnvironment scoped_task_environment_; + web::ScopedTestingWebClient web_client_; + std::unique_ptr<web::TestWebThread> ui_thread_; }; // Tests the creation of an IOSIOThread and verifies that it returns a system // url request context. TEST_F(IOSIOThreadTest, AssertSystemUrlRequestContext) { - PrefServiceFactory pref_service_factory; - pref_service_factory.set_user_prefs(base::MakeRefCounted<TestingPrefStore>()); + std::unique_ptr<TestingPrefServiceSimple> pref_service( + std::make_unique<TestingPrefServiceSimple>()); + PrefProxyConfigTrackerImpl::RegisterPrefs(pref_service->registry()); - scoped_refptr<PrefRegistrySimple> pref_registry = new PrefRegistrySimple; - PrefProxyConfigTrackerImpl::RegisterPrefs(pref_registry.get()); + // Create the IO thread but do not register it yet. + std::unique_ptr<web::TestWebThread> io_thread( + std::make_unique<web::TestWebThread>(web::WebThread::IO)); + io_thread->StartIOThreadUnregistered(); - std::unique_ptr<PrefService> pref_service( - pref_service_factory.Create(pref_registry.get())); - - std::unique_ptr<TestIOThread> test_io_thread( + // Create the TestIOThread before the IO thread is registered. + std::unique_ptr<TestIOThread> ios_io_thread( new TestIOThread(pref_service.get(), nullptr)); + io_thread->RegisterAsWebThread(); - ASSERT_TRUE(test_io_thread->system_url_request_context_getter()); + ASSERT_TRUE(ios_io_thread->system_url_request_context_getter()); + + // Explicitly destroy the IO thread so that it is unregistered before the + // TestIOThread is destroyed. + io_thread.reset(); }
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn index 4ba52f6..6e5b9fa5 100644 --- a/ios/web/BUILD.gn +++ b/ios/web/BUILD.gn
@@ -51,7 +51,6 @@ "//services/network:network_service", "//services/network/public/mojom", "//services/service_manager", - "//services/service_manager/embedder", "//services/service_manager/public/cpp", ]
diff --git a/ios/web/app/web_main_loop.h b/ios/web/app/web_main_loop.h index 3cc416d6..14ce06e 100644 --- a/ios/web/app/web_main_loop.h +++ b/ios/web/app/web_main_loop.h
@@ -83,7 +83,7 @@ // This must get destroyed after other threads that are created in parts_. std::unique_ptr<WebThreadImpl> main_thread_; - // Members initialized in |RunMainMessageLoopParts()| ------------------------ + // Members initialized in |CreateThreads()| ------------------------ std::unique_ptr<WebSubThread> io_thread_; // Members initialized in |WebThreadsStarted()| --------------------------
diff --git a/ios/web/app/web_main_loop.mm b/ios/web/app/web_main_loop.mm index d3bf9fe..083fc5d1 100644 --- a/ios/web/app/web_main_loop.mm +++ b/ios/web/app/web_main_loop.mm
@@ -130,7 +130,9 @@ base::Thread::Options io_message_loop_options; io_message_loop_options.message_loop_type = base::MessageLoop::TYPE_IO; io_thread_ = std::make_unique<WebSubThread>(WebThread::IO); - io_thread_->StartWithOptions(io_message_loop_options); + if (!io_thread_->StartWithOptions(io_message_loop_options)) + LOG(FATAL) << "Failed to start WebThread::IO"; + io_thread_->RegisterAsWebThread(); // Only start IO thread above as this is the only WebThread besides UI (which // is the main thread). @@ -196,8 +198,10 @@ base::PlatformThread::SetName("CrWebMain"); // Register the main thread by instantiating it, but don't call any methods. + DCHECK(base::ThreadTaskRunnerHandle::IsSet()); main_thread_.reset(new WebThreadImpl( - WebThread::UI, ios_global_state::GetMainThreadMessageLoop())); + WebThread::UI, + ios_global_state::GetMainThreadMessageLoop()->task_runner())); } int WebMainLoop::WebThreadsStarted() {
diff --git a/ios/web/public/test/fakes/test_native_content_provider.mm b/ios/web/public/test/fakes/test_native_content_provider.mm index 17c390e..ad116ce 100644 --- a/ios/web/public/test/fakes/test_native_content_provider.mm +++ b/ios/web/public/test/fakes/test_native_content_provider.mm
@@ -32,8 +32,8 @@ return nativeContent == _nativeContent.end() ? nil : nativeContent->second; } -- (CGFloat)nativeContentHeaderHeightForWebState:(web::WebState*)webState { - return 0; +- (UIEdgeInsets)nativeContentInsetForWebState:(web::WebState*)webState { + return UIEdgeInsetsZero; } @end
diff --git a/ios/web/public/test/test_web_thread.h b/ios/web/public/test/test_web_thread.h index bc5e427..449359e 100644 --- a/ios/web/public/test/test_web_thread.h +++ b/ios/web/public/test/test_web_thread.h
@@ -12,18 +12,29 @@ namespace base { class MessageLoop; +class Thread; } namespace web { -class TestWebThreadImpl; +class WebSubThread; +class WebThreadImpl; // DEPRECATED: use TestWebThreadBundle instead. // A WebThread for unit tests; this lets unit tests outside of web create // WebThread instances. class TestWebThread { public: + // Constructs a TestWebThread with a |real_thread_| and starts it (with a + // MessageLoopForIO if |identifier == WebThread::IO|). explicit TestWebThread(WebThread::ID identifier); + + // Constructs a TestWebThread "running" on |thread_runner| (no + // |real_thread_|). + TestWebThread(WebThread::ID identifier, + scoped_refptr<base::SingleThreadTaskRunner> thread_runner); + + // Constructs a TestWebThread based on |message_loop| (no |real_thread_|). TestWebThread(WebThread::ID identifier, base::MessageLoop* message_loop); ~TestWebThread(); @@ -33,22 +44,31 @@ // WebThread, do no provide the full Thread interface. // Starts the thread with a generic message loop. - bool Start(); + void Start(); // Starts the thread with an IOThread message loop. - bool StartIOThread(); + void StartIOThread(); + + // Together these are the same as StartIOThread(). They can be called in + // phases to test binding WebThread::IO after its underlying thread was + // started. + void StartIOThreadUnregistered(); + void RegisterAsWebThread(); // Stops the thread. void Stop(); - // Returns true if the thread is running. - bool IsRunning(); - private: - std::unique_ptr<TestWebThreadImpl> impl_; - const WebThread::ID identifier_; + // A real thread which represents |identifier_| when constructor #1 is used + // (null otherwise). + std::unique_ptr<WebSubThread> real_thread_; + + // Binds |identifier_| to |message_loop| when constructor #2 is used (null + // otherwise). + std::unique_ptr<WebThreadImpl> fake_thread_; + DISALLOW_COPY_AND_ASSIGN(TestWebThread); };
diff --git a/ios/web/public/web_state/ui/crw_native_content_provider.h b/ios/web/public/web_state/ui/crw_native_content_provider.h index 01b3266f..2feba845 100644 --- a/ios/web/public/web_state/ui/crw_native_content_provider.h +++ b/ios/web/public/web_state/ui/crw_native_content_provider.h
@@ -27,13 +27,8 @@ - (id<CRWNativeContent>)controllerForURL:(const GURL&)url webState:(web::WebState*)webState; -// Called to retrieve the height of any header that is overlaying on top of the -// native content. This can be used to implement, for e.g. a toolbar that -// changes height dynamically. Returning a non-zero height affects the visible -// frame shown by the CRWWebController. 0.0 is assumed if not implemented. -// TODO(crbug.com/674991) These should be removed when native content is -// removed. -- (CGFloat)nativeContentHeaderHeightForWebState:(web::WebState*)webState; +// Returns the inset from |webState|'s view to lay out provided native content. +- (UIEdgeInsets)nativeContentInsetForWebState:(web::WebState*)webState; @end
diff --git a/ios/web/public/web_thread.h b/ios/web/public/web_thread.h index 1244866..811520d 100644 --- a/ios/web/public/web_thread.h +++ b/ios/web/public/web_thread.h
@@ -95,9 +95,9 @@ // Only one delegate may be registered at a time. Delegates may be // unregistered by providing a nullptr pointer. // - // If the caller unregisters a delegate before CleanUp has been - // called, it must perform its own locking to ensure the delegate is - // not deleted while unregistering. + // The delegate can only be registered through this call before + // WebThreadImpl(WebThread::IO) is created and unregistered after + // it was destroyed and its underlying thread shutdown. static void SetIOThreadDelegate(WebThreadDelegate* delegate); // Returns an appropriate error message for when DCHECK_CURRENTLY_ON() fails.
diff --git a/ios/web/public/web_thread_delegate.h b/ios/web/public/web_thread_delegate.h index 9c57bd67..f8005761 100644 --- a/ios/web/public/web_thread_delegate.h +++ b/ios/web/public/web_thread_delegate.h
@@ -13,14 +13,17 @@ // If registered as such, it will schedule to run Init() before the // message loop begins, and receive a CleanUp() call right after the message // loop ends (and before the WebThread has done its own clean-up). + +// A delegate for //web embedders to perform extra initialization/cleanup on +// WebThread::IO. class WebThreadDelegate { public: virtual ~WebThreadDelegate() {} - // Called prior to starting the message loop + // Called prior to completing initialization of WebThread::IO. virtual void Init() = 0; - // Called just after the message loop ends. + // Called during teardown of WebThread::IO. virtual void CleanUp() = 0; };
diff --git a/ios/web/service_manager_context.mm b/ios/web/service_manager_context.mm index 3f10f2b9..df31e85 100644 --- a/ios/web/service_manager_context.mm +++ b/ios/web/service_manager_context.mm
@@ -26,10 +26,8 @@ #include "ios/web/public/web_task_traits.h" #include "ios/web/public/web_thread.h" #include "ios/web/service_manager_connection_impl.h" -#include "services/catalog/public/cpp/manifest_parsing_util.h" #include "services/catalog/public/mojom/constants.mojom.h" #include "services/service_manager/connect_params.h" -#include "services/service_manager/embedder/manifest_utils.h" #include "services/service_manager/public/cpp/connector.h" #include "services/service_manager/public/cpp/constants.h" #include "services/service_manager/public/cpp/manifest.h"
diff --git a/ios/web/test/test_web_thread.cc b/ios/web/test/test_web_thread.cc index cee2468..4cb38dc 100644 --- a/ios/web/test/test_web_thread.cc +++ b/ios/web/test/test_web_thread.cc
@@ -6,41 +6,36 @@ #include "base/macros.h" #include "base/message_loop/message_loop.h" +#include "ios/web/web_sub_thread.h" #include "ios/web/web_thread_impl.h" namespace web { -class TestWebThreadImpl : public WebThreadImpl { - public: - TestWebThreadImpl(WebThread::ID identifier) : WebThreadImpl(identifier) {} - - TestWebThreadImpl(WebThread::ID identifier, base::MessageLoop* message_loop) - : WebThreadImpl(identifier, message_loop) {} - - ~TestWebThreadImpl() override { Stop(); } - - private: - DISALLOW_COPY_AND_ASSIGN(TestWebThreadImpl); -}; - TestWebThread::TestWebThread(WebThread::ID identifier) - : impl_(new TestWebThreadImpl(identifier)), identifier_(identifier) {} + : identifier_(identifier), + real_thread_(std::make_unique<WebSubThread>(identifier_)) { + real_thread_->AllowBlockingForTesting(); +} + +TestWebThread::TestWebThread( + WebThread::ID identifier, + scoped_refptr<base::SingleThreadTaskRunner> thread_runner) + : identifier_(identifier), + fake_thread_(new WebThreadImpl(identifier_, thread_runner)) {} TestWebThread::TestWebThread(WebThread::ID identifier, base::MessageLoop* message_loop) - : impl_(new TestWebThreadImpl(identifier, message_loop)), - identifier_(identifier) {} + : TestWebThread(identifier, message_loop->task_runner()) {} TestWebThread::~TestWebThread() { // The upcoming WebThreadImpl::ResetGlobalsForTesting() call requires that - // |impl_| have triggered the shutdown phase for its WebThread::ID. This - // either happens when the thread is stopped (if real) or destroyed (when fake - // -- i.e. using an externally provided MessageLoop). - impl_.reset(); + // |identifier_| completed its shutdown phase. + real_thread_.reset(); + fake_thread_.reset(); - // Resets WebThreadImpl's globals so that |impl_| is no longer bound to - // |identifier_|. This is fine since the underlying MessageLoop has already - // been flushed and deleted in Stop(). In the case of an externally provided + // Resets WebThreadImpl's globals so that |identifier_| is no longer + // bound. This is fine since the underlying MessageLoop has already been + // flushed and deleted above. In the case of an externally provided // MessageLoop however, this means that TaskRunners obtained through // |WebThreadImpl::GetTaskRunnerForThread(identifier_)| will no longer // recognize their WebThreadImpl for RunsTasksInCurrentSequence(). This @@ -54,22 +49,29 @@ WebThreadImpl::ResetGlobalsForTesting(identifier_); } -bool TestWebThread::Start() { - return impl_->Start(); +void TestWebThread::Start() { + CHECK(real_thread_->Start()); + RegisterAsWebThread(); } -bool TestWebThread::StartIOThread() { +void TestWebThread::StartIOThread() { + StartIOThreadUnregistered(); + RegisterAsWebThread(); +} + +void TestWebThread::StartIOThreadUnregistered() { base::Thread::Options options; options.message_loop_type = base::MessageLoop::TYPE_IO; - return impl_->StartWithOptions(options); + CHECK(real_thread_->StartWithOptions(options)); +} + +void TestWebThread::RegisterAsWebThread() { + real_thread_->RegisterAsWebThread(); } void TestWebThread::Stop() { - impl_->Stop(); -} - -bool TestWebThread::IsRunning() { - return impl_->IsRunning(); + if (real_thread_) + real_thread_->Stop(); } } // namespace web
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index c04b05c..57fcf41f4 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -2347,9 +2347,9 @@ return _webViewProxy; } -- (CGFloat)nativeContentHeaderHeightForContainerView: +- (UIEdgeInsets)nativeContentInsetsForContainerView: (CRWWebControllerContainerView*)containerView { - return [_nativeProvider nativeContentHeaderHeightForWebState:self.webState]; + return [self.nativeProvider nativeContentInsetForWebState:self.webState]; } #pragma mark -
diff --git a/ios/web/web_state/ui/crw_web_controller_container_view.h b/ios/web/web_state/ui/crw_web_controller_container_view.h index 74f83c54..5b6d44e 100644 --- a/ios/web/web_state/ui/crw_web_controller_container_view.h +++ b/ios/web/web_state/ui/crw_web_controller_container_view.h
@@ -21,8 +21,9 @@ - (CRWWebViewProxyImpl*)contentViewProxyForContainerView: (CRWWebControllerContainerView*)containerView; -// Returns the height for any toolbars that overlap the top native content. -- (CGFloat)nativeContentHeaderHeightForContainerView: +// Returns the insets from |containerView|'s bounds in which to lay out native +// content. +- (UIEdgeInsets)nativeContentInsetsForContainerView: (CRWWebControllerContainerView*)containerView; @end
diff --git a/ios/web/web_state/ui/crw_web_controller_container_view.mm b/ios/web/web_state/ui/crw_web_controller_container_view.mm index 1a56c3a..e2af8c2 100644 --- a/ios/web/web_state/ui/crw_web_controller_container_view.mm +++ b/ios/web/web_state/ui/crw_web_controller_container_view.mm
@@ -25,12 +25,6 @@ // Convenience getter for the proxy object. @property(nonatomic, weak, readonly) CRWWebViewProxyImpl* contentViewProxy; -// Returns |self.bounds| after being inset at the top and bottom by the header -// and footer heights returned by the delegate. This is only used to lay out -// native controllers, as the header height is already accounted for in the -// scroll view content insets for other CRWContentViews. -@property(nonatomic, readonly) CGRect nativeContentVisibleFrame; - @end @implementation CRWWebControllerContainerView @@ -102,13 +96,6 @@ return [_delegate contentViewProxyForContainerView:self]; } -- (CGRect)nativeContentVisibleFrame { - CGFloat headerHeight = - [_delegate nativeContentHeaderHeightForContainerView:self]; - return UIEdgeInsetsInsetRect(self.bounds, - UIEdgeInsetsMake(headerHeight, 0, 0, 0)); -} - #pragma mark Layout - (void)traitCollectionDidChange:(UITraitCollection*)previousTraitCollection { @@ -138,7 +125,8 @@ [self addSubview:nativeView]; [nativeView setNeedsUpdateConstraints]; } - nativeView.frame = self.nativeContentVisibleFrame; + nativeView.frame = UIEdgeInsetsInsetRect( + self.bounds, [self.delegate nativeContentInsetsForContainerView:self]); } // transientContentView layout.
diff --git a/ios/web/web_sub_thread.cc b/ios/web/web_sub_thread.cc index 5a7f39a..4ab2333 100644 --- a/ios/web/web_sub_thread.cc +++ b/ios/web/web_sub_thread.cc
@@ -4,43 +4,122 @@ #include "ios/web/web_sub_thread.h" +#include "base/compiler_specific.h" +#include "base/debug/alias.h" #include "base/threading/thread_restrictions.h" -#include "ios/web/public/web_thread.h" +#include "ios/web/public/web_thread_delegate.h" #include "ios/web/web_thread_impl.h" #include "net/url_request/url_fetcher.h" namespace web { -WebSubThread::WebSubThread(WebThread::ID identifier) - : WebThreadImpl(identifier) {} +namespace { +WebThreadDelegate* g_io_thread_delegate = nullptr; +} // namespace -WebSubThread::WebSubThread(WebThread::ID identifier, - base::MessageLoop* message_loop) - : WebThreadImpl(identifier, message_loop) {} +// static +void WebThread::SetIOThreadDelegate(WebThreadDelegate* delegate) { + // |delegate| can only be set/unset while WebThread::IO isn't up. + DCHECK(!WebThread::IsThreadInitialized(WebThread::IO)); + // and it cannot be set twice. + DCHECK(!g_io_thread_delegate || !delegate); + + g_io_thread_delegate = delegate; +} + +WebSubThread::WebSubThread(WebThread::ID identifier) + : base::Thread(WebThreadImpl::GetThreadName(identifier)), + identifier_(identifier) { + // Not bound to creation thread. + DETACH_FROM_THREAD(web_thread_checker_); +} WebSubThread::~WebSubThread() { Stop(); } -void WebSubThread::Init() { - WebThreadImpl::Init(); +void WebSubThread::RegisterAsWebThread() { + DCHECK(IsRunning()); - if (WebThread::CurrentlyOn(WebThread::IO)) { - // Though this thread is called the "IO" thread, it actually just routes - // messages around; it shouldn't be allowed to perform any blocking disk - // I/O. + DCHECK(!web_thread_); + web_thread_.reset(new WebThreadImpl(identifier_, task_runner())); + + // Unretained(this) is safe as |this| outlives its underlying thread. + task_runner()->PostTask( + FROM_HERE, + base::BindOnce(&WebSubThread::CompleteInitializationOnWebThread, + Unretained(this))); +} + +void WebSubThread::AllowBlockingForTesting() { + DCHECK(!IsRunning()); + is_blocking_allowed_for_testing_ = true; +} + +void WebSubThread::Init() { + DCHECK_CALLED_ON_VALID_THREAD(web_thread_checker_); + + if (!is_blocking_allowed_for_testing_) { base::DisallowUnresponsiveTasks(); } } -void WebSubThread::CleanUp() { - if (WebThread::CurrentlyOn(WebThread::IO)) - IOThreadPreCleanUp(); +void WebSubThread::Run(base::RunLoop* run_loop) { + DCHECK_CALLED_ON_VALID_THREAD(web_thread_checker_); - WebThreadImpl::CleanUp(); + switch (identifier_) { + case WebThread::UI: + // The main thread is usually promoted as the UI thread and doesn't go + // through Run() but some tests do run a separate UI thread. + UIThreadRun(run_loop); + break; + case WebThread::IO: + IOThreadRun(run_loop); + return; + case WebThread::ID_COUNT: + NOTREACHED(); + break; + } } -void WebSubThread::IOThreadPreCleanUp() { +void WebSubThread::CleanUp() { + DCHECK_CALLED_ON_VALID_THREAD(web_thread_checker_); + + // Run extra cleanup if this thread represents WebThread::IO. + if (WebThread::CurrentlyOn(WebThread::IO)) + IOThreadCleanUp(); + + if (identifier_ == WebThread::IO && g_io_thread_delegate) + g_io_thread_delegate->CleanUp(); + + web_thread_.reset(); +} + +void WebSubThread::CompleteInitializationOnWebThread() { + DCHECK_CALLED_ON_VALID_THREAD(web_thread_checker_); + + if (identifier_ == WebThread::IO && g_io_thread_delegate) { + // Allow blocking calls while initializing the IO thread. + base::ScopedAllowBlocking allow_blocking_for_init; + g_io_thread_delegate->Init(); + } +} + +void WebSubThread::UIThreadRun(base::RunLoop* run_loop) { + const int line_number = __LINE__; + Thread::Run(run_loop); + base::debug::Alias(&line_number); +} + +void WebSubThread::IOThreadRun(base::RunLoop* run_loop) { + const int line_number = __LINE__; + Thread::Run(run_loop); + base::debug::Alias(&line_number); +} + +void WebSubThread::IOThreadCleanUp() { + DCHECK_CALLED_ON_VALID_THREAD(web_thread_checker_); + // Kill all things that might be holding onto // net::URLRequest/net::URLRequestContexts.
diff --git a/ios/web/web_sub_thread.h b/ios/web/web_sub_thread.h index 9805f536..4d8a26f 100644 --- a/ios/web/web_sub_thread.h +++ b/ios/web/web_sub_thread.h
@@ -6,26 +6,65 @@ #define IOS_WEB_WEB_SUB_THREAD_H_ #include "base/macros.h" -#include "ios/web/web_thread_impl.h" +#include "base/threading/thread.h" +#include "base/threading/thread_checker.h" +#include "ios/web/public/web_thread.h" + +namespace web { +class WebThreadImpl; +} namespace web { -// This simple thread object is used for the specialized threads that are spun -// up during startup. -class WebSubThread : public WebThreadImpl { +// A WebSubThread is a physical thread backing a WebThread. +class WebSubThread : public base::Thread { public: + // Constructs a WebSubThread for |identifier|. explicit WebSubThread(WebThread::ID identifier); - WebSubThread(WebThread::ID identifier, base::MessageLoop* message_loop); ~WebSubThread() override; + // Registers this thread to represent |identifier_| in the web_thread.h + // API. This thread must already be running when this is called. This can only + // be called once per WebSubThread instance. + void RegisterAsWebThread(); + + // Ideally there wouldn't be a special blanket allowance to block the + // WebThreads in tests but TestWebThreadImpl previously bypassed + // WebSubThread and hence wasn't subject to ThreadRestrictions... + // Flipping that around in favor of explicit scoped allowances would be + // preferable but a non-trivial amount of work. Can only be called before + // starting this WebSubThread. + void AllowBlockingForTesting(); + protected: void Init() override; + void Run(base::RunLoop* run_loop) override; void CleanUp() override; private: - // These methods encapsulate cleanup that needs to happen on the IO thread - // before the embedder's |CleanUp()| function is called. - void IOThreadPreCleanUp(); + // Second Init() phase that must happen on this thread but can only happen + // after it's promoted to a WebThread in |RegisterAsWebThread()|. + void CompleteInitializationOnWebThread(); + + // These methods merely forwards to Thread::Run() but are useful to identify + // which WebThread this represents in stack traces. + void UIThreadRun(base::RunLoop* run_loop); + void IOThreadRun(base::RunLoop* run_loop); + + // This method encapsulates cleanup that needs to happen on the IO thread. + void IOThreadCleanUp(); + + const WebThread::ID identifier_; + + // WebThreads are not allowed to do file I/O nor wait on synchronization + // primitives except when explicitly allowed in tests. + bool is_blocking_allowed_for_testing_ = false; + + // The WebThread registration for this |identifier_|, initialized in + // RegisterAsWebThread(). + std::unique_ptr<WebThreadImpl> web_thread_; + + THREAD_CHECKER(web_thread_checker_); DISALLOW_COPY_AND_ASSIGN(WebSubThread); };
diff --git a/ios/web/web_thread_impl.cc b/ios/web/web_thread_impl.cc index 2feb1e7..54c7348 100644 --- a/ios/web/web_thread_impl.cc +++ b/ios/web/web_thread_impl.cc
@@ -9,6 +9,7 @@ #include "base/atomicops.h" #include "base/bind.h" +#include "base/callback.h" #include "base/compiler_specific.h" #include "base/lazy_instance.h" #include "base/macros.h" @@ -17,6 +18,7 @@ #include "base/single_thread_task_runner.h" #include "base/task/post_task.h" #include "base/task/task_executor.h" +#include "base/time/time.h" #include "ios/web/public/web_task_traits.h" #include "ios/web/public/web_thread_delegate.h" @@ -24,18 +26,6 @@ namespace { -// Friendly names for the well-known threads. -const char* const g_web_thread_names[WebThread::ID_COUNT] = { - "Web_UIThread", // UI - "Web_IOThread", // IO -}; - -static const char* GetThreadName(WebThread::ID thread) { - if (WebThread::UI <= thread && thread < WebThread::ID_COUNT) - return g_web_thread_names[thread]; - return "Unknown Thread"; -} - // An implementation of SingleThreadTaskRunner to be used in conjunction // with WebThread. class WebThreadTaskRunner : public base::SingleThreadTaskRunner { @@ -88,17 +78,12 @@ enum WebThreadState { // WebThread::ID does not exist. UNINITIALIZED = 0, - // WebThread::ID is associated with a WebThreadImpl instance but the - // underlying thread hasn't started yet. - INITIALIZED, // WebThread::ID is associated to a TaskRunner and is accepting tasks. RUNNING, // WebThread::ID no longer accepts tasks. SHUTDOWN, }; -using WebThreadDelegateAtomicPtr = base::subtle::AtomicWord; - struct WebThreadGlobals { WebThreadGlobals() { } @@ -114,11 +99,6 @@ // This array is protected by |lock|. Holds the state of each WebThread::ID. WebThreadState states[WebThread::ID_COUNT] GUARDED_BY(lock) = {}; - - // Only atomic operations are used on this pointer. The delegate isn't owned - // by WebThreadGlobals, rather by whoever calls - // WebThread::SetIOThreadDelegate. - WebThreadDelegateAtomicPtr io_thread_delegate; }; base::LazyInstance<WebThreadGlobals>::Leaky g_globals = @@ -234,186 +214,55 @@ } // namespace -WebThreadImpl::WebThreadImpl(ID identifier) - : Thread(GetThreadName(identifier)), identifier_(identifier) { - Initialize(); -} +WebThreadImpl::WebThreadImpl( + ID identifier, + scoped_refptr<base::SingleThreadTaskRunner> task_runner) + : identifier_(identifier) { + DCHECK(task_runner); -WebThreadImpl::WebThreadImpl(ID identifier, base::MessageLoop* message_loop) - : Thread(GetThreadName(identifier)), identifier_(identifier) { - SetMessageLoop(message_loop); - Initialize(); - - // If constructed with an explicit message loop, this is a fake - // WebThread which runs on the current thread. WebThreadGlobals& globals = g_globals.Get(); + base::AutoLock lock(globals.lock); - - DCHECK(!globals.task_runners[identifier_]); - globals.task_runners[identifier_] = this->task_runner(); - - DCHECK_EQ(globals.states[identifier_], WebThreadState::INITIALIZED); - globals.states[identifier_] = WebThreadState::RUNNING; -} - -void WebThreadImpl::Init() { - WebThreadGlobals& globals = g_globals.Get(); - -#if DCHECK_IS_ON() - { - base::AutoLock lock(globals.lock); - // |globals| should already have been initialized for |identifier_| in - // WebThreadImpl::StartWithOptions(). If this isn't the case it's likely - // because this WebThreadImpl's owner incorrectly used Thread::Start.*() - // instead of WebThreadImpl::Start.*(). - DCHECK_EQ(globals.states[identifier_], WebThreadState::RUNNING); - DCHECK(globals.task_runners[identifier_]); - DCHECK(globals.task_runners[identifier_]->RunsTasksInCurrentSequence()); - } -#endif // DCHECK_IS_ON() - - if (identifier_ == WebThread::IO) { - WebThreadDelegateAtomicPtr delegate = - base::subtle::NoBarrier_Load(&globals.io_thread_delegate); - if (delegate) - reinterpret_cast<WebThreadDelegate*>(delegate)->Init(); - } -} - -NOINLINE void WebThreadImpl::UIThreadRun(base::RunLoop* run_loop) { - volatile int line_number = __LINE__; - Thread::Run(run_loop); - CHECK_GT(line_number, 0); -} - -NOINLINE void WebThreadImpl::IOThreadRun(base::RunLoop* run_loop) { - volatile int line_number = __LINE__; - Thread::Run(run_loop); - CHECK_GT(line_number, 0); -} - -bool WebThreadImpl::Start() { - return StartWithOptions(base::Thread::Options()); -} - -bool WebThreadImpl::StartWithOptions(const Options& options) { - WebThreadGlobals& globals = g_globals.Get(); - - // Holding the lock is necessary when kicking off the thread to ensure - // |states| and |task_runners| are updated before it gets to query them. - base::AutoLock lock(globals.lock); - - bool result = Thread::StartWithOptions(options); - - // Although the thread is starting asynchronously, the MessageLoop is already - // ready to accept tasks and as such this BrowserThreadImpl is considered as - // "running". DCHECK_GE(identifier_, 0); DCHECK_LT(identifier_, ID_COUNT); - DCHECK(!globals.task_runners[identifier_]); - globals.task_runners[identifier_] = this->task_runner(); - DCHECK(globals.task_runners[identifier_]); - DCHECK_EQ(globals.states[identifier_], WebThreadState::INITIALIZED); + DCHECK_EQ(globals.states[identifier_], WebThreadState::UNINITIALIZED); globals.states[identifier_] = WebThreadState::RUNNING; - return result; + DCHECK(!globals.task_runners[identifier_]); + globals.task_runners[identifier_] = std::move(task_runner); } -bool WebThreadImpl::StartAndWaitForTesting() { - if (!Start()) - return false; - WaitUntilThreadStarted(); - return true; -} - -void WebThreadImpl::Run(base::RunLoop* run_loop) { - WebThread::ID thread_id = ID_COUNT; - if (!GetCurrentThreadIdentifier(&thread_id)) - return Thread::Run(run_loop); - - switch (thread_id) { - case WebThread::UI: - return UIThreadRun(run_loop); - case WebThread::IO: - return IOThreadRun(run_loop); - case WebThread::ID_COUNT: - CHECK(false); // This shouldn't actually be reached! - break; - } - Thread::Run(run_loop); -} - -void WebThreadImpl::CleanUp() { +WebThreadImpl::~WebThreadImpl() { WebThreadGlobals& globals = g_globals.Get(); - - if (identifier_ == WebThread::IO) { - WebThreadDelegateAtomicPtr delegate = - base::subtle::NoBarrier_Load(&globals.io_thread_delegate); - if (delegate) - reinterpret_cast<WebThreadDelegate*>(delegate)->CleanUp(); - } - - // Change the state to SHUTDOWN so that PostTaskHelper stops accepting tasks - // for this thread. Do not clear globals.task_runners[identifier_] so that - // WebThread::CurrentlyOn() works from the MessageLoop's - // DestructionObservers. base::AutoLock lock(globals.lock); + DCHECK_EQ(globals.states[identifier_], WebThreadState::RUNNING); globals.states[identifier_] = WebThreadState::SHUTDOWN; } -void WebThreadImpl::Initialize() { - WebThreadGlobals& globals = g_globals.Get(); - - base::AutoLock lock(globals.lock); - DCHECK_GE(identifier_, 0); - DCHECK_LT(identifier_, ID_COUNT); - DCHECK_EQ(globals.states[identifier_], WebThreadState::UNINITIALIZED); - DCHECK(globals.task_runners[identifier_] == nullptr); - globals.states[identifier_] = WebThreadState::INITIALIZED; -} - // static void WebThreadImpl::ResetGlobalsForTesting(WebThread::ID identifier) { WebThreadGlobals& globals = g_globals.Get(); + base::AutoLock lock(globals.lock); DCHECK_EQ(globals.states[identifier], WebThreadState::SHUTDOWN); globals.states[identifier] = WebThreadState::UNINITIALIZED; globals.task_runners[identifier] = nullptr; - if (identifier == WebThread::IO) - SetIOThreadDelegate(nullptr); } -WebThreadImpl::~WebThreadImpl() { - // All Thread subclasses must call Stop() in the destructor. This is - // doubly important here as various bits of code check they are on - // the right WebThread. - Stop(); +// Friendly names for the well-known threads. - WebThreadGlobals& globals = g_globals.Get(); - base::AutoLock lock(globals.lock); - // This thread should have gone through Cleanup() as part of Stop() and be in - // the SHUTDOWN state already (unless it uses an externally provided - // MessageLoop instead of a real underlying thread and thus doesn't go through - // Cleanup()). - if (using_external_message_loop()) { - DCHECK_EQ(globals.states[identifier_], WebThreadState::RUNNING); - globals.states[identifier_] = WebThreadState::SHUTDOWN; - } else { - DCHECK_EQ(globals.states[identifier_], WebThreadState::SHUTDOWN); - } - globals.task_runners[identifier_] = nullptr; -#if DCHECK_IS_ON() - // Double check that the threads are ordered correctly in the enumeration. - for (int i = identifier_ + 1; i < ID_COUNT; ++i) { - DCHECK(globals.states[i] == WebThreadState::SHUTDOWN || - globals.states[i] == WebThreadState::UNINITIALIZED) - << "Threads must be listed in the reverse order that they die"; - DCHECK(!globals.task_runners[i]) - << "Threads must be listed in the reverse order that they die"; - } -#endif // DCHECK_IS_ON() +// static +const char* WebThreadImpl::GetThreadName(WebThread::ID thread) { + static const char* const kWebThreadNames[WebThread::ID_COUNT] = { + "Web_UIThread", // UI + "Web_IOThread", // IO + }; + + if (WebThread::UI <= thread && thread < WebThread::ID_COUNT) + return kWebThreadNames[thread]; + return "Unknown Thread"; } // static @@ -425,8 +274,7 @@ base::AutoLock lock(globals.lock); DCHECK_GE(identifier, 0); DCHECK_LT(identifier, ID_COUNT); - return globals.states[identifier] == WebThreadState::INITIALIZED || - globals.states[identifier] == WebThreadState::RUNNING; + return globals.states[identifier] == WebThreadState::RUNNING; } // static @@ -446,7 +294,7 @@ actual_name = "Unknown Thread"; std::string result = "Must be called on "; - result += GetThreadName(expected); + result += WebThreadImpl::GetThreadName(expected); result += "; actually called on "; result += actual_name; result += "."; @@ -478,19 +326,6 @@ } // static -void WebThread::SetIOThreadDelegate(WebThreadDelegate* delegate) { - using base::subtle::AtomicWord; - WebThreadGlobals& globals = g_globals.Get(); - WebThreadDelegateAtomicPtr old_delegate = - base::subtle::NoBarrier_AtomicExchange( - &globals.io_thread_delegate, - reinterpret_cast<WebThreadDelegateAtomicPtr>(delegate)); - - // This catches registration when previously registered. - DCHECK(!delegate || !old_delegate); -} - -// static void WebThreadImpl::CreateTaskExecutor() { DCHECK(!g_web_thread_task_executor); g_web_thread_task_executor = new WebThreadTaskExecutor();
diff --git a/ios/web/web_thread_impl.h b/ios/web/web_thread_impl.h index e695139d..b0a2c61 100644 --- a/ios/web/web_thread_impl.h +++ b/ios/web/web_thread_impl.h
@@ -6,28 +6,30 @@ #define IOS_WEB_WEB_THREAD_IMPL_H_ #include "base/callback.h" +#include "base/memory/scoped_refptr.h" #include "base/threading/thread.h" #include "ios/web/public/web_thread.h" namespace web { -class WebTestSuiteListener; +class TestWebThread; +class WebMainLoop; +class WebSubThread; -class WebThreadImpl : public WebThread, public base::Thread { +// WebThreadImpl is a scoped object which maps a SingleThreadTaskRunner to a +// WebThread::ID. On ~WebThreadImpl() that ID enters a SHUTDOWN state +// (in which WebThread::IsThreadInitialized() returns false) but the mapping +// isn't undone to avoid shutdown races (the task runner is free to stop +// accepting tasks however). +// +// Very few users should use this directly. To mock WebThreads, tests should +// use TestWebThreadBundle instead. +class WebThreadImpl : public WebThread { public: - // Construct a WebThreadImpl with the supplied identifier. It is an error - // to construct a WebThreadImpl that already exists. - explicit WebThreadImpl(WebThread::ID identifier); + ~WebThreadImpl(); - // Special constructor for the main (UI) thread and unittests. If a - // |message_loop| is provied, we use a dummy thread here since the main - // thread already exists. - WebThreadImpl(WebThread::ID identifier, base::MessageLoop* message_loop); - ~WebThreadImpl() override; - - bool Start(); - bool StartWithOptions(const Options& options); - bool StartAndWaitForTesting(); + // Returns the thread name for |identifier|. + static const char* GetThreadName(WebThread::ID identifier); // Creates and registers a TaskExecutor that facilitates posting tasks to a // WebThread via //base/task/post_task.h. @@ -46,29 +48,19 @@ // Also unregisters and deletes the TaskExecutor. static void ResetGlobalsForTesting(WebThread::ID identifier); - protected: - void Init() override; - void Run(base::RunLoop* run_loop) override; - void CleanUp() override; - private: - // This class implements all the functionality of the public WebThread - // functions, but state is stored in the WebThreadImpl to keep - // the API cleaner. Therefore make WebThread a friend class. - friend class WebThread; + // Restrict instantiation to WebSubThread as it performs important + // initialization that shouldn't be bypassed (except by WebMainLoop for + // the main thread). + friend class WebSubThread; + friend class WebMainLoop; + // TestWebThread is also allowed to construct this when instantiating fake + // threads. + friend class TestWebThread; - // The following are unique function names that makes it possible to tell - // the thread id from the callstack alone in crash dumps. - void UIThreadRun(base::RunLoop* run_loop); - void IOThreadRun(base::RunLoop* run_loop); - - // Common initialization code for the constructors. - void Initialize(); - - // For testing. - friend class TestWebThreadBundle; - friend class TestWebThreadBundleImpl; - friend class WebTestSuiteListener; + // Binds |identifier| to |task_runner| for the web_thread.h API. + WebThreadImpl(WebThread::ID identifier, + scoped_refptr<base::SingleThreadTaskRunner> task_runner); // The identifier of this thread. Only one thread can exist with a given // identifier at a given time.
diff --git a/mash/BUILD.gn b/mash/BUILD.gn index b9aa26a..d1773fbf 100644 --- a/mash/BUILD.gn +++ b/mash/BUILD.gn
@@ -13,7 +13,6 @@ testonly = true deps = [ - ":mash_catalog", "//components/services/leveldb", "//mash/catalog_viewer", "//mash/example", @@ -36,16 +35,14 @@ standalone_services = [ "//components/services/leveldb:manifest", "//mash/catalog_viewer:manifest", + "//mash/example/views_examples:manifest", + "//mash/example/window_type_launcher:manifest", "//mash/session:manifest", "//mash/task_viewer:manifest", "//services/ws/ime/test_ime_driver:manifest", "//services/viz:manifest", ] - executable_overrides = [ "content_packaged_services:@EXE_DIR/chrome" ] - - catalog_deps = [ "//mash/example:catalog" ] - if (is_chromeos) { standalone_services += [ "//ash:manifest", @@ -65,13 +62,8 @@ } } -copy("mash_catalog") { +catalog_cpp_source("mash_catalog_source") { testonly = true - sources = get_target_outputs(":catalog") - outputs = [ - "$root_out_dir/mash_catalog.json", - ] - deps = [ - ":catalog", - ] + catalog = ":catalog" + generated_function_name = "CreateMashCatalog" }
diff --git a/mash/example/BUILD.gn b/mash/example/BUILD.gn index a210a3c..1e772aae 100644 --- a/mash/example/BUILD.gn +++ b/mash/example/BUILD.gn
@@ -18,10 +18,3 @@ deps += [ "//ash:ash_service" ] } } - -catalog("catalog") { - standalone_services = [ - "//mash/example/views_examples:manifest", - "//mash/example/window_type_launcher:manifest", - ] -}
diff --git a/mash/runner/BUILD.gn b/mash/runner/BUILD.gn index 4cb3030c..a82a207 100644 --- a/mash/runner/BUILD.gn +++ b/mash/runner/BUILD.gn
@@ -13,13 +13,10 @@ "//base", "//base:i18n", "//base/test:test_support", + "//mash:mash_catalog_source", "//mojo/core/embedder", "//services/service_manager", "//services/service_manager/runner:init", "//services/service_manager/standalone", ] - - data_deps = [ - "//mash:mash_catalog", - ] }
diff --git a/mash/runner/main.cc b/mash/runner/main.cc index 68e56a3..e08d303 100644 --- a/mash/runner/main.cc +++ b/mash/runner/main.cc
@@ -25,19 +25,13 @@ #include "base/threading/platform_thread.h" #include "base/threading/thread.h" #include "build/build_config.h" +#include "mash/mash_catalog_source.h" #include "mojo/core/embedder/embedder.h" #include "mojo/core/embedder/scoped_ipc_support.h" #include "services/service_manager/runner/init.h" #include "services/service_manager/standalone/context.h" #include "services/service_manager/switches.h" -namespace { - -const base::FilePath::CharType kMashCatalogFilename[] = - FILE_PATH_LITERAL("mash_catalog.json"); - -} // namespace - int main(int argc, char** argv) { base::CommandLine::Init(argc, argv); @@ -54,19 +48,11 @@ #endif base::PlatformThread::SetName("service_manager"); - std::string catalog_contents; - base::FilePath exe_path; - base::PathService::Get(base::DIR_EXE, &exe_path); - base::FilePath catalog_path = exe_path.Append(kMashCatalogFilename); - bool result = base::ReadFileToString(catalog_path, &catalog_contents); - DCHECK(result); - std::unique_ptr<base::Value> manifest_value = - base::JSONReader::Read(catalog_contents); - DCHECK(manifest_value); - #if defined(OS_WIN) && defined(COMPONENT_BUILD) // In Windows component builds, ensure that loaded service binaries always // search this exe's dir for DLLs. + base::FilePath exe_path; + base::PathService::Get(base::DIR_EXE, &exe_path); SetDllDirectory(exe_path.value().c_str()); #endif @@ -86,7 +72,7 @@ base::test::ScopedTaskEnvironment scoped_task_environment; service_manager::Context service_manager_context(nullptr, - std::move(manifest_value)); + CreateMashCatalog()); base::RunLoop loop; scoped_task_environment.GetMainThreadTaskRunner()->PostTask( FROM_HERE,
diff --git a/media/capture/video/linux/camera_config_chromeos_unittest.cc b/media/capture/video/linux/camera_config_chromeos_unittest.cc index 4610803..a5f236f 100644 --- a/media/capture/video/linux/camera_config_chromeos_unittest.cc +++ b/media/capture/video/linux/camera_config_chromeos_unittest.cc
@@ -20,12 +20,11 @@ } TEST(CameraConfigChromeOSTest, ParseSuccessfully) { - const char file_name[] = "fake_camera_characteristics.conf"; - base::WriteFile(base::FilePath(file_name), kConfigFileContent, - sizeof(kConfigFileContent)); + base::FilePath conf_path; + ASSERT_TRUE(base::CreateTemporaryFile(&conf_path)); + base::WriteFile(conf_path, kConfigFileContent, sizeof(kConfigFileContent)); - std::string file_name_str(file_name); - CameraConfigChromeOS camera_config(file_name_str); + CameraConfigChromeOS camera_config(conf_path.value()); EXPECT_EQ(VideoFacingMode::MEDIA_VIDEO_FACING_ENVIRONMENT, camera_config.GetCameraFacing(std::string("/dev/video2"), std::string("04f2:b53a")));
diff --git a/media/gpu/windows/d3d11_cdm_proxy_unittest.cc b/media/gpu/windows/d3d11_cdm_proxy_unittest.cc index 00140a8..f4887ece 100644 --- a/media/gpu/windows/d3d11_cdm_proxy_unittest.cc +++ b/media/gpu/windows/d3d11_cdm_proxy_unittest.cc
@@ -145,47 +145,46 @@ DoAll(SetComPointee<7>(device_mock_.Get()), SetComPointeeAndReturnOk<9>(device_context_mock_.Get()))); - ON_CALL(*device_mock_.Get(), QueryInterface(IID_ID3D11VideoDevice, _)) + COM_ON_CALL(device_mock_, QueryInterface(IID_ID3D11VideoDevice, _)) .WillByDefault(SetComPointeeAndReturnOk<1>(video_device_mock_.Get())); - ON_CALL(*device_mock_.Get(), QueryInterface(IID_ID3D11VideoDevice1, _)) + COM_ON_CALL(device_mock_, QueryInterface(IID_ID3D11VideoDevice1, _)) .WillByDefault(SetComPointeeAndReturnOk<1>(video_device1_mock_.Get())); - ON_CALL(*device_mock_.Get(), QueryInterface(IID_IDXGIDevice2, _)) + COM_ON_CALL(device_mock_, QueryInterface(IID_IDXGIDevice2, _)) .WillByDefault(SetComPointeeAndReturnOk<1>(dxgi_device_.Get())); - ON_CALL(*dxgi_device_.Get(), GetParent(IID_IDXGIAdapter3, _)) + COM_ON_CALL(dxgi_device_, GetParent(IID_IDXGIAdapter3, _)) .WillByDefault(SetComPointeeAndReturnOk<1>(dxgi_adapter_.Get())); - ON_CALL(*dxgi_adapter_.Get(), - RegisterHardwareContentProtectionTeardownStatusEvent(_, _)) + COM_ON_CALL(dxgi_adapter_, + RegisterHardwareContentProtectionTeardownStatusEvent(_, _)) .WillByDefault(DoAll(SaveArg<0>(&teardown_event_), Return(S_OK))); - ON_CALL(*device_context_mock_.Get(), - QueryInterface(IID_ID3D11VideoContext, _)) + COM_ON_CALL(device_context_mock_, QueryInterface(IID_ID3D11VideoContext, _)) .WillByDefault(SetComPointeeAndReturnOk<1>(video_context_mock_.Get())); - ON_CALL(*device_context_mock_.Get(), - QueryInterface(IID_ID3D11VideoContext1, _)) + COM_ON_CALL(device_context_mock_, + QueryInterface(IID_ID3D11VideoContext1, _)) .WillByDefault(SetComPointeeAndReturnOk<1>(video_context1_mock_.Get())); - ON_CALL(*video_device_mock_.Get(), - CreateCryptoSession(Pointee(CRYPTO_TYPE_GUID), _, - Pointee(D3D11_KEY_EXCHANGE_HW_PROTECTION), _)) + COM_ON_CALL( + video_device_mock_, + CreateCryptoSession(Pointee(CRYPTO_TYPE_GUID), _, + Pointee(D3D11_KEY_EXCHANGE_HW_PROTECTION), _)) .WillByDefault(SetComPointeeAndReturnOk<3>(crypto_session_mock_.Get())); - ON_CALL( - *video_device1_mock_.Get(), - GetCryptoSessionPrivateDataSize(Pointee(CRYPTO_TYPE_GUID), _, _, _, _)) + COM_ON_CALL(video_device1_mock_, GetCryptoSessionPrivateDataSize( + Pointee(CRYPTO_TYPE_GUID), _, _, _, _)) .WillByDefault(DoAll(SetArgPointee<3>(kPrivateInputSize), SetArgPointee<4>(kPrivateOutputSize), Return(S_OK))); - ON_CALL(*video_device_mock_.Get(), GetContentProtectionCaps(_, _, _)) + COM_ON_CALL(video_device_mock_, GetContentProtectionCaps(_, _, _)) .WillByDefault( DoAll(SetArgPointee<2>(content_protection_caps_), Return(S_OK))); - ON_CALL(*video_device_mock_.Get(), CheckCryptoKeyExchange(_, _, Lt(1u), _)) + COM_ON_CALL(video_device_mock_, CheckCryptoKeyExchange(_, _, Lt(1u), _)) .WillByDefault(DoAll(SetArgPointee<3>(D3D11_KEY_EXCHANGE_HW_PROTECTION), Return(S_OK))); } @@ -195,35 +194,35 @@ void Initialize(CdmProxy::Client* client, CdmProxy::InitializeCB callback) { EXPECT_CALL(create_device_mock_, Create(_, D3D_DRIVER_TYPE_HARDWARE, _, _, _, _, _, _, _, _)); - EXPECT_CALL(*device_mock_.Get(), QueryInterface(IID_ID3D11VideoDevice, _)) + COM_EXPECT_CALL(device_mock_, QueryInterface(IID_ID3D11VideoDevice, _)) .Times(AtLeast(1)); - EXPECT_CALL(*device_mock_.Get(), QueryInterface(IID_IDXGIDevice2, _)) + COM_EXPECT_CALL(device_mock_, QueryInterface(IID_IDXGIDevice2, _)) .Times(AtLeast(1)); - EXPECT_CALL(*dxgi_device_.Get(), GetParent(IID_IDXGIAdapter3, _)) + COM_EXPECT_CALL(dxgi_device_, GetParent(IID_IDXGIAdapter3, _)) .Times(AtLeast(1)); - EXPECT_CALL(*dxgi_adapter_.Get(), - RegisterHardwareContentProtectionTeardownStatusEvent(_, _)) + COM_EXPECT_CALL(dxgi_adapter_, + RegisterHardwareContentProtectionTeardownStatusEvent(_, _)) .Times(AtLeast(1)); - EXPECT_CALL(*device_mock_.Get(), QueryInterface(IID_ID3D11VideoDevice1, _)) + COM_EXPECT_CALL(device_mock_, QueryInterface(IID_ID3D11VideoDevice1, _)) .Times(AtLeast(1)); - EXPECT_CALL(*device_context_mock_.Get(), - QueryInterface(IID_ID3D11VideoContext, _)) + COM_EXPECT_CALL(device_context_mock_, + QueryInterface(IID_ID3D11VideoContext, _)) .Times(AtLeast(1)); - EXPECT_CALL(*device_context_mock_.Get(), - QueryInterface(IID_ID3D11VideoContext1, _)) + COM_EXPECT_CALL(device_context_mock_, + QueryInterface(IID_ID3D11VideoContext1, _)) .Times(AtLeast(1)); - EXPECT_CALL( - *video_device_mock_.Get(), + COM_EXPECT_CALL( + video_device_mock_, CreateCryptoSession(Pointee(CRYPTO_TYPE_GUID), _, Pointee(D3D11_KEY_EXCHANGE_HW_PROTECTION), _)); - EXPECT_CALL( - *video_device1_mock_.Get(), + COM_EXPECT_CALL( + video_device1_mock_, GetCryptoSessionPrivateDataSize(Pointee(CRYPTO_TYPE_GUID), _, _, _, _)); - EXPECT_CALL(*video_device_mock_.Get(), GetContentProtectionCaps(_, _, _)); + COM_EXPECT_CALL(video_device_mock_, GetContentProtectionCaps(_, _, _)); - EXPECT_CALL(*video_device_mock_.Get(), - CheckCryptoKeyExchange(_, _, Lt(1u), _)); + COM_EXPECT_CALL(video_device_mock_, + CheckCryptoKeyExchange(_, _, Lt(1u), _)); proxy_->Initialize(client, std::move(callback)); @@ -316,8 +315,8 @@ EXPECT_CALL(callback_mock_, InitializeCallback(CdmProxy::Status::kFail, _, _)); - EXPECT_CALL(*dxgi_adapter_.Get(), - RegisterHardwareContentProtectionTeardownStatusEvent(_, _)) + COM_EXPECT_CALL(dxgi_adapter_, + RegisterHardwareContentProtectionTeardownStatusEvent(_, _)) .Times(AtLeast(1)) .WillRepeatedly(Return(E_FAIL)); @@ -359,8 +358,7 @@ InitializeCallback(CdmProxy::Status::kFail, _, _)); // GUID is set to non-D3D11_KEY_EXCHANGE_HW_PROTECTION, which means no HW key // exchange. - EXPECT_CALL(*video_device_mock_.Get(), - CheckCryptoKeyExchange(_, _, Lt(1u), _)) + COM_EXPECT_CALL(video_device_mock_, CheckCryptoKeyExchange(_, _, Lt(1u), _)) .WillOnce( DoAll(SetArgPointee<3>(D3D11_CRYPTO_TYPE_AES128_CTR), Return(S_OK))); @@ -532,11 +530,11 @@ test_output_data.size()); }; - EXPECT_CALL(*video_context_mock_.Get(), - NegotiateCryptoSessionKeyExchange( - _, sizeof(expected_key_exchange_data), - MatchesKeyExchangeStructure(&expected_key_exchange_data, - input_structure_size))) + COM_EXPECT_CALL(video_context_mock_, + NegotiateCryptoSessionKeyExchange( + _, sizeof(expected_key_exchange_data), + MatchesKeyExchangeStructure(&expected_key_exchange_data, + input_structure_size))) .WillOnce(DoAll(WithArgs<2>(Invoke(set_test_output_data)), Return(S_OK))); proxy_->Process(kTestFunction, crypto_session_id, kAnyInput, @@ -571,16 +569,16 @@ CdmProxy::Status::kOk, Ne(crypto_session_id_from_initialize), _)); auto media_crypto_session_mock = CreateD3D11Mock<D3D11CryptoSessionMock>(); - EXPECT_CALL(*video_device_mock_.Get(), - CreateCryptoSession(Pointee(CRYPTO_TYPE_GUID), _, - Pointee(CRYPTO_TYPE_GUID), _)) + COM_EXPECT_CALL(video_device_mock_, + CreateCryptoSession(Pointee(CRYPTO_TYPE_GUID), _, + Pointee(CRYPTO_TYPE_GUID), _)) .WillOnce(SetComPointeeAndReturnOk<3>(media_crypto_session_mock.Get())); - EXPECT_CALL(*video_context1_mock_.Get(), GetDataForNewHardwareKey(_, _, _, _)) + COM_EXPECT_CALL(video_context1_mock_, GetDataForNewHardwareKey(_, _, _, _)) .Times(0); - EXPECT_CALL(*video_context1_mock_.Get(), - CheckCryptoSessionStatus(media_crypto_session_mock.Get(), _)) + COM_EXPECT_CALL(video_context1_mock_, + CheckCryptoSessionStatus(media_crypto_session_mock.Get(), _)) .WillOnce(DoAll(SetArgPointee<1>(D3D11_CRYPTO_SESSION_STATUS_OK), Return(S_OK))); proxy_->CreateMediaCryptoSession( @@ -619,21 +617,21 @@ Ne(crypto_session_id_from_initialize), _)); auto media_crypto_session_mock = CreateD3D11Mock<D3D11CryptoSessionMock>(); - EXPECT_CALL(*video_device_mock_.Get(), - CreateCryptoSession(Pointee(CRYPTO_TYPE_GUID), _, - Pointee(CRYPTO_TYPE_GUID), _)) + COM_EXPECT_CALL(video_device_mock_, + CreateCryptoSession(Pointee(CRYPTO_TYPE_GUID), _, + Pointee(CRYPTO_TYPE_GUID), _)) .WillOnce(SetComPointeeAndReturnOk<3>(media_crypto_session_mock.Get())); // The size nor value here matter, so making non empty non zero vector. const std::vector<uint8_t> kAnyInput(16, 0xFF); const uint64_t kAnyOutputData = 23298u; - EXPECT_CALL(*video_context1_mock_.Get(), - GetDataForNewHardwareKey(media_crypto_session_mock.Get(), - kAnyInput.size(), - CastedToUint8Are(kAnyInput), _)) + COM_EXPECT_CALL(video_context1_mock_, + GetDataForNewHardwareKey(media_crypto_session_mock.Get(), + kAnyInput.size(), + CastedToUint8Are(kAnyInput), _)) .WillOnce(DoAll(SetArgPointee<3>(kAnyOutputData), Return(S_OK))); - EXPECT_CALL(*video_context1_mock_.Get(), - CheckCryptoSessionStatus(media_crypto_session_mock.Get(), _)) + COM_EXPECT_CALL(video_context1_mock_, + CheckCryptoSessionStatus(media_crypto_session_mock.Get(), _)) .WillOnce(DoAll(SetArgPointee<1>(D3D11_CRYPTO_SESSION_STATUS_OK), Return(S_OK))); proxy_->CreateMediaCryptoSession( @@ -674,9 +672,7 @@ base::Unretained(&callback_mock_)))); Mock::VerifyAndClearExpectations(&callback_mock_); - const std::vector<uint8_t> kAnyBlob = { - 0x01, 0x4f, 0x83, - }; + const std::vector<uint8_t> kAnyBlob = {0x01, 0x4f, 0x83}; EXPECT_CALL(callback_mock_, SetKeyCallback(CdmProxy::Status::kOk)); proxy_->SetKey(crypto_session_id_from_initialize, kAnyBlob,
diff --git a/media/gpu/windows/d3d11_decryptor_unittest.cc b/media/gpu/windows/d3d11_decryptor_unittest.cc index 75b4041..134e9b5 100644 --- a/media/gpu/windows/d3d11_decryptor_unittest.cc +++ b/media/gpu/windows/d3d11_decryptor_unittest.cc
@@ -172,11 +172,11 @@ .WillRepeatedly(SetComPointee<0>(device_mock_.Get())); // The other components accessible (directly or indirectly) from the device. - EXPECT_CALL(*device_mock_.Get(), GetImmediateContext(_)) + COM_EXPECT_CALL(device_mock_, GetImmediateContext(_)) .Times(AtLeast(1)) .WillRepeatedly(SetComPointee<0>(device_context_mock_.Get())); - EXPECT_CALL(*device_context_mock_.Get(), - QueryInterface(IID_ID3D11VideoContext, _)) + COM_EXPECT_CALL(device_context_mock_, + QueryInterface(IID_ID3D11VideoContext, _)) .Times(AtLeast(1)) .WillRepeatedly(SetComPointeeAndReturnOk<1>(video_context_mock_.Get())); @@ -185,29 +185,29 @@ .WillOnce(Return(*decrypt_context)); // These return big enough size. - ON_CALL(*staging_buffer1_.Get(), GetDesc(_)) + COM_ON_CALL(staging_buffer1_, GetDesc(_)) .WillByDefault(SetBufferDescSize(20000)); - ON_CALL(*staging_buffer2_.Get(), GetDesc(_)) + COM_ON_CALL(staging_buffer2_, GetDesc(_)) .WillByDefault(SetBufferDescSize(20000)); - ON_CALL(*gpu_buffer_.Get(), GetDesc(_)) + COM_ON_CALL(gpu_buffer_, GetDesc(_)) .WillByDefault(SetBufferDescSize(20000)); // It should be requesting for 2 staging buffers one for writing the data to // a GPU buffer and one for reading from the a GPU buffer. - EXPECT_CALL(*device_mock_.Get(), - CreateBuffer(BufferDescHas(D3D11_USAGE_STAGING, 0u, - D3D11_CPU_ACCESS_READ | - D3D11_CPU_ACCESS_WRITE), - nullptr, _)) + COM_EXPECT_CALL(device_mock_, + CreateBuffer(BufferDescHas(D3D11_USAGE_STAGING, 0u, + D3D11_CPU_ACCESS_READ | + D3D11_CPU_ACCESS_WRITE), + nullptr, _)) .WillOnce(SetComPointeeAndReturnOk<2>(staging_buffer1_.Get())) .WillOnce(SetComPointeeAndReturnOk<2>(staging_buffer2_.Get())); // It should be requesting a GPU only accessible buffer to the decrypted // output. - EXPECT_CALL(*device_mock_.Get(), - CreateBuffer(BufferDescHas(D3D11_USAGE_DEFAULT, - D3D11_BIND_RENDER_TARGET, 0u), - nullptr, _)) + COM_EXPECT_CALL(device_mock_, + CreateBuffer(BufferDescHas(D3D11_USAGE_DEFAULT, + D3D11_BIND_RENDER_TARGET, 0u), + nullptr, _)) .WillOnce(SetComPointeeAndReturnOk<2>(gpu_buffer_.Get())); } @@ -232,22 +232,22 @@ // It should be requesting for a memory mapped buffer, from the staging // buffer, to pass the encrypted data to the GPU. - EXPECT_CALL(*device_context_mock_.Get(), - Map(staging_buffer1_.Get(), 0, D3D11_MAP_WRITE, _, _)) + COM_EXPECT_CALL(device_context_mock_, + Map(staging_buffer1_.Get(), 0, D3D11_MAP_WRITE, _, _)) .WillOnce( DoAll(SetArgPointee<4>(staging_buffer1_subresource), Return(S_OK))); - EXPECT_CALL(*device_context_mock_.Get(), Unmap(staging_buffer1_.Get(), 0)); + COM_EXPECT_CALL(device_context_mock_, Unmap(staging_buffer1_.Get(), 0)); - EXPECT_CALL( - *video_context_mock_.Get(), + COM_EXPECT_CALL( + video_context_mock_, DecryptionBlt( crypto_session_mock, reinterpret_cast<ID3D11Texture2D*>(staging_buffer1_.Get()), reinterpret_cast<ID3D11Texture2D*>(gpu_buffer_.Get()), NumEncryptedBytesAtBeginningGreaterOrEq(encrypted_input.size()), sizeof(kAnyKeyBlob), kAnyKeyBlob, _, _)); - EXPECT_CALL(*device_context_mock_.Get(), - CopyResource(staging_buffer2_.Get(), gpu_buffer_.Get())); + COM_EXPECT_CALL(device_context_mock_, + CopyResource(staging_buffer2_.Get(), gpu_buffer_.Get())); D3D11_MAPPED_SUBRESOURCE staging_buffer2_subresource = {}; @@ -261,11 +261,11 @@ // Tt should be requesting for a memory mapped buffer, from the staging // buffer, to read the decrypted data out from the GPU buffer. - EXPECT_CALL(*device_context_mock_.Get(), - Map(staging_buffer2_.Get(), 0, D3D11_MAP_READ, _, _)) + COM_EXPECT_CALL(device_context_mock_, + Map(staging_buffer2_.Get(), 0, D3D11_MAP_READ, _, _)) .WillOnce( DoAll(SetArgPointee<4>(staging_buffer2_subresource), Return(S_OK))); - EXPECT_CALL(*device_context_mock_.Get(), Unmap(staging_buffer2_.Get(), 0)); + COM_EXPECT_CALL(device_context_mock_, Unmap(staging_buffer2_.Get(), 0)); CallbackMock callbacks; EXPECT_CALL(callbacks, @@ -499,7 +499,7 @@ Mock::VerifyAndClearExpectations(device_context_mock_.Get()); Mock::VerifyAndClearExpectations(&mock_proxy_); - EXPECT_CALL(*crypto_session_mock.Get(), GetDevice(_)) + COM_EXPECT_CALL(crypto_session_mock, GetDevice(_)) .Times(AtLeast(1)) .WillRepeatedly(SetComPointee<0>(device_mock_.Get())); EXPECT_CALL(mock_proxy_, @@ -508,7 +508,7 @@ // Buffers should not be (re)initialized on the next call to decrypt because // it's the same device as the previous call. - EXPECT_CALL(*device_mock_.Get(), CreateBuffer(_, _, _)).Times(0); + COM_EXPECT_CALL(device_mock_, CreateBuffer(_, _, _)).Times(0); // This calls Decrypt() so that the expectations above are triggered. ExpectSuccessfulDecryption(crypto_session_mock.Get(), kAnyInput, kAnyInput,
diff --git a/media/gpu/windows/d3d11_mocks.h b/media/gpu/windows/d3d11_mocks.h index 69d70a48..6c4d01b 100644 --- a/media/gpu/windows/d3d11_mocks.h +++ b/media/gpu/windows/d3d11_mocks.h
@@ -44,11 +44,17 @@ #define MOCK_STDCALL_METHOD9(Name, Types) \ MOCK_METHOD9_WITH_CALLTYPE(STDMETHODCALLTYPE, Name, Types) +// Helper ON_CALL and EXPECT_CALL for Microsoft::WRL::ComPtr, e.g. +// COM_EXPECT_CALL(foo_, Bar()); +// where |foo_| is ComPtr<D3D11FooMock>. +#define COM_ON_CALL(obj, call) ON_CALL(*obj.Get(), call) +#define COM_EXPECT_CALL(obj, call) EXPECT_CALL(*obj.Get(), call) + namespace media { // Use this action when using SetArgPointee with COM pointers. // e.g. -// EXPECT_CALL(*device_mock_.Get(), QueryInterface(IID_ID3D11VideoDevice, _)) +// COM_EXPECT_CALL(device_mock_, QueryInterface(IID_ID3D11VideoDevice, _)) // .WillRepeatedly(DoAll( // SetComPointee<1>(video_device_mock_.Get()), Return(S_OK))); ACTION_TEMPLATE(SetComPointee, @@ -60,7 +66,7 @@ // Same as above, but returns S_OK for convenience. // e.g. -// EXPECT_CALL(*device_mock_.Get(), QueryInterface(IID_ID3D11VideoDevice, _)) +// COM_EXPECT_CALL(device_mock_, QueryInterface(IID_ID3D11VideoDevice, _)) // .WillRepeatedly(SetComPointeeAndReturnOk<1>(video_device_mock_.Get())); ACTION_TEMPLATE(SetComPointeeAndReturnOk, HAS_1_TEMPLATE_PARAMS(int, k),
diff --git a/media/video/gpu_video_accelerator_factories.h b/media/video/gpu_video_accelerator_factories.h index 63b8f37..a4328d37 100644 --- a/media/video/gpu_video_accelerator_factories.h +++ b/media/video/gpu_video_accelerator_factories.h
@@ -81,6 +81,8 @@ // Return true if |config| is potentially supported by a decoder created with // CreateVideoDecoder(). + // + // May be called on any thread. virtual bool IsDecoderConfigSupported(const VideoDecoderConfig& config) = 0; virtual std::unique_ptr<media::VideoDecoder> CreateVideoDecoder(
diff --git a/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc b/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc index 03e3747c1..7dbcc87 100644 --- a/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc +++ b/sandbox/linux/seccomp-bpf-helpers/syscall_sets.cc
@@ -100,7 +100,7 @@ case __NR_stat: // EPERM not a valid errno. case __NR_symlink: case __NR_unlink: -#if !defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_64_BITS) +#if !(defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_64_BITS)) case __NR_uselib: // Neither EPERM, nor ENOENT are valid errno. #endif case __NR_ustat: // Same as above. Deprecated. @@ -483,7 +483,7 @@ // Big multiplexing system call for sockets. bool SyscallSets::IsSocketCall(int sysno) { switch (sysno) { -#if !defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_64_BITS) +#if !(defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_64_BITS)) case __NR_socketcall: return true; #endif @@ -881,7 +881,7 @@ // Big system V multiplexing system call. bool SyscallSets::IsSystemVIpc(int sysno) { switch (sysno) { -#if !defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_64_BITS) +#if !(defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_64_BITS)) case __NR_ipc: return true; #endif @@ -1090,7 +1090,7 @@ bool SyscallSets::IsMipsMisc(int sysno) { switch (sysno) { case __NR_sysmips: -#if !defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_64_BITS) +#if !(defined(ARCH_CPU_MIPS_FAMILY) && defined(ARCH_CPU_64_BITS)) case __NR_unused150: #endif return true;
diff --git a/services/audio/BUILD.gn b/services/audio/BUILD.gn index 575bcab..f6012237 100644 --- a/services/audio/BUILD.gn +++ b/services/audio/BUILD.gn
@@ -223,6 +223,7 @@ service_manifest("standalone_unittest_manifest") { name = "audio_unittests" source = "test/service_unittest_manifest.json" + generated_namespace = "standalone_audio_unittest" } catalog("standalone_unittest_catalog") {
diff --git a/services/catalog/BUILD.gn b/services/catalog/BUILD.gn index c35b58a..07cfd90 100644 --- a/services/catalog/BUILD.gn +++ b/services/catalog/BUILD.gn
@@ -2,7 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//services/service_manager/public/service_manifest.gni") import("//testing/test.gni") group("catalog") { @@ -31,7 +30,6 @@ "entry_cache.h", "instance.cc", "instance.h", - "manifest_provider.h", "service_options.h", ] @@ -55,24 +53,3 @@ defines = [ "IS_CATALOG_IMPL" ] } - -service_manifest("manifest") { - name = "catalog" - source = "manifest.json" -} - -source_set("unittests") { - testonly = true - sources = [ - "entry_unittest.cc", - ] - data = [ - "//services/catalog/test_data/", - ] - deps = [ - ":lib", - "//base", - "//services/service_manager/public/cpp", - "//testing/gtest", - ] -}
diff --git a/services/catalog/catalog.cc b/services/catalog/catalog.cc index 6931cf8..2d1d21ff 100644 --- a/services/catalog/catalog.cc +++ b/services/catalog/catalog.cc
@@ -32,87 +32,11 @@ namespace { -const char kCatalogServicesKey[] = "services"; -const char kCatalogServiceEmbeddedKey[] = "embedded"; -const char kCatalogServiceExecutableKey[] = "executable"; -const char kCatalogServiceManifestKey[] = "manifest"; - std::vector<service_manager::Manifest>& GetDefaultManifests() { static base::NoDestructor<std::vector<service_manager::Manifest>> manifests; return *manifests; } -void LoadCatalogManifestIntoCache(const base::Value* root, EntryCache* cache) { - DCHECK(root); - const base::DictionaryValue* catalog = nullptr; - if (!root->GetAsDictionary(&catalog)) { - LOG(ERROR) << "Catalog manifest is not a dictionary value."; - return; - } - DCHECK(catalog); - - const base::DictionaryValue* services = nullptr; - if (!catalog->GetDictionary(kCatalogServicesKey, &services)) { - LOG(ERROR) << "Catalog manifest \"services\" is not a dictionary value."; - return; - } - - for (base::DictionaryValue::Iterator it(*services); !it.IsAtEnd(); - it.Advance()) { - const base::DictionaryValue* service_entry = nullptr; - if (!it.value().GetAsDictionary(&service_entry)) { - LOG(ERROR) << "Catalog service entry for \"" << it.key() - << "\" is not a dictionary value."; - continue; - } - - bool is_embedded = false; - service_entry->GetBoolean(kCatalogServiceEmbeddedKey, &is_embedded); - - base::FilePath executable_path; - std::string executable_path_string; - if (service_entry->GetString(kCatalogServiceExecutableKey, - &executable_path_string)) { - base::FilePath exe_dir; - CHECK(base::PathService::Get(base::DIR_EXE, &exe_dir)); -#if defined(OS_WIN) - executable_path_string += ".exe"; - base::ReplaceFirstSubstringAfterOffset( - &executable_path_string, 0, "@EXE_DIR", - base::UTF16ToUTF8(exe_dir.value())); - executable_path = - base::FilePath(base::UTF8ToUTF16(executable_path_string)); -#else - base::ReplaceFirstSubstringAfterOffset( - &executable_path_string, 0, "@EXE_DIR", exe_dir.value()); - executable_path = base::FilePath(executable_path_string); -#endif - } - - const base::DictionaryValue* manifest = nullptr; - if (!service_entry->GetDictionary(kCatalogServiceManifestKey, &manifest)) { - LOG(ERROR) << "Catalog entry for \"" << it.key() << "\" has an invalid " - << "\"manifest\" value."; - continue; - } - - DCHECK(!(is_embedded && !executable_path.empty())); - - if (is_embedded) - executable_path = base::CommandLine::ForCurrentProcess()->GetProgram(); - - auto entry = Entry::Deserialize(*manifest); - if (entry) { - if (!executable_path.empty()) - entry->set_path(std::move(executable_path)); - bool added = cache->AddRootEntry(std::move(entry)); - DCHECK(added); - } else { - LOG(ERROR) << "Failed to read manifest entry for \"" << it.key() << "\"."; - } - } -} - } // namespace // Wraps state needed for servicing directory requests on a separate thread. @@ -143,13 +67,8 @@ DISALLOW_COPY_AND_ASSIGN(DirectoryThreadState); }; -Catalog::Catalog(std::unique_ptr<base::Value> catalog_contents, - const std::vector<service_manager::Manifest>& manifests, - ManifestProvider* service_manifest_provider) - : service_manifest_provider_(service_manifest_provider) { - if (catalog_contents) { - LoadCatalogManifestIntoCache(catalog_contents.get(), &system_cache_); - } else if (!manifests.empty()) { +Catalog::Catalog(const std::vector<service_manager::Manifest>& manifests) { + if (!manifests.empty()) { for (const auto& manifest : manifests) system_cache_.AddRootEntryFromManifest(manifest); } else { @@ -181,9 +100,8 @@ if (it != instances_.end()) return it->second.get(); - auto result = instances_.emplace( - instance_group, - std::make_unique<Instance>(&system_cache_, service_manifest_provider_)); + auto result = instances_.emplace(instance_group, + std::make_unique<Instance>(&system_cache_)); return result.first->second.get(); }
diff --git a/services/catalog/catalog.h b/services/catalog/catalog.h index daa3a42..728dd5a 100644 --- a/services/catalog/catalog.h +++ b/services/catalog/catalog.h
@@ -26,23 +26,18 @@ namespace base { class SequencedTaskRunner; -class Value; } namespace catalog { class Instance; -class ManifestProvider; // Creates and owns an instance of the catalog. Exposes a ServicePtr that // can be passed to the service manager, potentially in a different process. class COMPONENT_EXPORT(CATALOG) Catalog : public service_manager::Service { public: - // Constructs a catalog over a set of Manifests and optionally a - // ManifestProvider for dynamic manifest lookup. - explicit Catalog(std::unique_ptr<base::Value> catalog_contents, - const std::vector<service_manager::Manifest>& manifests, - ManifestProvider* service_manifest_provider = nullptr); + // Constructs a catalog over a set of Manifests to use for lookup. + explicit Catalog(const std::vector<service_manager::Manifest>& manifests); ~Catalog() override; void BindServiceRequest(service_manager::mojom::ServiceRequest request); @@ -79,7 +74,6 @@ const service_manager::BindSourceInfo&> registry_; - ManifestProvider* service_manifest_provider_; EntryCache system_cache_; std::map<base::Token, std::unique_ptr<Instance>> instances_;
diff --git a/services/catalog/entry.cc b/services/catalog/entry.cc index f3884de..c1d438d 100644 --- a/services/catalog/entry.cc +++ b/services/catalog/entry.cc
@@ -5,113 +5,10 @@ #include "services/catalog/entry.h" #include "base/files/file_path.h" -#include "base/path_service.h" -#include "base/values.h" -#include "build/build_config.h" -#include "services/catalog/public/cpp/manifest_parsing_util.h" #include "services/catalog/store.h" #include "services/service_manager/public/mojom/interface_provider_spec.mojom.h" namespace catalog { -namespace { - -#if defined(OS_WIN) -const char kServiceExecutableExtension[] = ".service.exe"; -#else -const char kServiceExecutableExtension[] = ".service"; -#endif - -bool ReadStringSet(const base::ListValue& list_value, - std::set<std::string>* string_set) { - DCHECK(string_set); - for (const auto& value_value : list_value) { - std::string value; - if (!value_value.GetAsString(&value)) { - LOG(ERROR) << "Entry::Deserialize: list member must be a string"; - return false; - } - string_set->insert(std::move(value)); - } - return true; -} - -bool ReadStringSetFromValue(const base::Value& value, - std::set<std::string>* string_set) { - const base::ListValue* list_value = nullptr; - if (!value.GetAsList(&list_value)) { - LOG(ERROR) << "Entry::Deserialize: Value must be a list."; - return false; - } - return ReadStringSet(*list_value, string_set); -} - -// If |key| refers to a dictionary value within |value|, |*out| is set to that -// DictionaryValue. Returns true if either |key| is not present or the -// corresponding value is a dictionary. -bool GetDictionaryValue(const base::DictionaryValue& value, - base::StringPiece key, - const base::DictionaryValue** out) { - const base::Value* entry_value = nullptr; - return !value.Get(key, &entry_value) || entry_value->GetAsDictionary(out); -} - -bool BuildInterfaceProviderSpec( - const base::DictionaryValue& value, - service_manager::InterfaceProviderSpec* interface_provider_specs) { - DCHECK(interface_provider_specs); - const base::DictionaryValue* provides_value = nullptr; - if (!GetDictionaryValue(value, Store::kInterfaceProviderSpecs_ProvidesKey, - &provides_value)) { - LOG(ERROR) << "Entry::Deserialize: " - << Store::kInterfaceProviderSpecs_ProvidesKey - << " must be a dictionary."; - return false; - } - if (provides_value) { - base::DictionaryValue::Iterator it(*provides_value); - for(; !it.IsAtEnd(); it.Advance()) { - service_manager::InterfaceSet interfaces; - if (!ReadStringSetFromValue(it.value(), &interfaces)) { - LOG(ERROR) << "Entry::Deserialize: Invalid interface list in provided " - << " capabilities dictionary"; - return false; - } - interface_provider_specs->provides[it.key()] = std::move(interfaces); - } - } - - const base::DictionaryValue* requires_value = nullptr; - if (!GetDictionaryValue(value, Store::kInterfaceProviderSpecs_RequiresKey, - &requires_value)) { - LOG(ERROR) << "Entry::Deserialize: " - << Store::kInterfaceProviderSpecs_RequiresKey - << " must be a dictionary."; - return false; - } - if (requires_value) { - base::DictionaryValue::Iterator it(*requires_value); - for (; !it.IsAtEnd(); it.Advance()) { - service_manager::CapabilitySet capabilities; - const base::ListValue* entry_value = nullptr; - if (!it.value().GetAsList(&entry_value)) { - LOG(ERROR) << "Entry::Deserialize: " - << Store::kInterfaceProviderSpecs_RequiresKey - << " entry must be a list."; - return false; - } - if (!ReadStringSet(*entry_value, &capabilities)) { - LOG(ERROR) << "Entry::Deserialize: Invalid capabilities list in " - << "requires dictionary."; - return false; - } - - interface_provider_specs->requires[it.key()] = std::move(capabilities); - } - } - return true; -} - -} // namespace Entry::Entry() {} Entry::Entry(const std::string& name) @@ -119,147 +16,6 @@ display_name_(name) {} Entry::~Entry() {} -// static -std::unique_ptr<Entry> Entry::Deserialize(const base::Value& manifest_root) { - const base::DictionaryValue* dictionary_value = nullptr; - if (!manifest_root.GetAsDictionary(&dictionary_value)) - return nullptr; - const base::DictionaryValue& value = *dictionary_value; - - auto entry = std::make_unique<Entry>(); - - // Name. - std::string name; - if (!value.GetString(Store::kNameKey, &name)) { - LOG(ERROR) << "Entry::Deserialize: dictionary has no " - << Store::kNameKey << " key"; - return nullptr; - } - if (name.empty()) { - LOG(ERROR) << "Entry::Deserialize: empty service name."; - return nullptr; - } - entry->set_name(std::move(name)); - - // By default we assume a standalone service executable. The catalog may - // override this layer based on configuration external to the service's own - // manifest. - base::FilePath service_exe_root; - CHECK(base::PathService::Get(base::DIR_ASSETS, &service_exe_root)); - entry->set_path(service_exe_root.AppendASCII(entry->name() + - kServiceExecutableExtension)); - - // Human-readable name. - std::string display_name; - if (!value.GetString(Store::kDisplayNameKey, &display_name)) { - LOG(ERROR) << "Entry::Deserialize: dictionary has no " - << Store::kDisplayNameKey << " key"; - return nullptr; - } - entry->set_display_name(std::move(display_name)); - - // Sandbox type, optional. - std::string sandbox_type; - if (value.GetString(Store::kSandboxTypeKey, &sandbox_type)) - entry->set_sandbox_type(std::move(sandbox_type)); - - // Options, optional. - if (const base::Value* options = value.FindKey(Store::kOptionsKey)) { - ServiceOptions options_struct; - - if (const base::Value* instance_sharing_value = - options->FindKey("instance_sharing")) { - const std::string& instance_sharing = instance_sharing_value->GetString(); - if (instance_sharing == "none") { - options_struct.instance_sharing = - ServiceOptions::InstanceSharingType::NONE; - } else if (instance_sharing == "singleton") { - options_struct.instance_sharing = - ServiceOptions::InstanceSharingType::SINGLETON; - } else if (instance_sharing == "shared_instance_across_users" || - instance_sharing == "shared_across_instance_groups") { - options_struct.instance_sharing = - ServiceOptions::InstanceSharingType::SHARED_ACROSS_INSTANCE_GROUPS; - } else { - LOG(ERROR) << "Entry::Deserialize invalid instance sharing type: " - << instance_sharing; - } - } - - if (const base::Value* can_connect_to_instances_in_any_group = - options->FindKey("can_connect_to_other_services_as_any_user")) { - options_struct.can_connect_to_instances_in_any_group = - can_connect_to_instances_in_any_group->GetBool(); - } - - if (const base::Value* - can_connect_to_other_services_with_any_instance_name_value = - options->FindKey( - "can_connect_to_other_services_with_any_instance_name")) { - options_struct.can_connect_to_other_services_with_any_instance_name = - can_connect_to_other_services_with_any_instance_name_value->GetBool(); - } - - if (const base::Value* can_create_other_service_instances_value = - options->FindKey("can_create_other_service_instances")) { - options_struct.can_create_other_service_instances = - can_create_other_service_instances_value->GetBool(); - } - - entry->AddOptions(std::move(options_struct)); - } - - // InterfaceProvider specs. - const base::DictionaryValue* interface_provider_specs = nullptr; - if (!value.GetDictionary(Store::kInterfaceProviderSpecsKey, - &interface_provider_specs)) { - LOG(ERROR) << "Entry::Deserialize: dictionary has no " - << Store::kInterfaceProviderSpecsKey << " key"; - return nullptr; - } - - base::DictionaryValue::Iterator it(*interface_provider_specs); - for (; !it.IsAtEnd(); it.Advance()) { - const base::DictionaryValue* spec_value = nullptr; - if (!interface_provider_specs->GetDictionary(it.key(), &spec_value)) { - LOG(ERROR) << "Entry::Deserialize: value of InterfaceProvider map for " - << "key: " << it.key() << " not a dictionary."; - return nullptr; - } - - service_manager::InterfaceProviderSpec spec; - if (!BuildInterfaceProviderSpec(*spec_value, &spec)) { - LOG(ERROR) << "Entry::Deserialize: failed to build InterfaceProvider " - << "spec for key: " << it.key(); - return nullptr; - } - entry->AddInterfaceProviderSpec(it.key(), std::move(spec)); - } - - // Required files. - base::Optional<RequiredFileMap> required_files = - catalog::RetrieveRequiredFiles(value); - DCHECK(required_files); - for (auto& iter : *required_files) { - entry->AddRequiredFilePath(iter.first, std::move(iter.second)); - } - - const base::ListValue* services = nullptr; - if (value.GetList(Store::kServicesKey, &services)) { - for (size_t i = 0; i < services->GetSize(); ++i) { - const base::DictionaryValue* service = nullptr; - services->GetDictionary(i, &service); - std::unique_ptr<Entry> child = Entry::Deserialize(*service); - if (child) { - child->set_parent(entry.get()); - entry->children().emplace_back(std::move(child)); - } - } - } - - return entry; -} - bool Entry::ProvidesCapability(const std::string& capability) const { auto it = interface_provider_specs_.find( service_manager::mojom::kServiceManager_ConnectorSpec);
diff --git a/services/catalog/entry.h b/services/catalog/entry.h index 86a29e3..46de570 100644 --- a/services/catalog/entry.h +++ b/services/catalog/entry.h
@@ -16,10 +16,6 @@ #include "services/catalog/service_options.h" #include "services/service_manager/public/cpp/interface_provider_spec.h" -namespace base { -class Value; -} - namespace catalog { // Static information about a service package known to the Catalog. @@ -29,8 +25,6 @@ explicit Entry(const std::string& name); ~Entry(); - static std::unique_ptr<Entry> Deserialize(const base::Value& manifest_root); - bool ProvidesCapability(const std::string& capability) const; bool operator==(const Entry& other) const;
diff --git a/services/catalog/entry_unittest.cc b/services/catalog/entry_unittest.cc deleted file mode 100644 index f89668b4..0000000 --- a/services/catalog/entry_unittest.cc +++ /dev/null
@@ -1,149 +0,0 @@ -// Copyright 2016 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 "services/catalog/entry.h" - -#include "base/files/file_path.h" -#include "base/json/json_file_value_serializer.h" -#include "base/macros.h" -#include "base/path_service.h" -#include "base/values.h" -#include "build/build_config.h" -#include "services/service_manager/public/cpp/interface_provider_spec.h" -#include "services/service_manager/public/mojom/interface_provider_spec.mojom.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace catalog { - -class EntryTest : public testing::Test { - public: - EntryTest() {} - ~EntryTest() override {} - - protected: - std::unique_ptr<Entry> ReadEntry(const std::string& manifest, - std::unique_ptr<base::Value>* out_value) { - std::unique_ptr<base::Value> value = ReadManifest(manifest); - base::DictionaryValue* dictionary = nullptr; - CHECK(value->GetAsDictionary(&dictionary)); - if (out_value) - *out_value = std::move(value); - return Entry::Deserialize(*dictionary); - } - - std::unique_ptr<base::Value> ReadManifest(const std::string& manifest) { - base::FilePath manifest_path; - base::PathService::Get(base::DIR_SOURCE_ROOT, &manifest_path); - manifest_path = - manifest_path.AppendASCII("services/catalog/test_data/" + manifest); - - JSONFileValueDeserializer deserializer(manifest_path); - int error = 0; - std::string message; - // TODO(beng): probably want to do more detailed error checking. This should - // be done when figuring out if to unblock connection - // completion. - return deserializer.Deserialize(&error, &message); - } - - private: - void SetUp() override {} - void TearDown() override {} - - DISALLOW_COPY_AND_ASSIGN(EntryTest); -}; - -TEST_F(EntryTest, Simple) { - std::unique_ptr<Entry> entry = ReadEntry("simple", nullptr); - EXPECT_EQ("foo", entry->name()); - EXPECT_EQ("Foo", entry->display_name()); - EXPECT_EQ("none", entry->sandbox_type()); -} - -TEST_F(EntryTest, Instance) { - std::unique_ptr<Entry> entry = ReadEntry("instance", nullptr); - EXPECT_EQ("foo", entry->name()); - EXPECT_EQ("Foo", entry->display_name()); - EXPECT_EQ("", entry->sandbox_type()); -} - -TEST_F(EntryTest, Options) { - std::unique_ptr<Entry> entry = ReadEntry("options", nullptr); - EXPECT_EQ("foo", entry->name()); - EXPECT_EQ("Foo", entry->display_name()); - - EXPECT_EQ(ServiceOptions::InstanceSharingType::SINGLETON, - entry->options().instance_sharing); - EXPECT_TRUE(entry->options().can_connect_to_instances_in_any_group); - EXPECT_TRUE( - entry->options().can_connect_to_other_services_with_any_instance_name); - EXPECT_TRUE(entry->options().can_create_other_service_instances); - - EXPECT_EQ("", entry->sandbox_type()); -} - -TEST_F(EntryTest, ConnectionSpec) { - std::unique_ptr<Entry> entry = ReadEntry("connection_spec", nullptr); - - EXPECT_EQ("foo", entry->name()); - EXPECT_EQ("Foo", entry->display_name()); - service_manager::InterfaceProviderSpec spec; - service_manager::CapabilitySet capabilities; - capabilities.insert("bar:bar"); - spec.requires["bar"] = capabilities; - service_manager::InterfaceProviderSpecMap specs; - specs[service_manager::mojom::kServiceManager_ConnectorSpec] = spec; - EXPECT_EQ(specs, entry->interface_provider_specs()); -} - -TEST_F(EntryTest, RequiredFiles) { - std::unique_ptr<Entry> entry = ReadEntry("required_files", nullptr); - EXPECT_EQ("foo", entry->name()); - EXPECT_EQ("Foo", entry->display_name()); - auto required_files = entry->required_file_paths(); - EXPECT_EQ(2U, required_files.size()); - auto iter = required_files.find("all_platforms"); - ASSERT_NE(required_files.end(), iter); - bool checked_platform_specific_file = false; -#if defined(OS_WIN) - EXPECT_EQ(base::FilePath(L"/all/platforms/windows"), iter->second); - iter = required_files.find("windows_only"); - ASSERT_NE(required_files.end(), iter); - EXPECT_EQ(base::FilePath(L"/windows/only"), iter->second); - checked_platform_specific_file = true; -#elif defined(OS_FUCHSIA) - EXPECT_EQ(base::FilePath("/all/platforms/fuchsia"), iter->second); - iter = required_files.find("fuchsia_only"); - ASSERT_NE(required_files.end(), iter); - EXPECT_EQ(base::FilePath("/fuchsia/only"), iter->second); - checked_platform_specific_file = true; -#elif defined(OS_LINUX) - EXPECT_EQ(base::FilePath("/all/platforms/linux"), iter->second); - iter = required_files.find("linux_only"); - ASSERT_NE(required_files.end(), iter); - EXPECT_EQ(base::FilePath("/linux/only"), iter->second); - checked_platform_specific_file = true; -#elif defined(OS_MACOSX) - EXPECT_EQ(base::FilePath("/all/platforms/macosx"), iter->second); - iter = required_files.find("macosx_only"); - ASSERT_NE(required_files.end(), iter); - EXPECT_EQ(base::FilePath("/macosx/only"), iter->second); - checked_platform_specific_file = true; -#elif defined(OS_ANDROID) - EXPECT_EQ(base::FilePath("/all/platforms/android"), iter->second); - iter = required_files.find("android_only"); - ASSERT_NE(required_files.end(), iter); - EXPECT_EQ(base::FilePath("/android/only"), iter->second); - checked_platform_specific_file = true; -#endif - EXPECT_TRUE(checked_platform_specific_file); -} - -TEST_F(EntryTest, Malformed) { - std::unique_ptr<base::Value> value = ReadManifest("malformed"); - EXPECT_FALSE(value.get()); -} - - -} // namespace catalog
diff --git a/services/catalog/instance.cc b/services/catalog/instance.cc index 7dcbb76..8cc1422 100644 --- a/services/catalog/instance.cc +++ b/services/catalog/instance.cc
@@ -10,7 +10,6 @@ #include "base/values.h" #include "services/catalog/entry.h" #include "services/catalog/entry_cache.h" -#include "services/catalog/manifest_provider.h" namespace catalog { namespace { @@ -24,12 +23,9 @@ } // namespace -Instance::Instance(EntryCache* system_cache, - ManifestProvider* service_manifest_provider) - : system_cache_(system_cache), - service_manifest_provider_(service_manifest_provider) {} +Instance::Instance(EntryCache* system_cache) : system_cache_(system_cache) {} -Instance::~Instance() {} +Instance::~Instance() = default; void Instance::BindCatalog(mojom::CatalogRequest request) { catalog_bindings_.AddBinding(this, std::move(request)); @@ -41,25 +37,8 @@ if (cached_entry) return cached_entry; - std::unique_ptr<base::Value> new_manifest; - if (service_manifest_provider_) - new_manifest = service_manifest_provider_->GetManifest(service_name); - - if (!new_manifest) { - LOG(ERROR) << "Unable to locate service manifest for " << service_name; - return nullptr; - } - - auto new_entry = Entry::Deserialize(*new_manifest); - if (!new_entry) { - LOG(ERROR) << "Malformed manifest for " << service_name; - return nullptr; - } - - cached_entry = const_cast<const Entry*>(new_entry.get()); - bool added = system_cache_->AddRootEntry(std::move(new_entry)); - DCHECK(added); - return cached_entry; + LOG(ERROR) << "Unable to locate service manifest for " << service_name; + return nullptr; } void Instance::GetEntries(const base::Optional<std::vector<std::string>>& names,
diff --git a/services/catalog/instance.h b/services/catalog/instance.h index ad7d05c..14faa9d3 100644 --- a/services/catalog/instance.h +++ b/services/catalog/instance.h
@@ -17,14 +17,11 @@ namespace catalog { class EntryCache; -class ManifestProvider; class COMPONENT_EXPORT(CATALOG) Instance : public mojom::Catalog { public: - // Neither |system_cache| nor |service_manifest_provider| is owned. - // |service_manifest_provider| may be null - Instance(EntryCache* system_cache, - ManifestProvider* service_manifest_provider); + // |system_cache| is not owned. + explicit Instance(EntryCache* system_cache); ~Instance() override; void BindCatalog(mojom::CatalogRequest request); @@ -46,10 +43,6 @@ // TODO(beng): eventually add per-user applications. EntryCache* const system_cache_; - // A runtime interface the embedder can use to provide dynamic manifest data - // to be queried on-demand if something can't be found in |system_cache_|. - ManifestProvider* const service_manifest_provider_; - DISALLOW_COPY_AND_ASSIGN(Instance); };
diff --git a/services/catalog/manifest.json b/services/catalog/manifest.json deleted file mode 100644 index 0a5c2d2..0000000 --- a/services/catalog/manifest.json +++ /dev/null
@@ -1,20 +0,0 @@ -{ - "name": "catalog", - "display_name": "Application Resolver", - "options" : { - "instance_sharing" : "shared_instance_across_users" - }, - "interface_provider_specs": { - // NOTE: This manifest is for documentation purposes only. Relevant - // capability spec is defined inline in the ServiceManager implementation. - // - // TODO(rockot): Fix this. We can bake this file into ServiceManager at - // build time or something. Same with service:service_manager. - "service_manager:connector": { - "provides": { - "directory": [ "filesystem.mojom.Directory" ], - "control": [ "catalog.mojom.CatalogControl" ] - } - } - } -}
diff --git a/services/catalog/manifest_provider.h b/services/catalog/manifest_provider.h deleted file mode 100644 index f1caa225..0000000 --- a/services/catalog/manifest_provider.h +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2016 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 SERVICES_CATALOG_MANIFEST_PROVIDER_H_ -#define SERVICES_CATALOG_MANIFEST_PROVIDER_H_ - -#include <string> - -#include "base/component_export.h" - -namespace base { -class Value; -} - -namespace catalog { - -// An interface which can be implemented by a catalog embedder to override -// manifest fetching behavior. -class COMPONENT_EXPORT(CATALOG) ManifestProvider { - public: - virtual ~ManifestProvider() {} - - // Retrieves the raw contents of the manifest for application named |name|. - // Returns true if |name| is known and |*manifest_contents| is populated. - // returns false otherwise. - virtual std::unique_ptr<base::Value> GetManifest(const std::string& name) = 0; -}; - -} // namespace catalog - -#endif // SERVICES_CATALOG_MANIFEST_PROVIDER_H_
diff --git a/services/catalog/public/cpp/BUILD.gn b/services/catalog/public/cpp/BUILD.gn index 7eb6bda..1b61a04 100644 --- a/services/catalog/public/cpp/BUILD.gn +++ b/services/catalog/public/cpp/BUILD.gn
@@ -4,8 +4,6 @@ source_set("cpp") { sources = [ - "manifest_parsing_util.cc", - "manifest_parsing_util.h", "resource_loader.cc", "resource_loader.h", ]
diff --git a/services/catalog/public/cpp/manifest_parsing_util.cc b/services/catalog/public/cpp/manifest_parsing_util.cc deleted file mode 100644 index 4a19ec6..0000000 --- a/services/catalog/public/cpp/manifest_parsing_util.cc +++ /dev/null
@@ -1,111 +0,0 @@ -// Copyright 2017 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 "services/catalog/public/cpp/manifest_parsing_util.h" - -#include "base/values.h" -#include "build/build_config.h" -#include "services/catalog/store.h" - -namespace catalog { - -namespace { - -bool IsValidPlatformName(const std::string& name) { - return name == Store::kRequiredFilesKey_PlatformValue_Windows || - name == Store::kRequiredFilesKey_PlatformValue_Linux || - name == Store::kRequiredFilesKey_PlatformValue_MacOSX || - name == Store::kRequiredFilesKey_PlatformValue_Android || - name == Store::kRequiredFilesKey_PlatformValue_Fuchsia; -} - -bool IsCurrentPlatform(const std::string& name) { -#if defined(OS_WIN) - return name == Store::kRequiredFilesKey_PlatformValue_Windows; -#elif defined(OS_LINUX) - return name == Store::kRequiredFilesKey_PlatformValue_Linux; -#elif defined(OS_MACOSX) - return name == Store::kRequiredFilesKey_PlatformValue_MacOSX; -#elif defined(OS_ANDROID) - return name == Store::kRequiredFilesKey_PlatformValue_Android; -#elif defined(OS_FUCHSIA) - return name == Store::kRequiredFilesKey_PlatformValue_Fuchsia; -#else -#error This architecture is not supported. -#endif -} - -} // namespace - -base::Optional<RequiredFileMap> RetrieveRequiredFiles( - const base::Value& manifest_value) { - const base::DictionaryValue* manifest_dictionary = nullptr; - if (!manifest_value.GetAsDictionary(&manifest_dictionary)) { - DLOG(ERROR) << "Entry::Deserialize: manifest node is not a dictionary."; - return base::nullopt; - } - - RequiredFileMap required_files; - if (!manifest_dictionary->HasKey(Store::kRequiredFilesKey)) - return {required_files}; - - const base::DictionaryValue* required_files_value = nullptr; - if (!manifest_dictionary->GetDictionary(Store::kRequiredFilesKey, - &required_files_value)) { - DLOG(ERROR) << "Entry::Deserialize: RequiredFiles not a dictionary."; - return base::nullopt; - } - - base::DictionaryValue::Iterator it(*required_files_value); - for (; !it.IsAtEnd(); it.Advance()) { - const std::string& entry_name = it.key(); - const base::ListValue* all_platform_values = nullptr; - if (!it.value().GetAsList(&all_platform_values)) { - DLOG(ERROR) << "Entry::Deserialize: value of RequiredFiles for key: " - << entry_name << " not a list."; - return base::nullopt; - } - - for (size_t i = 0; i < all_platform_values->GetSize(); i++) { - const base::DictionaryValue* file_descriptor_value = nullptr; - if (!all_platform_values->GetDictionary(i, &file_descriptor_value)) { - DLOG(ERROR) << "Entry::Deserialize: value of entry at index " << i - << " of RequiredFiles for key: " << entry_name - << " not a dictionary."; - return base::nullopt; - } - std::string platform; - if (file_descriptor_value->GetString(Store::kRequiredFilesKey_PlatformKey, - &platform)) { - if (!IsValidPlatformName(platform)) { - DLOG(ERROR) << "Entry::Deserialize: value of platform for " - << "required file entry entry is invalid " << platform; - return base::nullopt; - } - } - if (!IsCurrentPlatform(platform)) { - continue; - } - base::FilePath::StringType path; - if (!file_descriptor_value->GetString(Store::kRequiredFilesKey_PathKey, - &path)) { - DLOG(ERROR) << "Entry::Deserialize: value of RequiredFiles entry for " - << "key: " << entry_name - << " missing: " << Store::kRequiredFilesKey_PathKey - << " value."; - return base::nullopt; - } - if (required_files.count(entry_name) > 0) { - DLOG(ERROR) << "Entry::Deserialize: value of RequiredFiles entry for " - << "key: " << entry_name << " has more than one value for " - << "platform: " << platform; - return base::nullopt; - } - required_files[entry_name] = base::FilePath(path); - } - } - return base::make_optional(std::move(required_files)); -} - -} // namespace content
diff --git a/services/catalog/public/cpp/manifest_parsing_util.h b/services/catalog/public/cpp/manifest_parsing_util.h deleted file mode 100644 index f76c156..0000000 --- a/services/catalog/public/cpp/manifest_parsing_util.h +++ /dev/null
@@ -1,29 +0,0 @@ -// Copyright 2017 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 SERVICES_CATALOG_PUBLIC_CPP_MANIFEST_PARSING_UTIL_H_ -#define SERVICES_CATALOG_PUBLIC_CPP_MANIFEST_PARSING_UTIL_H_ - -#include <map> -#include <string> - -#include "base/files/file_path.h" -#include "base/optional.h" - -namespace base { -class Value; -} - -// TODO(jcivelli): http://crbug.com/687250 Remove this file and inline -// PopulateRequiredFiles() in Entry::Deserialize. -namespace catalog { - -using RequiredFileMap = std::map<std::string, base::FilePath>; - -base::Optional<RequiredFileMap> RetrieveRequiredFiles( - const base::Value& manifest); - -} // namespace content - -#endif // SERVICES_CATALOG_PUBLIC_CPP_MANIFEST_PARSING_UTIL_H_
diff --git a/services/catalog/public/tools/catalog.cc.tmpl b/services/catalog/public/tools/catalog.cc.tmpl index 06327c5..85ebc0c 100644 --- a/services/catalog/public/tools/catalog.cc.tmpl +++ b/services/catalog/public/tools/catalog.cc.tmpl
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This is a generated file. Please see the "catalog_cpp_source" template in -// src/services/catalog/public/tools/catalog.gni for more details. +// This is a generated file. Please see the "service_manifest" template in +// src/services/service_manager/public/service_manifest.gni for more details. #include "{{path}}.h" @@ -13,8 +13,15 @@ #include "base/no_destructor.h" #include "build/build_config.h" #include "services/service_manager/public/cpp/manifest_builder.h" +{% for info in packaged_services %} +#include "{{info.header}}" +{%- endfor %} +{% for info in overlays %} +#include "{{info.header}}" +{%- endfor %} -{%- macro generate_manifest_builder(manifest) -%} +{%- macro generate_manifest_builder(manifest, packaged_services=[], + overlays=[]) -%} service_manager::ManifestBuilder() .WithServiceName("{{manifest['name']}}") {%- if 'display_name' in manifest %} @@ -102,21 +109,36 @@ .PackageService( {{generate_manifest_builder(packaged_service_manifest)|indent(8)}}) {%- endfor %} +{%- for info in packaged_services %} + .PackageService({{info.namespace}}::GetManifest()) +{%- endfor %} .Build() +{%- for info in overlays %} + .Amend({{info.namespace}}::GetManifest()) +{%- endfor %} {%- endmacro %} {% for namespace in namespaces %} namespace {{namespace}} { {%- endfor %} -const std::vector<service_manager::Manifest>& {{function_name}}() { - static base::NoDestructor<std::vector<service_manager::Manifest>> catalog{ { -{%- for entry in catalog['services'].itervalues() %} - {{generate_manifest_builder(entry['manifest'])|indent(6)}} -{%- if not loop.last %},{% endif %} -{%- endfor %} } }; - return *catalog; +{% if root_manifest %} +const service_manager::Manifest& {{function_name}}() { + static base::NoDestructor<service_manager::Manifest> manifest{ + {{generate_manifest_builder(root_manifest, + packaged_services=packaged_services, overlays=overlays) + |indent(6)}} }; + return *manifest; } +{% else %} +const std::vector<service_manager::Manifest>& {{function_name}}() { + static base::NoDestructor<std::vector<service_manager::Manifest>> manifests{ { +{%- for info in packaged_services %} + {{info.namespace}}::GetManifest(){%- if not loop.last %},{%- endif %} +{%- endfor -%} }}; + return *manifests; +} +{% endif %} {%- for namespace in namespaces|reverse %} } // namespace {{namespace}}
diff --git a/services/catalog/public/tools/catalog.gni b/services/catalog/public/tools/catalog.gni index 212d28c..ca11a734 100644 --- a/services/catalog/public/tools/catalog.gni +++ b/services/catalog/public/tools/catalog.gni
@@ -4,173 +4,53 @@ import("//build/config/dcheck_always_on.gni") -# Generates a static catalog manifest to be loaded at runtime. This manifest -# contains the union of all individual service manifests specified by the -# template parameters. +# Generates code to produce a list service_manager::Manifest objects given a set +# of service_manager targets to include in the list. # -# The output of a catalog rule is always a file named: +# This is a temporary helper to transition away from JSON manifests. The catalog +# target always has a companion catalog_cpp_source target, which yields a +# source_set defining the generated function. # -# ${target_gen_dir}/${target_name}.json -# -# A Service Manager embedder uses a catalog manifest as its singular source of -# truth regarding available services in the system. -# -# Parameters: -# -# embedded_services (optional) -# A list of service manifest targets whose outputs correspond to services -# embedded by the Service Manager embedder's binary. Outputs of targets -# listed here will be embedded in the catalog within its -# "embedded_services" list. -# -# standalone_services (optional) -# A list of service manifest targets whose outputs correspond to services -# with standalone binaries which must be available to the Service Manager -# at runtime. Outputs of targets listed here will be embedded in the -# catalog within its "standalone_services" list. -# -# Typically a standalone service binary is expected to live next to -# the Service Manager embedder's binary, with the name -# "${service_name}.service", with an additional ".exe" suffix on Windows. -# Binaries following this naming scheme are typically output by -# service_executable targets. See -# //services/service_manager/public/cpp/service_executable.gni. -# -# executable_overrides (optional) -# A list of overrides to apply in catalog metadata for individual -# services. An override string must be of the form -# -# "<service_name>:<executable_path>" -# -# The special token @EXE_DIR may be used in |executable_path| to denote -# a path relative to the Service Manager embedder's binary, substituted -# at runtime. For example: -# -# "content_browser:@EXE_DIR/chrome" -# -# would indicate to the Service Manager embedder that the -# "content_browser" service can be started by running the "chrome" -# executable in the embedder's own directory. -# -# This overrides the default binary name expectation described in -# |standalone_services| above. -# -# catalog_deps (optional) -# A list of other catalog targets whose outputs will be included within -# this catalog. Targets in this list -# +# No new uses of these targets should be introduced. template("catalog") { - output_filename = "$target_gen_dir/${target_name}.json" - action(target_name) { + group(target_name) { testonly = defined(invoker.testonly) && invoker.testonly - - script = "//services/catalog/public/tools/generate_manifest.py" - - inputs = [] - outputs = [ - output_filename, - ] - - args = [ "--output=" + rebase_path(output_filename, root_build_dir) ] - - if (is_debug || dcheck_always_on) { - args += [ "--pretty" ] - } - - deps = [] - if (defined(invoker.deps)) { - deps += invoker.deps - } - - if (defined(invoker.embedded_services)) { - args += [ "--embedded-services" ] - foreach(manifest_target, invoker.embedded_services) { - manifest_target_dir = get_label_info(manifest_target, "target_gen_dir") - manifest_target_name = get_label_info(manifest_target, "name") - manifest_filename = "$manifest_target_dir/${manifest_target_name}.json" - - inputs += [ "$manifest_filename" ] - deps += [ manifest_target ] - args += [ rebase_path(manifest_filename, root_build_dir) ] - - # Ensure that each entry does in fact reference a service manifest rule. - label_no_toolchain = - get_label_info(manifest_target, "label_no_toolchain") - toolchain = get_label_info(manifest_target, "toolchain") - deps += [ "${label_no_toolchain}__is_service_manifest(${toolchain})" ] - } - } - - if (defined(invoker.standalone_services)) { - args += [ "--standalone-services" ] - foreach(manifest_target, invoker.standalone_services) { - manifest_target_dir = get_label_info(manifest_target, "target_gen_dir") - manifest_target_name = get_label_info(manifest_target, "name") - manifest_filename = "$manifest_target_dir/${manifest_target_name}.json" - - inputs += [ "$manifest_filename" ] - deps += [ manifest_target ] - args += [ rebase_path(manifest_filename, root_build_dir) ] - - # Ensure that each entry does in fact reference a service manifest rule. - label_no_toolchain = - get_label_info(manifest_target, "label_no_toolchain") - toolchain = get_label_info(manifest_target, "toolchain") - deps += [ "${label_no_toolchain}__is_service_manifest(${toolchain})" ] - } - } - - if (defined(invoker.executable_overrides)) { - args += - [ "--override-service-executables" ] + invoker.executable_overrides - } - - if (defined(invoker.catalog_deps)) { - args += [ "--include-catalogs" ] - foreach(catalog_target, invoker.catalog_deps) { - catalog_target_dir = get_label_info(catalog_target, "target_gen_dir") - catalog_target_name = get_label_info(catalog_target, "name") - catalog_filename = "$catalog_target_dir/${catalog_target_name}.json" - - inputs += [ "$catalog_filename" ] - deps += [ catalog_target ] - args += [ rebase_path(catalog_filename, root_build_dir) ] - } - } } + + # NOTE: There is no longer a practical difference between embedded and + # standalone services in terms of manifest data. Some targets use one or the + # other or both. + submanifests = [] + if (defined(invoker.embedded_services)) { + submanifests += invoker.embedded_services + } + if (defined(invoker.standalone_services)) { + submanifests += invoker.standalone_services + } + + write_file("$target_gen_dir/${target_name}.submanifests", submanifests) } -# Generates a source_set target which defines a single string constant -# containing the contents of a compiled catalog manifest. -# -# Parameters: -# -# catalog -# The catalog target whose output should be stringified. -# -# generated_function_name -# The fully qualified symbol name of the C++ string constant to define in -# the generate source_set. -# template("catalog_cpp_source") { assert(defined(invoker.catalog), "catalog is required") assert(defined(invoker.generated_function_name), "generated_function_name is required") + generator_target_name = "${target_name}__generator" + generated_filename_base = "${target_gen_dir}/${target_name}" + catalog_target = invoker.catalog catalog_target_dir = get_label_info(catalog_target, "target_gen_dir") catalog_target_name = get_label_info(catalog_target, "name") - catalog_filename = "$catalog_target_dir/${catalog_target_name}.json" - generator_target_name = "${target_name}__generator" - generated_filename_base = "${target_gen_dir}/${target_name}" + submanifests = + read_file("$catalog_target_dir/${catalog_target_name}.submanifests", + "list lines") action(generator_target_name) { testonly = defined(invoker.testonly) && invoker.testonly script = "//services/catalog/public/tools/sourcify_manifest.py" inputs = [ - catalog_filename, - "//services/catalog/public/tools/catalog.cc.tmpl", "//services/catalog/public/tools/catalog.h.tmpl", ] @@ -178,28 +58,42 @@ "${generated_filename_base}.cc", "${generated_filename_base}.h", ] + + submanifest_info = [] + foreach(submanifest, submanifests) { + manifest_dir = get_label_info(submanifest, "target_gen_dir") + manifest_target_name = get_label_info(submanifest, "name") + manifest_namespace_input = + "$manifest_dir/${manifest_target_name}.namespace" + manifest_namespace_path = + rebase_path(manifest_namespace_input, root_build_dir) + manifest_header_base = + rebase_path(manifest_dir, root_gen_dir) + "/${manifest_target_name}" + submanifest_info += + [ "packaged@$manifest_namespace_path@$manifest_header_base" ] + } + + submanifest_info_file = + "$target_gen_dir/${invoker.target_name}.submanifest_info" + write_file(submanifest_info_file, submanifest_info) + args = [ - "--input=" + rebase_path(catalog_filename, root_build_dir), + "--submanifest-info=" + + rebase_path(submanifest_info_file, root_build_dir), "--output-filename-base=" + rebase_path(generated_filename_base, root_build_dir), "--output-function-name=" + invoker.generated_function_name, "--module-path=" + rebase_path(generated_filename_base, root_gen_dir), ] - if (is_debug || dcheck_always_on) { - args += [ "--pretty" ] - } - deps = [ - catalog_target, - ] } source_set(target_name) { testonly = defined(invoker.testonly) && invoker.testonly sources = get_target_outputs(":$generator_target_name") deps = [ - ":$generator_target_name", - "//base", - "//services/service_manager/public/cpp", - ] + ":$generator_target_name", + "//base", + "//services/service_manager/public/cpp", + ] + submanifests } }
diff --git a/services/catalog/public/tools/catalog.h.tmpl b/services/catalog/public/tools/catalog.h.tmpl index 402a877b..aed4b1d 100644 --- a/services/catalog/public/tools/catalog.h.tmpl +++ b/services/catalog/public/tools/catalog.h.tmpl
@@ -2,8 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This is a generated file. Please see the "catalog_cpp_source" template in -// src/services/catalog/public/tools/catalog.gni for more details. +// This is a generated file. Please see the "service_manifest" template in +// src/services/service_manager/public/service_manifest.gni for more details. + {%- set header_guard = "%s_H_"|format(path)|upper|replace("/", "_")| replace(".", "_")|replace("-", "_") %} @@ -18,7 +19,11 @@ namespace {{namespace}} { {%- endfor %} +{% if root_manifest -%} +const service_manager::Manifest& {{function_name}}(); +{% else -%} const std::vector<service_manager::Manifest>& {{function_name}}(); +{%- endif %} {% for namespace in namespaces|reverse %} } // namespace {{namespace}}
diff --git a/services/catalog/public/tools/sourcify_manifest.py b/services/catalog/public/tools/sourcify_manifest.py index 1bcfc6ae..acfc971d 100755 --- a/services/catalog/public/tools/sourcify_manifest.py +++ b/services/catalog/public/tools/sourcify_manifest.py
@@ -18,10 +18,20 @@ "build", "android", "gyp")) from util import build_utils + _H_FILE_TEMPLATE = "catalog.h.tmpl" _CC_FILE_TEMPLATE = "catalog.cc.tmpl" +eater_relative = "../../../../../tools/json_comment_eater" +eater_relative = os.path.join(os.path.abspath(__file__), eater_relative) +sys.path.insert(0, os.path.normpath(eater_relative)) +try: + import json_comment_eater +finally: + sys.path.pop(0) + + # Disable lint check for finding modules: # pylint: disable=F0401 @@ -44,49 +54,38 @@ def ApplyTemplate(path_to_template, output_path, global_vars, **kwargs): - def make_ascii(maybe_unicode): - if type(maybe_unicode) is str: - return maybe_unicode - assert type(maybe_unicode) is unicode - return maybe_unicode.encode("ascii", "ignore") - with build_utils.AtomicOutput(output_path) as output_file: jinja_env = jinja2.Environment( loader=jinja2.FileSystemLoader(os.path.dirname(__file__)), keep_trailing_newline=True, **kwargs) jinja_env.globals.update(global_vars) - jinja_env.filters.update({ - "is_dict": lambda x : type(x) is dict, - "is_list": lambda x : type(x) is list, - "is_number": lambda x : type(x) is int or type(x) is float, - "is_bool": lambda x: type(x) is bool, - "is_string": lambda x: type(x) is str, - "is_unicode": lambda x: type(x) is unicode, - "make_ascii": make_ascii, - }) output_file.write(jinja_env.get_template(path_to_template).render()) def main(): parser = argparse.ArgumentParser( description="Generates a C++ constant containing a catalog manifest.") - parser.add_argument("--input") + parser.add_argument("--root-manifest") + parser.add_argument("--submanifest-info") parser.add_argument("--output-filename-base") parser.add_argument("--output-function-name") parser.add_argument("--module-path") args, _ = parser.parse_known_args() - if args.input is None: - raise Exception("--input is required") + if args.submanifest_info is None: + raise Exception("--submanifest-info required") if args.output_filename_base is None: raise Exception("--output-filename-base is required") if args.output_function_name is None: raise Exception("--output-function-name is required") if args.module_path is None: - raise Exception("--module-path is required") + args.module_path = args.output_filename_base - with open(args.input, "r") as input_file: - catalog = json.load(input_file) + if args.root_manifest: + with open(args.root_manifest, "r") as input_file: + root_manifest = json.loads(json_comment_eater.Nom(input_file.read())) + else: + root_manifest = None qualified_function_name = args.output_function_name.split("::") namespaces = qualified_function_name[0:-1] @@ -95,8 +94,23 @@ def raise_error(error, value): raise Exception(error) + overlays = [] + packaged_services = [] + with open(args.submanifest_info, "r") as info_file: + for line in info_file.readlines(): + submanifest_type, namespace_file, header_base = line.strip().split("@", 3) + with open(namespace_file, "r") as namespace_file: + namespace = namespace_file.readline().strip() + info = { "namespace": namespace, "header": header_base + ".h" } + if submanifest_type == "overlay": + overlays.append(info) + else: + packaged_services.append(info) + global_vars = { - "catalog": catalog, + "root_manifest": root_manifest, + "overlays": overlays, + "packaged_services": packaged_services, "function_name": function_name, "namespaces": namespaces, "path": args.module_path,
diff --git a/services/catalog/test_data/connection_spec b/services/catalog/test_data/connection_spec deleted file mode 100644 index 80da172..0000000 --- a/services/catalog/test_data/connection_spec +++ /dev/null
@@ -1,11 +0,0 @@ -{ - "name": "foo", - "display_name": "Foo", - "interface_provider_specs": { - "service_manager:connector": { - "requires": { - "bar": [ "bar:bar" ] - } - } - } -}
diff --git a/services/catalog/test_data/instance b/services/catalog/test_data/instance deleted file mode 100644 index 3fa31be..0000000 --- a/services/catalog/test_data/instance +++ /dev/null
@@ -1,5 +0,0 @@ -{ - "name": "foo", - "display_name": "Foo", - "interface_provider_specs": { } -}
diff --git a/services/catalog/test_data/malformed b/services/catalog/test_data/malformed deleted file mode 100644 index 28a269c..0000000 --- a/services/catalog/test_data/malformed +++ /dev/null
@@ -1,3 +0,0 @@ -{ - "name": "foo", - "display_name": "Foo",
diff --git a/services/catalog/test_data/options b/services/catalog/test_data/options deleted file mode 100644 index 203a4e6..0000000 --- a/services/catalog/test_data/options +++ /dev/null
@@ -1,11 +0,0 @@ -{ - "name": "foo", - "display_name": "Foo", - "options": { - "instance_sharing": "singleton", - "can_connect_to_other_services_as_any_user": true, - "can_connect_to_other_services_with_any_instance_name": true, - "can_create_other_service_instances": true - }, - "interface_provider_specs": { } -}
diff --git a/services/catalog/test_data/required_files b/services/catalog/test_data/required_files deleted file mode 100644 index 2e45d97e..0000000 --- a/services/catalog/test_data/required_files +++ /dev/null
@@ -1,19 +0,0 @@ -{ - "name": "foo", - "display_name": "Foo", - "interface_provider_specs": { }, - "required_files": { - "all_platforms": [ - { "path": "/all/platforms/fuchsia", "platform": "fuchsia" }, - { "path": "/all/platforms/linux", "platform": "linux" }, - { "path": "/all/platforms/windows", "platform": "windows" }, - { "path": "/all/platforms/macosx", "platform": "macosx" }, - { "path": "/all/platforms/android", "platform": "android" } - ], - "fuchsia_only": [{ "path": "/fuchsia/only", "platform": "fuchsia" }], - "linux_only": [{ "path": "/linux/only", "platform": "linux" }], - "windows_only": [{ "path" : "/windows/only", "platform": "windows" }], - "macosx_only": [{ "path" : "/macosx/only", "platform": "macosx" }], - "android_only": [{ "path" : "/android/only", "platform": "android" }] - } -}
diff --git a/services/catalog/test_data/serialization b/services/catalog/test_data/serialization deleted file mode 100644 index 10fe188..0000000 --- a/services/catalog/test_data/serialization +++ /dev/null
@@ -1,15 +0,0 @@ -{ - "name": "foo", - "display_name": "Foo", - "interface_provider_specs": { - "service_manager:connector": { - "provides": { - "foo": [ "mojo::Bar", "mojo::Baz" ], - "bar": [ "mojo::Bork" ] - }, - "requires": { - "bar": [ "a", "b" ] - } - } - } -}
diff --git a/services/catalog/test_data/simple b/services/catalog/test_data/simple deleted file mode 100644 index 04cd6fe..0000000 --- a/services/catalog/test_data/simple +++ /dev/null
@@ -1,6 +0,0 @@ -{ - "name": "foo", - "display_name": "Foo", - "sandbox_type": "none", - "interface_provider_specs": { } -}
diff --git a/services/service_manager/BUILD.gn b/services/service_manager/BUILD.gn index efd375a..e55963d 100644 --- a/services/service_manager/BUILD.gn +++ b/services/service_manager/BUILD.gn
@@ -28,8 +28,6 @@ "connect_params.h", "service_manager.cc", "service_manager.h", - "service_overrides.cc", - "service_overrides.h", "switches.cc", "switches.h", ]
diff --git a/services/service_manager/background/background_service_manager.cc b/services/service_manager/background/background_service_manager.cc index c887ea7..6e718c4 100644 --- a/services/service_manager/background/background_service_manager.cc +++ b/services/service_manager/background/background_service_manager.cc
@@ -26,26 +26,13 @@ BackgroundServiceManager::BackgroundServiceManager( ServiceProcessLauncherDelegate* launcher_delegate, - std::unique_ptr<base::Value> catalog_contents) - : background_thread_("service_manager") { - background_thread_.Start(); - background_thread_.task_runner()->PostTask( - FROM_HERE, - base::BindOnce(&BackgroundServiceManager::InitializeOnBackgroundThread, - base::Unretained(this), launcher_delegate, - std::move(catalog_contents), std::vector<Manifest>())); -} - -BackgroundServiceManager::BackgroundServiceManager( - ServiceProcessLauncherDelegate* launcher_delegate, const std::vector<Manifest>& manifests) : background_thread_("service_manager") { background_thread_.Start(); background_thread_.task_runner()->PostTask( FROM_HERE, base::BindOnce(&BackgroundServiceManager::InitializeOnBackgroundThread, - base::Unretained(this), launcher_delegate, nullptr, - manifests)); + base::Unretained(this), launcher_delegate, manifests)); } BackgroundServiceManager::~BackgroundServiceManager() { @@ -74,14 +61,8 @@ void BackgroundServiceManager::InitializeOnBackgroundThread( ServiceProcessLauncherDelegate* launcher_delegate, - std::unique_ptr<base::Value> catalog_contents, const std::vector<Manifest>& manifests) { - if (!manifests.empty()) { - context_ = std::make_unique<Context>(launcher_delegate, manifests); - } else { - context_ = std::make_unique<Context>(launcher_delegate, - std::move(catalog_contents)); - } + context_ = std::make_unique<Context>(launcher_delegate, manifests); } void BackgroundServiceManager::ShutDownOnBackgroundThread(
diff --git a/services/service_manager/background/background_service_manager.h b/services/service_manager/background/background_service_manager.h index d614f5b..8260d0c 100644 --- a/services/service_manager/background/background_service_manager.h +++ b/services/service_manager/background/background_service_manager.h
@@ -10,7 +10,6 @@ #include "base/macros.h" #include "base/threading/thread.h" -#include "base/values.h" #include "build/build_config.h" #include "services/service_manager/public/cpp/manifest.h" #include "services/service_manager/public/mojom/connector.mojom.h" @@ -32,8 +31,6 @@ class BackgroundServiceManager { public: BackgroundServiceManager(ServiceProcessLauncherDelegate* launcher_delegate, - std::unique_ptr<base::Value> catalog_contents); - BackgroundServiceManager(ServiceProcessLauncherDelegate* launcher_delegate, const std::vector<Manifest>& manifests); ~BackgroundServiceManager(); @@ -50,7 +47,6 @@ private: void InitializeOnBackgroundThread( ServiceProcessLauncherDelegate* launcher_delegate, - std::unique_ptr<base::Value> catalog_contents, const std::vector<Manifest>& manifests); void ShutDownOnBackgroundThread(base::WaitableEvent* done_event); void RegisterServiceOnBackgroundThread(
diff --git a/services/service_manager/embedder/BUILD.gn b/services/service_manager/embedder/BUILD.gn index df6fb926..feeac1e2 100644 --- a/services/service_manager/embedder/BUILD.gn +++ b/services/service_manager/embedder/BUILD.gn
@@ -2,19 +2,12 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -component("embedder") { - public = [ - "manifest_utils.h", - ] - - sources = [ - "manifest_utils.cc", - ] - - # iOS embeds the Service Manager but does not use service_manager::Main() (and - # cannot use or even build it as-is). - if (!is_ios) { - public += [ +if (!is_ios) { + # iOS embeds the Service Manager but does not use anything in this library. + # This avoids having an empty component library target, which can otherwise be + # problematic. + component("embedder") { + public = [ "main.h", "main_delegate.h", "process_type.h", @@ -22,60 +15,52 @@ "set_process_title_linux.h", "shared_file_util.h", ] - sources += [ + + sources = [ "main.cc", "main_delegate.cc", "set_process_title.cc", "set_process_title_linux.cc", "shared_file_util.cc", ] - } - if (is_mac) { - sources += [ - "mac_init.h", - "mac_init.mm", - ] + if (is_mac) { + sources += [ + "mac_init.h", + "mac_init.mm", + ] - libs = [ "Foundation.framework" ] - } + libs = [ "Foundation.framework" ] + } - deps = [ - "//base:base_static", - "//base:i18n", - ] - - public_deps = [ - ":embedder_result_codes", - "//base", - "//services/service_manager/public/cpp", - "//services/service_manager/public/mojom", - ] - - if (!is_ios) { - # deps of ServiceManager::Main and related functionality. - deps += [ + deps = [ + "//base:base_static", + "//base:i18n", "//base/allocator:buildflags", "//components/tracing:startup_tracing", ] + public_deps = [ + ":embedder_result_codes", + ":embedder_switches", + "//base", + "//mojo/core/embedder", + "//services/service_manager/background:lib", + "//services/service_manager/public/cpp", + "//services/service_manager/public/cpp/service_executable:support", + "//services/service_manager/public/mojom", + "//services/service_manager/runner:init", + "//services/service_manager/runner/common", + ] + if (!is_nacl) { # NaCl stuff should not depend on skia as it would require platform and # cpu properties set. deps += [ "//ui/base" ] } - public_deps += [ - ":embedder_switches", - "//mojo/core/embedder", - "//services/service_manager/background:lib", - "//services/service_manager/public/cpp/service_executable:support", - "//services/service_manager/runner:init", - "//services/service_manager/runner/common", - ] + defines = [ "IS_SERVICE_MANAGER_EMBEDDER_IMPL" ] } - - defines = [ "IS_SERVICE_MANAGER_EMBEDDER_IMPL" ] } component("embedder_switches") { @@ -94,18 +79,3 @@ "result_codes.h", ] } - -source_set("unittests") { - testonly = true - - sources = [ - "manifest_utils_unittest.cc", - ] - - deps = [ - ":embedder", - "//base", - "//base/test:test_support", - "//testing/gtest", - ] -}
diff --git a/services/service_manager/embedder/main.cc b/services/service_manager/embedder/main.cc index 53eeddcb..329b86e0 100644 --- a/services/service_manager/embedder/main.cc +++ b/services/service_manager/embedder/main.cc
@@ -234,7 +234,7 @@ ServiceProcessLauncherDelegateImpl service_process_launcher_delegate( delegate); service_manager::BackgroundServiceManager background_service_manager( - &service_process_launcher_delegate, delegate->CreateServiceCatalog()); + &service_process_launcher_delegate, delegate->GetServiceManifests()); base::RunLoop run_loop; delegate->OnServiceManagerInitialized(run_loop.QuitClosure(),
diff --git a/services/service_manager/embedder/main_delegate.cc b/services/service_manager/embedder/main_delegate.cc index 1501a97b..ea4c1d7 100644 --- a/services/service_manager/embedder/main_delegate.cc +++ b/services/service_manager/embedder/main_delegate.cc
@@ -27,8 +27,8 @@ void MainDelegate::OverrideMojoConfiguration( mojo::core::Configuration* config) {} -std::unique_ptr<base::Value> MainDelegate::CreateServiceCatalog() { - return nullptr; +std::vector<Manifest> MainDelegate::GetServiceManifests() { + return std::vector<Manifest>(); } bool MainDelegate::ShouldLaunchAsServiceProcess(const Identity& identity) {
diff --git a/services/service_manager/embedder/main_delegate.h b/services/service_manager/embedder/main_delegate.h index d373d708..ba3589a5 100644 --- a/services/service_manager/embedder/main_delegate.h +++ b/services/service_manager/embedder/main_delegate.h
@@ -6,6 +6,7 @@ #define SERVICES_SERVICE_MANAGER_EMBEDDER_MAIN_DELEGATE_H_ #include <memory> +#include <vector> #include "base/callback_forward.h" #include "base/component_export.h" @@ -15,12 +16,12 @@ #include "services/service_manager/background/background_service_manager.h" #include "services/service_manager/embedder/process_type.h" #include "services/service_manager/public/cpp/identity.h" +#include "services/service_manager/public/cpp/manifest.h" #include "services/service_manager/public/cpp/service.h" #include "services/service_manager/public/mojom/service.mojom.h" namespace base { class CommandLine; -class Value; namespace mac { class ScopedNSAutoreleasePool; } @@ -73,9 +74,10 @@ // Allows the embedder to override the process-wide Mojop configuration. virtual void OverrideMojoConfiguration(mojo::core::Configuration* config); - // Create the service catalog to be used by the Service Manager. May return - // null to use the default (empty) catalog, if you're into that. - virtual std::unique_ptr<base::Value> CreateServiceCatalog(); + // Gets the list of service manifests with which to initialize the Service + // Manager. This list must describe the complete set of usable services in + // the system and remains fixed for the lifetime of the Service Manager. + virtual std::vector<Manifest> GetServiceManifests(); // Indicates whether a process started by the service manager for a given // target service identity should be run as a real service process (|true|)
diff --git a/services/service_manager/embedder/manifest_utils.cc b/services/service_manager/embedder/manifest_utils.cc deleted file mode 100644 index a43c152..0000000 --- a/services/service_manager/embedder/manifest_utils.cc +++ /dev/null
@@ -1,63 +0,0 @@ -// Copyright 2016 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 "services/service_manager/embedder/manifest_utils.h" - - -namespace service_manager { - -namespace { - -// Similar to base::DictionaryValue::MergeDictionary(), except concatenates -// ListValue contents. -// This is explicitly not part of base::DictionaryValue at brettw's request. -void MergeDictionary(base::DictionaryValue* target, - const base::DictionaryValue* source) { - for (base::DictionaryValue::Iterator it(*source); !it.IsAtEnd(); - it.Advance()) { - const base::Value* merge_value = &it.value(); - // Check whether we have to merge dictionaries. - if (merge_value->is_dict()) { - base::DictionaryValue* sub_dict; - if (target->GetDictionaryWithoutPathExpansion(it.key(), &sub_dict)) { - MergeDictionary(sub_dict, - static_cast<const base::DictionaryValue*>(merge_value)); - continue; - } - } - if (merge_value->is_list()) { - const base::ListValue* merge_list = nullptr; - if (merge_value->GetAsList(&merge_list)) { - base::ListValue* target_list = nullptr; - if (target->GetListWithoutPathExpansion(it.key(), &target_list)) { - for (size_t i = 0; i < merge_list->GetSize(); ++i) { - const base::Value* element = nullptr; - CHECK(merge_list->Get(i, &element)); - target_list->Append(element->CreateDeepCopy()); - } - continue; - } - } - } - // All other cases: Make a copy and hook it up. - target->SetKey(it.key(), merge_value->Clone()); - } -} - -} // namespace - -void MergeManifestWithOverlay(base::Value* manifest, base::Value* overlay) { - if (!overlay) - return; - - base::DictionaryValue* manifest_dictionary = nullptr; - bool result = manifest->GetAsDictionary(&manifest_dictionary); - DCHECK(result); - base::DictionaryValue* overlay_dictionary = nullptr; - result = overlay->GetAsDictionary(&overlay_dictionary); - DCHECK(result); - MergeDictionary(manifest_dictionary, overlay_dictionary); -} - -} // namespace service_manager
diff --git a/services/service_manager/embedder/manifest_utils.h b/services/service_manager/embedder/manifest_utils.h deleted file mode 100644 index a6af881..0000000 --- a/services/service_manager/embedder/manifest_utils.h +++ /dev/null
@@ -1,20 +0,0 @@ -// Copyright 2016 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 SERVICES_SERVICE_MANAGER_EMBEDDER_MANIFEST_UTILS_H_ -#define SERVICES_SERVICE_MANAGER_EMBEDDER_MANIFEST_UTILS_H_ - -#include "base/component_export.h" -#include "base/values.h" - -namespace service_manager { - -// Merges |overlay| (if not null) into |manifest|. -// Uses a strategy similar to base::DictionaryValue::MergeDictionary(), except -// concatenates ListValue contents. -void COMPONENT_EXPORT(SERVICE_MANAGER_EMBEDDER) - MergeManifestWithOverlay(base::Value* manifest, base::Value* overlay); -} // namespace service_manager - -#endif // SERVICES_SERVICE_MANAGER_EMBEDDER_MANIFEST_UTILS_H_
diff --git a/services/service_manager/embedder/manifest_utils_unittest.cc b/services/service_manager/embedder/manifest_utils_unittest.cc deleted file mode 100644 index 9d8e46ac..0000000 --- a/services/service_manager/embedder/manifest_utils_unittest.cc +++ /dev/null
@@ -1,70 +0,0 @@ -// Copyright 2016 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 "services/service_manager/embedder/manifest_utils.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace service_manager { - -TEST(MergeManifestWithOverlayTest, Merge) { - // |manifest| & |overlay| have three properties, "string", "list" and - // "dictionary", which are then merged. - base::DictionaryValue manifest; - manifest.SetString("string", "Hello, "); - std::unique_ptr<base::DictionaryValue> dict_value_original( - std::make_unique<base::DictionaryValue>()); - dict_value_original->SetString("key1", "original"); - dict_value_original->SetString("key3", "original"); - manifest.Set("dictionary", std::move(dict_value_original)); - std::unique_ptr<base::ListValue> list(std::make_unique<base::ListValue>()); - list->AppendString("A"); - list->AppendString("B"); - manifest.Set("list", std::move(list)); - - base::DictionaryValue overlay; - overlay.SetString("string", "World!"); - std::unique_ptr<base::DictionaryValue> dict_value_replacement( - std::make_unique<base::DictionaryValue>()); - dict_value_replacement->SetString("key1", "new"); - dict_value_replacement->SetString("key2", "new"); - overlay.Set("dictionary", std::move(dict_value_replacement)); - list = std::make_unique<base::ListValue>(); - list->AppendString("C"); - overlay.Set("list", std::move(list)); - - MergeManifestWithOverlay(&manifest, &overlay); - - // Simple string value should have been clobbered. - std::string out_string; - EXPECT_TRUE(manifest.GetString("string", &out_string)); - EXPECT_EQ(out_string, "World!"); - - // Dictionary should have been merged, with key1 being clobbered, key2 added - // and key3 preserved. - base::DictionaryValue* out_dictionary = nullptr; - EXPECT_TRUE(manifest.GetDictionary("dictionary", &out_dictionary)); - EXPECT_EQ(3u, out_dictionary->size()); - std::string value1, value2, value3; - EXPECT_TRUE(out_dictionary->GetString("key1", &value1)); - EXPECT_TRUE(out_dictionary->GetString("key2", &value2)); - EXPECT_TRUE(out_dictionary->GetString("key3", &value3)); - EXPECT_EQ(value1, "new"); - EXPECT_EQ(value2, "new"); - EXPECT_EQ(value3, "original"); - - // List should have been merged, with the items from overlay appended to the - // items from manifest. - base::ListValue* out_list = nullptr; - EXPECT_TRUE(manifest.GetList("list", &out_list)); - EXPECT_EQ(3u, out_list->GetSize()); - std::string a, b, c; - EXPECT_TRUE(out_list->GetString(0, &a)); - EXPECT_TRUE(out_list->GetString(1, &b)); - EXPECT_TRUE(out_list->GetString(2, &c)); - EXPECT_EQ("A", a); - EXPECT_EQ("B", b); - EXPECT_EQ("C", c); -} - -} // namespace service_manager
diff --git a/services/service_manager/public/cpp/manifest.cc b/services/service_manager/public/cpp/manifest.cc index e018583d..464ad43 100644 --- a/services/service_manager/public/cpp/manifest.cc +++ b/services/service_manager/public/cpp/manifest.cc
@@ -230,7 +230,7 @@ return manifest; } -void Manifest::Amend(Manifest other) { +Manifest& Manifest::Amend(Manifest other) { for (auto& other_capability : other.exposed_capabilities) { auto it = std::find_if( exposed_capabilities.begin(), exposed_capabilities.end(), @@ -272,6 +272,8 @@ packaged_services.emplace_back(std::move(manifest)); for (auto& file_info : other.preloaded_files) preloaded_files.emplace_back(std::move(file_info)); + + return *this; } } // namespace service_manager
diff --git a/services/service_manager/public/cpp/manifest.h b/services/service_manager/public/cpp/manifest.h index 684a60eb..12294aa 100644 --- a/services/service_manager/public/cpp/manifest.h +++ b/services/service_manager/public/cpp/manifest.h
@@ -267,7 +267,7 @@ // Amends this Manifest with a subset of |other|. Namely, exposed and required // capabilities, exposed and required interface filter capabilities, packaged // services, and preloaded files are all added from |other| if present. - void Amend(Manifest other); + Manifest& Amend(Manifest other); std::string service_name; DisplayName display_name;
diff --git a/services/service_manager/public/service_manifest.gni b/services/service_manager/public/service_manifest.gni index 1bf9463..b797200e 100644 --- a/services/service_manager/public/service_manifest.gni +++ b/services/service_manager/public/service_manifest.gni
@@ -4,65 +4,129 @@ import("//build/config/dcheck_always_on.gni") -# Used to produce a Service Manifest for a Service. +# Generates code to produce a compiled service_manager::Manifest from a JSON +# description at build time. # -# Service manifests may be subsequently aggregated into one or more catalog -# manifests (see //services/catalog/public/tools/catalog.gni). A catalog -# manifest provides the Service Manager at runtime with a static service layout -# configuration to dictate which services are supported by the runtime -# environment as well as how individual services may be launched and -# interconnected. +# This is a temporary helper for the transition away from JSON manifests. Do not +# introduce new service_manifest targets. # -# Note that this target may be used to produce partial manifests, and partial -# manifests may be aggregated by using one service_manifest target as the -# |source_manifest| of another (see below.) +# This template yields a source_set target which defines a symbol named +# "${name}::GetManifest()" where ${name} is the service name given in the +# target. # -# Parameters: -# -# source (optional**) -# The manifest template for this service. Must be the name of a valid JSON -# file. -# -# source_manifest (optional**) -# The manifest template for this service. Must be the name of another -# service_manifest target. -# -# ** NOTE: Either |source| OR |source_manifest| MUST be specified. -# -# name (optional) -# The name of the service whose manifest is to be generated. A script -# validates that the value of this parameter matches the name set in the -# source manifest and raises an error if it does not match. -# -# overlays (optional) -# A list of other manifest targets whose outputs should be overlayed onto -# the source manifest before emitting the final output. Overlays are -# applied in-order as the last step of output generation, after any -# |packaged_services| manifests are embedded. -# -# packaged_services (optional) -# A list of other manifest targets whose outputs should be packaged -# within this output manifest, specifically within a toplevel "services" -# list. -# -# testonly (optional) -# -# Outputs: -# -# An instantiation of this template produces a meta manifest from the source -# template and the output manifests of all its |overlay| and -# |packaged_services|dependencies. The output file is always -# "$target_gen_dir/${target_name}.json". -# +# All service_manifest targets should be replaced with in-tree C++ sources. template("service_manifest") { - assert( - defined(invoker.source) || defined(invoker.source_manifest), - "\"source\" or \"source_manifest\" must be defined for the $target_name target") - assert( - !defined(invoker.source) || !defined(invoker.source_manifest), - "Only one of \"source\" or \"source_manifest\" must be defined for the $target_name target") + assert(defined(invoker.source), + "\"source\" must be defined for the $target_name target") - action(target_name) { + generator_target_name = "${target_name}__generator" + generated_sources = [ + "$target_gen_dir/${target_name}.cc", + "$target_gen_dir/${target_name}.h", + ] + + # We prefer to use |name| for the generated function's namespace if a + # |generated_namespace| isn't explicitly defined. It turns out that we also + # have a few targets which don't specify a |name| though; they all have unique + # target names, so we fall back on that if necessary. The important detail is + # that all generated GetManifest() functions should live in their own + # namespace, and with the current (and final) set of service_manifest targets + # in the tree, these rules accomplish that. + if (defined(invoker.generated_namespace)) { + output_namespace = invoker.generated_namespace + } else if (defined(invoker.name)) { + output_namespace = invoker.name + } else { + output_namespace = invoker.target_name + } + + write_file("$target_gen_dir/${target_name}.namespace", output_namespace) + + source_set(target_name) { + testonly = defined(invoker.testonly) && invoker.testonly + sources = generated_sources + public_deps = [ + ":$generator_target_name", + ] + + deps = [] + if (defined(invoker.packaged_services)) { + deps += invoker.packaged_services + } + if (defined(invoker.overlays)) { + deps += invoker.overlays + } + } + + collator_target_name = "${target_name}__collator" + + action(generator_target_name) { + testonly = defined(invoker.testonly) && invoker.testonly + script = "//services/catalog/public/tools/sourcify_manifest.py" + + inputs = [ + "//services/catalog/public/tools/catalog.cc.tmpl", + "//services/catalog/public/tools/catalog.h.tmpl", + invoker.source, + ] + outputs = generated_sources + + submanifest_info = [] + if (defined(invoker.packaged_services)) { + foreach(submanifest, invoker.packaged_services) { + manifest_dir = get_label_info(submanifest, "target_gen_dir") + manifest_target_name = get_label_info(submanifest, "name") + manifest_namespace_input = + "$manifest_dir/${manifest_target_name}.namespace" + manifest_namespace_path = + rebase_path(manifest_namespace_input, root_build_dir) + manifest_header_base = + rebase_path(manifest_dir, root_gen_dir) + "/${manifest_target_name}" + submanifest_info += + [ "packaged@$manifest_namespace_path@$manifest_header_base" ] + } + } + if (defined(invoker.overlays)) { + foreach(submanifest, invoker.overlays) { + manifest_dir = get_label_info(submanifest, "target_gen_dir") + manifest_target_name = get_label_info(submanifest, "name") + manifest_namespace_input = + "$manifest_dir/${manifest_target_name}.namespace" + manifest_namespace_path = + rebase_path(manifest_namespace_input, root_build_dir) + manifest_header_base = + rebase_path(manifest_dir, root_gen_dir) + "/${manifest_target_name}" + submanifest_info += + [ "overlay@$manifest_namespace_path@$manifest_header_base" ] + } + } + + submanifest_info_file = + "${target_gen_dir}/${invoker.target_name}.submanifest_info" + write_file(submanifest_info_file, submanifest_info) + + args = [ + "--root-manifest=" + rebase_path(invoker.source, root_build_dir), + "--submanifest-info=" + + rebase_path(submanifest_info_file, root_build_dir), + "--output-function-name=${output_namespace}::GetManifest", + "--output-filename-base=" + + rebase_path("$target_gen_dir/${invoker.target_name}", root_build_dir), + "--module-path=" + + rebase_path("$target_gen_dir/${invoker.target_name}", root_gen_dir), + ] + + # We inherit a public dependency on the collator because service_manifest + # dependents still expect to use its generated JSON output. We don't + # actually depend on the collated JSON at all here, since packaged services + # and overlays are added in the generated C++ code by referring to other + # generated C++ code. + public_deps = [ + ":$collator_target_name", + ] + } + + action(collator_target_name) { testonly = defined(invoker.testonly) && invoker.testonly script = @@ -73,25 +137,16 @@ deps += invoker.deps } - if (defined(invoker.source)) { - source = invoker.source - } else { - source_target_dir = - get_label_info(invoker.source_manifest, "target_gen_dir") - source_target_name = get_label_info(invoker.source_manifest, "name") - source = "$source_target_dir/${source_target_name}.json" - deps += [ invoker.source_manifest ] - } inputs = [ - source, + invoker.source, ] - output = "$target_gen_dir/${target_name}.json" + output = "$target_gen_dir/${invoker.target_name}.json" outputs = [ output, ] - rebase_parent = rebase_path(source, root_build_dir) + rebase_parent = rebase_path(invoker.source, root_build_dir) rebase_output = rebase_path(output, root_build_dir) args = [
diff --git a/services/service_manager/service_manager.cc b/services/service_manager/service_manager.cc index a169c130..c42fa2a 100644 --- a/services/service_manager/service_manager.cc +++ b/services/service_manager/service_manager.cc
@@ -946,24 +946,42 @@ ServiceManager::ServiceManager(std::unique_ptr<ServiceProcessLauncherFactory> service_process_launcher_factory, - const std::vector<Manifest>& manifests, - catalog::ManifestProvider* manifest_provider) - : catalog_(nullptr, manifests, manifest_provider), + const std::vector<Manifest>& manifests) + : catalog_(manifests), identity_to_instance_(std::make_unique<IdentityToInstanceMap>()), service_process_launcher_factory_( std::move(service_process_launcher_factory)) { - InitBuiltinServices(); -} + InterfaceProviderSpec spec; + spec.provides[kCapability_ServiceManager].insert( + "service_manager.mojom.ServiceManager"); + spec.requires["*"].insert("service_manager:service_factory"); + InterfaceProviderSpecMap specs; + specs[mojom::kServiceManager_ConnectorSpec] = std::move(spec); -ServiceManager::ServiceManager(std::unique_ptr<ServiceProcessLauncherFactory> - service_process_launcher_factory, - std::unique_ptr<base::Value> catalog_contents, - catalog::ManifestProvider* manifest_provider) - : catalog_(std::move(catalog_contents), {}, manifest_provider), - identity_to_instance_(std::make_unique<IdentityToInstanceMap>()), - service_process_launcher_factory_( - std::move(service_process_launcher_factory)) { - InitBuiltinServices(); + service_manager_instance_ = CreateInstance( + GetServiceManagerInstanceIdentity(), InstanceType::kSingleton, + std::move(specs), catalog::ServiceOptions()); + + mojom::ServicePtr service; + service_binding_.Bind(mojo::MakeRequest(&service)); + service_manager_instance_->StartWithService(std::move(service)); + + InterfaceProviderSpec catalog_spec; + catalog_spec.provides["directory"].insert("filesystem.mojom.Directory"); + catalog_spec.provides["catalog:catalog"].insert("catalog.mojom.Catalog"); + catalog_spec.provides["control"].insert("catalog.mojom.CatalogControl"); + InterfaceProviderSpecMap catalog_specs; + catalog_specs[mojom::kServiceManager_ConnectorSpec] = std::move(catalog_spec); + + Identity id{catalog::mojom::kServiceName, kSystemInstanceGroup, base::Token{}, + base::Token::CreateRandom()}; + Instance* instance = + CreateInstance(id, InstanceType::kSingleton, std::move(catalog_specs), + catalog::ServiceOptions()); + + mojom::ServicePtr catalog_service; + catalog_.BindServiceRequest(mojo::MakeRequest(&catalog_service)); + instance->StartWithService(std::move(catalog_service)); } ServiceManager::~ServiceManager() { @@ -1218,43 +1236,6 @@ Connect(std::move(params)); } -//////////////////////////////////////////////////////////////////////////////// -// ServiceManager, private: - -void ServiceManager::InitBuiltinServices() { - InterfaceProviderSpec spec; - spec.provides[kCapability_ServiceManager].insert( - "service_manager.mojom.ServiceManager"); - spec.requires["*"].insert("service_manager:service_factory"); - InterfaceProviderSpecMap specs; - specs[mojom::kServiceManager_ConnectorSpec] = std::move(spec); - - service_manager_instance_ = CreateInstance( - GetServiceManagerInstanceIdentity(), InstanceType::kSingleton, - std::move(specs), catalog::ServiceOptions()); - - mojom::ServicePtr service; - service_binding_.Bind(mojo::MakeRequest(&service)); - service_manager_instance_->StartWithService(std::move(service)); - - InterfaceProviderSpec catalog_spec; - catalog_spec.provides["directory"].insert("filesystem.mojom.Directory"); - catalog_spec.provides["catalog:catalog"].insert("catalog.mojom.Catalog"); - catalog_spec.provides["control"].insert("catalog.mojom.CatalogControl"); - InterfaceProviderSpecMap catalog_specs; - catalog_specs[mojom::kServiceManager_ConnectorSpec] = std::move(catalog_spec); - - Identity id{catalog::mojom::kServiceName, kSystemInstanceGroup, base::Token{}, - base::Token::CreateRandom()}; - Instance* instance = - CreateInstance(id, InstanceType::kSingleton, std::move(catalog_specs), - catalog::ServiceOptions()); - - mojom::ServicePtr catalog_service; - catalog_.BindServiceRequest(mojo::MakeRequest(&catalog_service)); - instance->StartWithService(std::move(catalog_service)); -} - void ServiceManager::OnInstanceError(Instance* instance) { // We never clean up the ServiceManager's own instance. if (instance == service_manager_instance_)
diff --git a/services/service_manager/service_manager.h b/services/service_manager/service_manager.h index 2a046f9..8bf2428 100644 --- a/services/service_manager/service_manager.h +++ b/services/service_manager/service_manager.h
@@ -12,7 +12,6 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/process/process.h" -#include "base/values.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "mojo/public/cpp/bindings/interface_ptr_set.h" #include "services/catalog/catalog.h" @@ -29,11 +28,6 @@ #include "services/service_manager/public/mojom/service_factory.mojom.h" #include "services/service_manager/public/mojom/service_manager.mojom.h" #include "services/service_manager/runner/host/service_process_launcher_factory.h" -#include "services/service_manager/service_overrides.h" - -namespace catalog { -class ManifestProvider; -} namespace service_manager { @@ -50,25 +44,9 @@ // |service_process_launcher_factory| is an instance of an object capable of // vending implementations of ServiceProcessLauncher, e.g. for out-of-process // execution. - explicit ServiceManager( - std::unique_ptr<ServiceProcessLauncherFactory> - service_process_launcher_factory, - const std::vector<Manifest>& manifests, - catalog::ManifestProvider* manifest_provider = nullptr); - - // |service_process_launcher_factory| is an instance of an object capable of - // vending implementations of ServiceProcessLauncher, e.g. for out-of-process - // execution. - // - // |catalog_contents|, if not null, will be used to prepoulate the service - // manager catalog with a fixed data set. |manifest_provider|, if not null, - // will be consulted for dynamic manifest resolution if a manifest is not - // found within the catalog; if used, |manifest_provider| is not owned and - // must outlive this ServiceManager. - ServiceManager(std::unique_ptr<ServiceProcessLauncherFactory> - service_process_launcher_factory, - std::unique_ptr<base::Value> catalog_contents, - catalog::ManifestProvider* manifest_provider); + explicit ServiceManager(std::unique_ptr<ServiceProcessLauncherFactory> + service_process_launcher_factory, + const std::vector<Manifest>& manifests); ~ServiceManager() override; // Provide a callback to be notified whenever an instance is destroyed. @@ -128,8 +106,6 @@ kSingleton, }; - void InitBuiltinServices(); - // Called when |instance| encounters an error. Deletes |instance|. void OnInstanceError(Instance* instance);
diff --git a/services/service_manager/service_overrides.cc b/services/service_manager/service_overrides.cc deleted file mode 100644 index 2dfa8b5..0000000 --- a/services/service_manager/service_overrides.cc +++ /dev/null
@@ -1,78 +0,0 @@ -// Copyright 2016 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 "services/service_manager/service_overrides.h" - -#include "base/base_paths.h" -#include "base/path_service.h" -#include "base/strings/string_util.h" -#include "base/strings/utf_string_conversions.h" - -namespace service_manager { - -namespace { - -const char kExecutablePathKey[] = "executable_path"; -const char kPackageNameKey[] = "package_name"; - -} // namespace - -ServiceOverrides::Entry::Entry() {} - -ServiceOverrides::Entry::~Entry() {} - -ServiceOverrides::ServiceOverrides(std::unique_ptr<base::Value> overrides) { - const base::DictionaryValue* services; - if (!overrides->GetAsDictionary(&services)) { - LOG(ERROR) << "Expected top-level dictionary."; - return; - } - - base::DictionaryValue::Iterator service_iter(*services); - for (; !service_iter.IsAtEnd(); service_iter.Advance()) { - Entry& new_entry = entries_[service_iter.key()]; - - const base::DictionaryValue* value; - if (!service_iter.value().GetAsDictionary(&value)) { - LOG(ERROR) << "Expected service entry to be a dictionary."; - return; - } - - std::string executable_path_value; - if (value->GetString(kExecutablePathKey, &executable_path_value)) { - base::FilePath exe_dir; - CHECK(base::PathService::Get(base::DIR_EXE, &exe_dir)); -#if defined(OS_WIN) - executable_path_value += ".exe"; - base::ReplaceFirstSubstringAfterOffset( - &executable_path_value, 0, "@EXE_DIR", - base::UTF16ToUTF8(exe_dir.value())); - new_entry.executable_path = - base::FilePath(base::UTF8ToUTF16(executable_path_value)); -#else - base::ReplaceFirstSubstringAfterOffset( - &executable_path_value, 0, "@EXE_DIR", - exe_dir.value()); - new_entry.executable_path = base::FilePath(executable_path_value); -#endif - } - - value->GetString(kPackageNameKey, &new_entry.package_name); - } -} - -ServiceOverrides::~ServiceOverrides() {} - -bool ServiceOverrides::GetExecutablePathOverride( - const std::string& service_name, - base::FilePath* path) const { - auto iter = entries_.find(service_name); - if (iter == entries_.end() || iter->second.executable_path.empty()) - return false; - - *path = iter->second.executable_path; - return true; -} - -} // namespace service_manager
diff --git a/services/service_manager/service_overrides.h b/services/service_manager/service_overrides.h deleted file mode 100644 index 1478ef76..0000000 --- a/services/service_manager/service_overrides.h +++ /dev/null
@@ -1,44 +0,0 @@ -// Copyright 2016 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 SERVICES_SERVICE_MANAGER_SERVICE_OVERRIDES_H_ -#define SERVICES_SERVICE_MANAGER_SERVICE_OVERRIDES_H_ - -#include <map> -#include <memory> -#include <string> - -#include "base/files/file_path.h" -#include "base/macros.h" -#include "base/values.h" - -namespace service_manager { - -class ServiceOverrides { - public: - struct Entry { - Entry(); - ~Entry(); - - base::FilePath executable_path; - std::string package_name; - }; - - explicit ServiceOverrides(std::unique_ptr<base::Value> overrides); - ~ServiceOverrides(); - - bool GetExecutablePathOverride(const std::string& service_name, - base::FilePath* path) const; - - const std::map<std::string, Entry>& entries() const { return entries_; } - - private: - std::map<std::string, Entry> entries_; - - DISALLOW_COPY_AND_ASSIGN(ServiceOverrides); -}; - -} // namespace service_manager - -#endif // SERVICES_SERVICE_MANAGER_SERVICE_OVERRIDES_H_
diff --git a/services/service_manager/standalone/context.cc b/services/service_manager/standalone/context.cc index b7908da..12594f8 100644 --- a/services/service_manager/standalone/context.cc +++ b/services/service_manager/standalone/context.cc
@@ -70,21 +70,7 @@ Context::Context( ServiceProcessLauncherDelegate* service_process_launcher_delegate, - const std::vector<Manifest>& manifests) - : Context(service_process_launcher_delegate, nullptr, manifests) {} - -Context::Context( - ServiceProcessLauncherDelegate* service_process_launcher_delegate, - std::unique_ptr<base::Value> catalog_contents) - : Context(service_process_launcher_delegate, - std::move(catalog_contents), - std::vector<Manifest>()) {} - -Context::Context( - ServiceProcessLauncherDelegate* service_process_launcher_delegate, - std::unique_ptr<base::Value> catalog_contents, - const std::vector<Manifest>& manifests) - : main_entry_time_(base::Time::Now()) { + const std::vector<Manifest>& manifests) { TRACE_EVENT0("service_manager", "Context::Context"); std::unique_ptr<ServiceProcessLauncherFactory> @@ -97,14 +83,8 @@ std::make_unique<ServiceProcessLauncherFactoryImpl>( service_process_launcher_delegate); #endif - if (!manifests.empty()) { - service_manager_ = std::make_unique<ServiceManager>( - std::move(service_process_launcher_factory), manifests, nullptr); - } else { - service_manager_ = std::make_unique<ServiceManager>( - std::move(service_process_launcher_factory), - std::move(catalog_contents), nullptr); - } + service_manager_ = std::make_unique<ServiceManager>( + std::move(service_process_launcher_factory), manifests); } Context::~Context() = default;
diff --git a/services/service_manager/standalone/context.h b/services/service_manager/standalone/context.h index 2fc0c97aa..234a9aa 100644 --- a/services/service_manager/standalone/context.h +++ b/services/service_manager/standalone/context.h
@@ -11,7 +11,6 @@ #include "base/callback.h" #include "base/macros.h" #include "base/time/time.h" -#include "base/values.h" #include "services/service_manager/public/cpp/manifest.h" #include "services/service_manager/runner/host/service_process_launcher_delegate.h" @@ -24,11 +23,6 @@ public: Context(ServiceProcessLauncherDelegate* launcher_delegate, const std::vector<Manifest>& manifests); - Context(ServiceProcessLauncherDelegate* launcher_delegate, - std::unique_ptr<base::Value> catalog_contents); - Context(ServiceProcessLauncherDelegate* launcher_delegate, - std::unique_ptr<base::Value> catalog_contents, - const std::vector<Manifest>& manifests); ~Context(); // Run the application specified on the command line, and run |on_quit| when
diff --git a/services/service_manager/tests/BUILD.gn b/services/service_manager/tests/BUILD.gn index b3cc60a..db89a4b 100644 --- a/services/service_manager/tests/BUILD.gn +++ b/services/service_manager/tests/BUILD.gn
@@ -26,11 +26,9 @@ "//mojo/public/cpp/bindings", "//mojo/public/cpp/system", "//services/catalog:lib", - "//services/catalog:unittests", "//services/service_manager", "//services/service_manager/background:lib", "//services/service_manager/background/tests:unittests", - "//services/service_manager/embedder:unittests", "//services/service_manager/public/cpp", "//services/service_manager/public/cpp:unittests", "//services/service_manager/public/cpp/test:test_support",
diff --git a/services/service_manager/tests/service_manager/service_manager_listener_unittest.cc b/services/service_manager/tests/service_manager/service_manager_listener_unittest.cc index e922c84..6927e6c8 100644 --- a/services/service_manager/tests/service_manager/service_manager_listener_unittest.cc +++ b/services/service_manager/tests/service_manager/service_manager_listener_unittest.cc
@@ -103,7 +103,8 @@ class ServiceManagerListenerTest : public testing::Test, public Service { public: ServiceManagerListenerTest() - : service_manager_(nullptr, GetTestManifests(), nullptr) {} + : service_manager_(nullptr, GetTestManifests()) {} + ~ServiceManagerListenerTest() override = default; Connector* connector() { return service_binding_.GetConnector(); }
diff --git a/services/viz/public/cpp/compositing/compositor_frame_metadata_struct_traits.cc b/services/viz/public/cpp/compositing/compositor_frame_metadata_struct_traits.cc index 6e932e4..8175112 100644 --- a/services/viz/public/cpp/compositing/compositor_frame_metadata_struct_traits.cc +++ b/services/viz/public/cpp/compositing/compositor_frame_metadata_struct_traits.cc
@@ -32,7 +32,6 @@ out->content_source_id = data.content_source_id(); out->frame_token = data.frame_token(); out->send_frame_token_to_embedder = data.send_frame_token_to_embedder(); - out->request_presentation_feedback = data.request_presentation_feedback(); out->root_background_color = data.root_background_color(); out->min_page_scale_factor = data.min_page_scale_factor(); out->top_controls_height = data.top_controls_height();
diff --git a/services/viz/public/cpp/compositing/compositor_frame_metadata_struct_traits.h b/services/viz/public/cpp/compositing/compositor_frame_metadata_struct_traits.h index c63c28c..4c1f33e 100644 --- a/services/viz/public/cpp/compositing/compositor_frame_metadata_struct_traits.h +++ b/services/viz/public/cpp/compositing/compositor_frame_metadata_struct_traits.h
@@ -92,11 +92,6 @@ return metadata.send_frame_token_to_embedder; } - static bool request_presentation_feedback( - const viz::CompositorFrameMetadata& metadata) { - return metadata.request_presentation_feedback; - } - static float min_page_scale_factor( const viz::CompositorFrameMetadata& metadata) { return metadata.min_page_scale_factor;
diff --git a/services/viz/public/interfaces/compositing/compositor_frame_metadata.mojom b/services/viz/public/interfaces/compositing/compositor_frame_metadata.mojom index 2b09a55..c5ebc770 100644 --- a/services/viz/public/interfaces/compositing/compositor_frame_metadata.mojom +++ b/services/viz/public/interfaces/compositing/compositor_frame_metadata.mojom
@@ -30,7 +30,6 @@ BeginFrameAck begin_frame_ack; uint32 frame_token; bool send_frame_token_to_embedder; - bool request_presentation_feedback; float min_page_scale_factor;
diff --git a/third_party/arcore-android-sdk/BUILD.gn b/third_party/arcore-android-sdk/BUILD.gn index 9f7d9e4..c6b23c1 100644 --- a/third_party/arcore-android-sdk/BUILD.gn +++ b/third_party/arcore-android-sdk/BUILD.gn
@@ -4,6 +4,12 @@ import("//build/config/android/rules.gni") +java_prebuilt("libdynamite_client_java") { + supports_android = true + proguard_configs = [ "proguard-arcore.txt" ] + jar_path = "libarcore_client_c.jar" +} + config("libarcore_config") { include_dirs = [ "src/libraries/include/" ] }
diff --git a/third_party/arcore-android-sdk/README.chromium b/third_party/arcore-android-sdk/README.chromium index 86ba41a..1d04387 100644 --- a/third_party/arcore-android-sdk/README.chromium +++ b/third_party/arcore-android-sdk/README.chromium
@@ -1,7 +1,8 @@ Name: ARCore SDK Short Name: arcore URL: https://github.com/google-ar/arcore-android-sdk -Version: 1.5 +Version: 1.1 +Date: 19 March 2018 License: Apache 2.0 License File: LICENSE Security Critical: yes @@ -11,7 +12,11 @@ devices. Local Modifications: -Added BUILD.gn for compilation in chrome. +To address binary size concerns, we are using a minimal shim produced for +Chromium that is not publicly distributed elsewhere. We have also stripped the +.so's to minimize their size. + +Also, added BUILD.gn for compilation in chrome. Added the test-apks/ subdirectory for storing production versions of AR APKs, namely ArCore, for testing. @@ -24,8 +29,6 @@ * https://github.com/google-ar/arcore-unity-sdk/blob/master/LICENSE Changes: -2018-12-11 - Upgrade ARCore to v1.5. Remove checked in .so files - we now - extract them from ARCore's .aar file at build time. 2018-12-11 - Upgrade test-apks/arcore_current.apk to v1.6. 2018-09-14 - Upgrade test-apks/arcore_current.apk to v1.4. 2018-08-10 - First, removed arcore shim copy target from BUILD.gn since it is no
diff --git a/third_party/arcore-android-sdk/libarcore_client_c.jar b/third_party/arcore-android-sdk/libarcore_client_c.jar new file mode 100644 index 0000000..335fe92 --- /dev/null +++ b/third_party/arcore-android-sdk/libarcore_client_c.jar Binary files differ
diff --git a/third_party/arcore-android-sdk/libarcore_dummy.so b/third_party/arcore-android-sdk/libarcore_dummy.so new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/third_party/arcore-android-sdk/libarcore_dummy.so
diff --git a/third_party/arcore-android-sdk/libraries/android_arm/libarcore_sdk_c_minimal.so b/third_party/arcore-android-sdk/libraries/android_arm/libarcore_sdk_c_minimal.so new file mode 100755 index 0000000..ce3ab2df --- /dev/null +++ b/third_party/arcore-android-sdk/libraries/android_arm/libarcore_sdk_c_minimal.so Binary files differ
diff --git a/third_party/arcore-android-sdk/libraries/android_arm64/libarcore_sdk_c_minimal.so b/third_party/arcore-android-sdk/libraries/android_arm64/libarcore_sdk_c_minimal.so new file mode 100755 index 0000000..cfd9654f --- /dev/null +++ b/third_party/arcore-android-sdk/libraries/android_arm64/libarcore_sdk_c_minimal.so Binary files differ
diff --git a/third_party/arcore-android-sdk/proguard-arcore.txt b/third_party/arcore-android-sdk/proguard-arcore.txt new file mode 100644 index 0000000..b1c85042 --- /dev/null +++ b/third_party/arcore-android-sdk/proguard-arcore.txt
@@ -0,0 +1,41 @@ +# Keep ARCore public-facing classes +-keepparameternames +-renamesourcefileattribute SourceFile + +# These are part of the Java <-> native interfaces for ARCore. +-keepclasseswithmembernames,includedescriptorclasses class com.google.ar.** { + native <methods>; +} + +-keep public class com.google.ar.core.** {*;} + +-keep class com.google.ar.core.annotations.UsedByNative +-keep @com.google.ar.core.annotations.UsedByNative class * +-keepclassmembers class * { + @com.google.ar.core.annotations.UsedByNative *; +} + +-keep class com.google.ar.core.annotations.UsedByReflection +-keep @com.google.ar.core.annotations.UsedByReflection class * +-keepclassmembers class * { + @com.google.ar.core.annotations.UsedByReflection *; +} +# Keep Dynamite classes + +# .aidl file will be proguarded, we should keep all Aidls. +-keep class com.google.vr.dynamite.client.IObjectWrapper { *; } +-keep class com.google.vr.dynamite.client.ILoadedInstanceCreator { *; } +-keep class com.google.vr.dynamite.client.INativeLibraryLoader { *; } + +# Keep annotation files and the file got annotated. +-keep class com.google.vr.dynamite.client.UsedByNative +-keep @com.google.vr.dynamite.client.UsedByNative class * +-keepclassmembers class * { + @com.google.vr.dynamite.client.UsedByNative *; +} + +-keep class com.google.vr.dynamite.client.UsedByReflection +-keep @com.google.vr.dynamite.client.UsedByReflection class * +-keepclassmembers class * { + @com.google.vr.dynamite.client.UsedByReflection *; +}
diff --git a/third_party/blink/public/web/web_navigation_control.h b/third_party/blink/public/web/web_navigation_control.h index 5492cba..271c97bb 100644 --- a/third_party/blink/public/web/web_navigation_control.h +++ b/third_party/blink/public/web/web_navigation_control.h
@@ -17,6 +17,7 @@ class WebURL; struct WebURLError; class WebHistoryItem; +struct WebNavigationInfo; struct WebNavigationParams; // This interface gives control to navigation-related functionality of @@ -92,8 +93,7 @@ // is actually being handled by the client. // TODO(dgozman): remove this together with placeholder document loader. virtual bool CreatePlaceholderDocumentLoader( - std::unique_ptr<WebNavigationParams>, - WebNavigationType, + const WebNavigationInfo&, std::unique_ptr<WebDocumentLoader::ExtraData>) = 0; protected:
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.cc b/third_party/blink/renderer/core/display_lock/display_lock_context.cc index 5e631a67..d58b177 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_context.cc +++ b/third_party/blink/renderer/core/display_lock/display_lock_context.cc
@@ -139,8 +139,8 @@ } ScriptPromise DisplayLockContext::update(ScriptState* script_state) { - // Reject if we're unlocked. - if (state_ == kUnlocked) + // Reject if we're unlocked or disconnected. + if (state_ == kUnlocked || !element_->isConnected()) return GetRejectedPromise(script_state); // If we have a resolver, then we're at least updating already, just return @@ -151,16 +151,13 @@ } update_resolver_ = ScriptPromiseResolver::Create(script_state); - // We only need to kick off an Update if we're in a locked state, all other - // states are already updating. - if (state_ == kLocked) - StartUpdate(); + StartUpdateIfNeeded(); return update_resolver_->Promise(); } ScriptPromise DisplayLockContext::commit(ScriptState* script_state) { - // Reject if we're unlocked. - if (state_ == kUnlocked) + // Reject if we're unlocked or disonnected. + if (state_ == kUnlocked || !element_->isConnected()) return GetRejectedPromise(script_state); // If we have a resolver, we must be committing already, just return the same @@ -391,12 +388,19 @@ layout_invalidation_reason::kDisplayLockCommitting); } -void DisplayLockContext::StartUpdate() { - DCHECK_EQ(state_, kLocked); - state_ = kUpdating; +void DisplayLockContext::StartUpdateIfNeeded() { + // We should not be calling this if we're unlocked. + DCHECK_NE(state_, kUnlocked); + // Any state other than kLocked means that we are already in the process of + // updating/committing, so we can piggy back on that process without kicking + // off any new updates. + if (state_ != kLocked) + return; + // We don't need to mark anything dirty since the budget will take care of // that for us. update_budget_ = CreateNewBudget(); + state_ = kUpdating; ScheduleAnimation(); } @@ -509,6 +513,8 @@ } void DisplayLockContext::ScheduleAnimation() { + DCHECK(element_->isConnected()); + // Schedule an animation to perform the lifecycle phases. element_->GetDocument().GetPage()->Animator().ScheduleVisualUpdate( element_->GetDocument().GetFrame());
diff --git a/third_party/blink/renderer/core/display_lock/display_lock_context.h b/third_party/blink/renderer/core/display_lock/display_lock_context.h index b8956f9..06c767c 100644 --- a/third_party/blink/renderer/core/display_lock/display_lock_context.h +++ b/third_party/blink/renderer/core/display_lock/display_lock_context.h
@@ -149,7 +149,7 @@ // Initiate a commit. void StartCommit(); // Initiate an update. - void StartUpdate(); + void StartUpdateIfNeeded(); // The following functions propagate dirty bits from the locked element up to // the ancestors in order to be reached. They return true if the element or
diff --git a/third_party/blink/renderer/core/editing/commands/editor_command.cc b/third_party/blink/renderer/core/editing/commands/editor_command.cc index 2e631eeb..ccb6ef7 100644 --- a/third_party/blink/renderer/core/editing/commands/editor_command.cc +++ b/third_party/blink/renderer/core/editing/commands/editor_command.cc
@@ -60,6 +60,7 @@ #include "third_party/blink/renderer/core/editing/visible_position.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" +#include "third_party/blink/renderer/core/html/html_br_element.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/input/event_handler.h" #include "third_party/blink/renderer/core/page/chrome_client.h" @@ -1185,6 +1186,13 @@ if (Node* root = HighestEditableRoot(selection.Start())) { if (!root->hasChildren()) return false; + + // When the editable contains a BR only, it appears as an empty line, in + // which case allowing select-all confuses users. + if (root->firstChild() == root->lastChild() && + IsHTMLBRElement(root->firstChild())) + return false; + // TODO(amaralp): Return false if already fully selected. } // TODO(amaralp): Address user-select handling.
diff --git a/third_party/blink/renderer/core/exported/web_frame_test.cc b/third_party/blink/renderer/core/exported/web_frame_test.cc index cb3816c..72d0d17 100644 --- a/third_party/blink/renderer/core/exported/web_frame_test.cc +++ b/third_party/blink/renderer/core/exported/web_frame_test.cc
@@ -12538,9 +12538,7 @@ TestWebFrameClient::BeginNavigation(std::move(info)); return; } - Frame()->CreatePlaceholderDocumentLoader( - WebNavigationParams::CreateFromInfo(*info), info->navigation_type, - nullptr /* extra_data */); + Frame()->CreatePlaceholderDocumentLoader(*info, nullptr /* extra_data */); } private:
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index f9d1baf5..bca23d8 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -2195,13 +2195,12 @@ } bool WebLocalFrameImpl::CreatePlaceholderDocumentLoader( - std::unique_ptr<WebNavigationParams> navigation_params, - WebNavigationType navigation_type, + const WebNavigationInfo& info, std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) { - DCHECK(!navigation_params->request.IsNull()); - DCHECK(!navigation_params->request.Url().ProtocolIs("javascript")); + DCHECK(!info.url_request.IsNull()); + DCHECK(!info.url_request.Url().ProtocolIs("javascript")); return GetFrame()->Loader().CreatePlaceholderDocumentLoader( - std::move(navigation_params), navigation_type, std::move(extra_data)); + info, std::move(extra_data)); } void WebLocalFrameImpl::SendOrientationChangeEvent() {
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h index ca6ec16..99644b9 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -319,8 +319,7 @@ void ClientDroppedNavigation() override; void MarkAsLoading() override; bool CreatePlaceholderDocumentLoader( - std::unique_ptr<WebNavigationParams>, - WebNavigationType, + const WebNavigationInfo&, std::unique_ptr<WebDocumentLoader::ExtraData>) override; void InitializeCoreFrame(Page&, FrameOwner*, const AtomicString& name);
diff --git a/third_party/blink/renderer/core/inspector/dev_tools_host.cc b/third_party/blink/renderer/core/inspector/dev_tools_host.cc index 64c10cbf..4b454e0 100644 --- a/third_party/blink/renderer/core/inspector/dev_tools_host.cc +++ b/third_party/blink/renderer/core/inspector/dev_tools_host.cc
@@ -44,7 +44,6 @@ #include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h" #include "third_party/blink/renderer/core/input/context_menu_allowed_scope.h" #include "third_party/blink/renderer/core/inspector/inspector_frontend_client.h" -#include "third_party/blink/renderer/core/layout/layout_theme.h" #include "third_party/blink/renderer/core/loader/frame_loader.h" #include "third_party/blink/renderer/core/page/chrome_client.h" #include "third_party/blink/renderer/core/page/context_menu_controller.h" @@ -214,27 +213,6 @@ } } -String DevToolsHost::getSelectionBackgroundColor() { - return LayoutTheme::GetTheme().ActiveSelectionBackgroundColor().Serialized(); -} - -String DevToolsHost::getSelectionForegroundColor() { - return LayoutTheme::GetTheme().ActiveSelectionForegroundColor().Serialized(); -} - -String DevToolsHost::getInactiveSelectionBackgroundColor() { - return LayoutTheme::GetTheme() - .InactiveSelectionBackgroundColor() - .Serialized(); -} - -String DevToolsHost::getInactiveSelectionForegroundColor() { - return LayoutTheme::GetTheme() - .InactiveSelectionForegroundColor() - .Serialized(); -} - - bool DevToolsHost::isHostedMode() { return false; }
diff --git a/third_party/blink/renderer/core/inspector/dev_tools_host.h b/third_party/blink/renderer/core/inspector/dev_tools_host.h index 7e47396..8f35f29 100644 --- a/third_party/blink/renderer/core/inspector/dev_tools_host.h +++ b/third_party/blink/renderer/core/inspector/dev_tools_host.h
@@ -69,11 +69,6 @@ WebVector<WebMenuItemInfo> items); void sendMessageToEmbedder(const String& message); - String getSelectionBackgroundColor(); - String getSelectionForegroundColor(); - String getInactiveSelectionBackgroundColor(); - String getInactiveSelectionForegroundColor(); - bool isHostedMode(); LocalFrame* FrontendFrame() { return frontend_frame_; }
diff --git a/third_party/blink/renderer/core/inspector/dev_tools_host.idl b/third_party/blink/renderer/core/inspector/dev_tools_host.idl index cd4481da..1586096 100644 --- a/third_party/blink/renderer/core/inspector/dev_tools_host.idl +++ b/third_party/blink/renderer/core/inspector/dev_tools_host.idl
@@ -41,10 +41,5 @@ [Custom] void showContextMenuAtPoint(float x, float y, any items, optional Document document); void sendMessageToEmbedder(DOMString message); - DOMString getSelectionBackgroundColor(); - DOMString getSelectionForegroundColor(); - DOMString getInactiveSelectionBackgroundColor(); - DOMString getInactiveSelectionForegroundColor(); - boolean isHostedMode(); };
diff --git a/third_party/blink/renderer/core/loader/frame_loader.cc b/third_party/blink/renderer/core/loader/frame_loader.cc index 697a18b..ee8a02e 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.cc +++ b/third_party/blink/renderer/core/loader/frame_loader.cc
@@ -1121,8 +1121,7 @@ } bool FrameLoader::CreatePlaceholderDocumentLoader( - std::unique_ptr<WebNavigationParams> navigation_params, - WebNavigationType navigation_type, + const WebNavigationInfo& info, std::unique_ptr<WebDocumentLoader::ExtraData> extra_data) { if (!CancelProvisionalLoaderForNewNavigation( true /* cancel_scheduled_navigations */, @@ -1130,8 +1129,14 @@ return false; } - provisional_document_loader_ = CreateDocumentLoader( - navigation_type, std::move(navigation_params), std::move(extra_data)); + auto navigation_params = std::make_unique<WebNavigationParams>(); + navigation_params->request = info.url_request; + navigation_params->frame_load_type = info.frame_load_type; + navigation_params->is_client_redirect = info.is_client_redirect; + navigation_params->navigation_timings.input_start = info.input_start; + provisional_document_loader_ = + CreateDocumentLoader(info.navigation_type, std::move(navigation_params), + std::move(extra_data)); provisional_document_loader_->AppendRedirect( provisional_document_loader_->Url()); frame_->GetFrameScheduler()->DidStartProvisionalLoad(frame_->IsMainFrame());
diff --git a/third_party/blink/renderer/core/loader/frame_loader.h b/third_party/blink/renderer/core/loader/frame_loader.h index e284aba..b2bb56586 100644 --- a/third_party/blink/renderer/core/loader/frame_loader.h +++ b/third_party/blink/renderer/core/loader/frame_loader.h
@@ -66,6 +66,7 @@ class SerializedScriptValue; class TracedValue; struct FrameLoadRequest; +struct WebNavigationInfo; struct WebNavigationParams; namespace mojom { @@ -125,8 +126,7 @@ // lives temporarily so that the rest of Blink code knows the navigation // is in place. bool CreatePlaceholderDocumentLoader( - std::unique_ptr<WebNavigationParams>, - WebNavigationType, + const WebNavigationInfo&, std::unique_ptr<WebDocumentLoader::ExtraData>); // This runs the "stop document loading" algorithm in HTML:
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc index 38f5047..d58c79e 100644 --- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc +++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -1019,6 +1019,11 @@ // Now hit test ourselves. if (hit_test_self && VisibleToHitTestRequest(result.GetHitTestRequest())) { LayoutRect bounds_rect(physical_offset, size); + if (UNLIKELY(result.GetHitTestRequest().GetType() & + HitTestRequest::kHitTestVisualOverflow)) { + bounds_rect = PhysicalFragment().SelfInkOverflow().ToLayoutRect(); + bounds_rect.MoveBy(physical_offset); + } if (location_in_container.Intersects(bounds_rect)) { Node* node = box_fragment_.NodeForHitTest(); if (!result.InnerNode() && node) { @@ -1067,6 +1072,12 @@ // TODO(layout-dev): Clip to line-top/bottom. LayoutRect rect = LayoutRect(PixelSnappedIntRect(border_rect)); + if (UNLIKELY(result.GetHitTestRequest().GetType() & + HitTestRequest::kHitTestVisualOverflow)) { + rect = text_paint_fragment.SelfInkOverflow(); + rect.MoveBy(border_rect.Location()); + } + if (FragmentVisibleToHitTestRequest(text_paint_fragment, result.GetHitTestRequest()) && location_in_container.Intersects(rect)) {
diff --git a/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js b/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js index 7627ba2..010108b 100644 --- a/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js +++ b/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js
@@ -320,35 +320,31 @@ */ const InspectorFrontendHostImpl = class { /** - * @override * @return {string} */ getSelectionBackgroundColor() { - return DevToolsHost.getSelectionBackgroundColor(); + return '#6e86ff'; } /** - * @override * @return {string} */ getSelectionForegroundColor() { - return DevToolsHost.getSelectionForegroundColor(); + return '#ffffff'; } /** - * @override * @return {string} */ getInactiveSelectionBackgroundColor() { - return DevToolsHost.getInactiveSelectionBackgroundColor(); + return '#c9c8c8'; } /** - * @override * @return {string} */ getInactiveSelectionForegroundColor() { - return DevToolsHost.getInactiveSelectionForegroundColor(); + return '#323232'; } /**
diff --git a/third_party/blink/renderer/devtools/front_end/elements/elementsTreeOutline.css b/third_party/blink/renderer/devtools/front_end/elements/elementsTreeOutline.css index 78d8f5a..31e1a8f 100644 --- a/third_party/blink/renderer/devtools/front_end/elements/elementsTreeOutline.css +++ b/third_party/blink/renderer/devtools/front_end/elements/elementsTreeOutline.css
@@ -36,11 +36,6 @@ .elements-disclosure .elements-tree-outline:not(.hide-selection-when-blurred) li.selected .selected-hint:before { opacity: 0.6; - color: var(--selection-inactive-fg-color); -} - -.elements-disclosure li.selected:focus .selected-hint:before { - color: var(--selection-fg-color); } .elements-disclosure li.parent::before { @@ -94,7 +89,7 @@ } .elements-disclosure .elements-tree-outline:not(.hide-selection-when-blurred) .selection { - background-color: var(--selection-inactive-bg-color); + background-color: var(--editor-selection-inactive-bg-color); } .elements-disclosure .elements-tree-outline.hide-selection-when-blurred .selected:focus[data-keyboard-focus="true"] .highlight > * { @@ -131,20 +126,8 @@ padding-left: 2px; } -.elements-disclosure .elements-tree-outline:not(.hide-selection-when-blurred) li.selected:focus { - color: var(--selection-fg-color); -} - -.elements-disclosure .elements-tree-outline:not(.hide-selection-when-blurred) li.parent.selected:focus::before { - background-color: var(--selection-fg-color); -} - -.elements-disclosure .elements-tree-outline:not(.hide-selection-when-blurred) li.selected:focus * { - color: inherit; -} - .elements-disclosure .elements-tree-outline:not(.hide-selection-when-blurred) li.selected:focus .selection { - background-color: var(--selection-bg-color); + background-color: var(--editor-selection-bg-color); } .elements-tree-outline ol.shadow-root-depth-4 { @@ -308,13 +291,6 @@ display: none; } -.elements-tree-outline:not(.hide-selection-when-blurred) li.selected:focus .webkit-html-tag-name, -.elements-tree-outline:not(.hide-selection-when-blurred) li.selected:focus .webkit-html-close-tag-name, -.elements-tree-outline:not(.hide-selection-when-blurred) li.selected:focus .webkit-html-attribute-value, -.elements-tree-outline:not(.hide-selection-when-blurred) li.selected:focus .devtools-link { - color: var(--selection-fg-color); -} - .elements-disclosure .gutter-container { position: absolute; top: 0;
diff --git a/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHost.js b/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHost.js index 3a5bc6c..06d4a8f 100644 --- a/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHost.js +++ b/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHost.js
@@ -56,38 +56,6 @@ * @override * @return {string} */ - getSelectionBackgroundColor() { - return '#6e86ff'; - } - - /** - * @override - * @return {string} - */ - getSelectionForegroundColor() { - return '#ffffff'; - } - - /** - * @override - * @return {string} - */ - getInactiveSelectionBackgroundColor() { - return '#c9c8c8'; - } - - /** - * @override - * @return {string} - */ - getInactiveSelectionForegroundColor() { - return '#323232'; - } - - /** - * @override - * @return {string} - */ platform() { let match = navigator.userAgent.match(/Windows NT/); if (match)
diff --git a/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHostAPI.js b/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHostAPI.js index 93b1dc5..def2675 100644 --- a/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHostAPI.js +++ b/third_party/blink/renderer/devtools/front_end/host/InspectorFrontendHostAPI.js
@@ -110,26 +110,6 @@ indexPath(requestId, fileSystemPath, excludedFolders) {}, /** - * @return {string} - */ - getSelectionBackgroundColor() {}, - - /** - * @return {string} - */ - getSelectionForegroundColor() {}, - - /** - * @return {string} - */ - getInactiveSelectionBackgroundColor() {}, - - /** - * @return {string} - */ - getInactiveSelectionForegroundColor() {}, - - /** * Requests inspected page to be placed atop of the inspector frontend with specified bounds. * @param {{x: number, y: number, width: number, height: number}} bounds */
diff --git a/third_party/blink/renderer/devtools/front_end/main/Main.js b/third_party/blink/renderer/devtools/front_end/main/Main.js index 6f1c7e5..76abe4fa 100644 --- a/third_party/blink/renderer/devtools/front_end/main/Main.js +++ b/third_party/blink/renderer/devtools/front_end/main/Main.js
@@ -152,7 +152,7 @@ Runtime.experiments.setDefaultExperiments([ 'colorContrastRatio', 'stepIntoAsync', 'oopifInlineDOM', 'consoleBelowPrompt', 'timelineTracingJSProfile', - 'pinnedExpressions', 'consoleKeyboardNavigation' + 'pinnedExpressions', 'consoleKeyboardNavigation', 'sourcesLogpoints' ]); }
diff --git a/third_party/blink/renderer/devtools/front_end/sources/BreakpointEditDialog.js b/third_party/blink/renderer/devtools/front_end/sources/BreakpointEditDialog.js index c98cc69..3c13460 100644 --- a/third_party/blink/renderer/devtools/front_end/sources/BreakpointEditDialog.js +++ b/third_party/blink/renderer/devtools/front_end/sources/BreakpointEditDialog.js
@@ -19,6 +19,7 @@ /** @type {?UI.TextEditor} */ this._editor = null; const isNewBreakpointsEnabled = Runtime.experiments.isEnabled('sourcesLogpoints'); + this.element.tabIndex = -1; const logpointPrefix = Sources.BreakpointEditDialog._LogpointPrefix; const logpointSuffix = Sources.BreakpointEditDialog._LogpointSuffix;
diff --git a/third_party/blink/renderer/devtools/front_end/sources/breakpointEditDialog.css b/third_party/blink/renderer/devtools/front_end/sources/breakpointEditDialog.css index e2ec0db..154d0a0 100644 --- a/third_party/blink/renderer/devtools/front_end/sources/breakpointEditDialog.css +++ b/third_party/blink/renderer/devtools/front_end/sources/breakpointEditDialog.css
@@ -38,12 +38,11 @@ border-radius: 0; z-index: 30; background-color: var(--toolbar-bg-color); - width: 100%; - max-width: 600px; + width: 555px; pointer-events: auto; - margin-bottom: 5px; + margin: 2px 0 2px -1px; padding: 0 10px 10px 5px; - border-left: 3px solid var(--divider-color); + border: 1px solid var(--divider-color); } :host-context(.sources-edit-breakpoint-dialog) .condition-editor {
diff --git a/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js b/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js index 64670ab..1335b70 100644 --- a/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js +++ b/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js
@@ -42,8 +42,6 @@ this.registerRequiredCSS('cm/codemirror.css'); this.registerRequiredCSS('text_editor/cmdevtools.css'); - TextEditor.CodeMirrorUtils.appendThemeStyle(this.element); - this._codeMirror = new CodeMirror(this.element, { lineNumbers: options.lineNumbers, matchBrackets: true,
diff --git a/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorUtils.js b/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorUtils.js index 770ad2a..2ad76a5 100644 --- a/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorUtils.js +++ b/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorUtils.js
@@ -89,46 +89,6 @@ }; /** - * @param {!Element} element - */ -TextEditor.CodeMirrorUtils.appendThemeStyle = function(element) { - if (UI.themeSupport.hasTheme()) - return; - - const backgroundColor = InspectorFrontendHost.getSelectionBackgroundColor(); - const foregroundColor = InspectorFrontendHost.getSelectionForegroundColor(); - const inactiveBackgroundColor = InspectorFrontendHost.getInactiveSelectionBackgroundColor(); - const inactiveForegroundColor = InspectorFrontendHost.getInactiveSelectionForegroundColor(); - const style = createElement('style'); - style.textContent = ` - .CodeMirror .CodeMirror-selected { - background-color: ${inactiveBackgroundColor}; - } - - .CodeMirror .CodeMirror-selectedtext:not(.CodeMirror-persist-highlight) { - color: ${inactiveForegroundColor} !important; - } - - .CodeMirror-focused .CodeMirror-selected { - background-color: ${backgroundColor}; - } - - .CodeMirror-focused .CodeMirror-selectedtext:not(.CodeMirror-persist-highlight) { - color: ${foregroundColor} !important; - } - - .CodeMirror .CodeMirror-line::selection, - .CodeMirror .CodeMirror-line > span::selection, - .CodeMirror .CodeMirror-line > span > span::selection { - background: ${backgroundColor}; - color: ${foregroundColor} !important; - } - `; - element.appendChild(style); -}; - - -/** * @implements {TextUtils.TokenizerFactory} * @unrestricted */
diff --git a/third_party/blink/renderer/devtools/front_end/text_editor/cmdevtools.css b/third_party/blink/renderer/devtools/front_end/text_editor/cmdevtools.css index 97f3383..c690f4e1 100644 --- a/third_party/blink/renderer/devtools/front_end/text_editor/cmdevtools.css +++ b/third_party/blink/renderer/devtools/front_end/text_editor/cmdevtools.css
@@ -117,7 +117,7 @@ } .pretty-printed .CodeMirror-linenumber { - color: var( --accent-color-b); + color: var(--accent-color); } .cm-highlight { @@ -571,7 +571,7 @@ } .pretty-printed .CodeMirror-linenumber { - color: var(--accent-color-b); + color: var(--accent-color); } .CodeMirror-foldmarker { @@ -633,3 +633,17 @@ .CodeMirror-foldgutter-folded::before { -webkit-mask-position: 0 0; } + +.CodeMirror .CodeMirror-selected { + background-color: var(--editor-selection-inactive-bg-color); +} + +.CodeMirror-focused .CodeMirror-selected { + background-color: var(--editor-selection-bg-color); +} + +.CodeMirror .CodeMirror-line::selection, +.CodeMirror .CodeMirror-line > span::selection, +.CodeMirror .CodeMirror-line > span > span::selection { + background: var(--editor-selection-bg-color); +}
diff --git a/third_party/blink/renderer/devtools/front_end/ui/inspectorCommon.css b/third_party/blink/renderer/devtools/front_end/ui/inspectorCommon.css index 40892fe..1ab2d02 100644 --- a/third_party/blink/renderer/devtools/front_end/ui/inspectorCommon.css +++ b/third_party/blink/renderer/devtools/front_end/ui/inspectorCommon.css
@@ -420,3 +420,11 @@ .expandable-inline-button:hover { background-color: #d5d5d5; } + +::selection { + background-color: #bbdefb; +} + +.-theme-with-dark-background *::selection { + background-color: #9e9e9e;; +}
diff --git a/third_party/blink/renderer/devtools/front_end/ui/inspectorStyle.css b/third_party/blink/renderer/devtools/front_end/ui/inspectorStyle.css index eb057ad8..0475592 100644 --- a/third_party/blink/renderer/devtools/front_end/ui/inspectorStyle.css +++ b/third_party/blink/renderer/devtools/front_end/ui/inspectorStyle.css
@@ -33,9 +33,7 @@ } :root { - --accent-color: #03a9f4; - --accent-color-b: #2196f3; - --accent-color-c: #3e82f7; + --accent-color: #42a5f5; --focus-bg-color: hsl(214, 40%, 92%); --toolbar-bg-color: #f3f3f3; --toolbar-hover-bg-color: #eaeaea; @@ -48,12 +46,12 @@ 0 2px 6px rgba(0, 0, 0, 0.1); --divider-color: #d0d0d0; --focus-ring-inactive-shadow: 0 0 0 1px #e0e0e0; + --editor-selection-bg-color: #cfe8fc; + --editor-selection-inactive-bg-color: #e0e0e0; } .-theme-with-dark-background { - --accent-color: #32699f; - --accent-color-b: #2f84da; - --accent-color-c: #1f4061; + --accent-color: #2f84da; --focus-bg-color: hsl(214, 19%, 27%); --toolbar-bg-color: #333333; --toolbar-hover-bg-color: #202020; @@ -66,11 +64,13 @@ 0 2px 6px 2px rgba(0, 0, 0, 0.1); --divider-color: #525252; --focus-ring-inactive-shadow: 0 0 0 1px #5a5a5a; + --editor-selection-bg-color: #454545; + --editor-selection-inactive-bg-color: #454545; } :root { - --focus-ring-active-shadow: 0 0 0 1px var(--accent-color); - --selection-bg-color: var(--accent-color-b); + --focus-ring-active-shadow: 0 0 0 1px #bef7ff; + --selection-bg-color: var(--accent-color); --divider-border: 1px solid var(--divider-color); }
diff --git a/third_party/blink/renderer/devtools/front_end/ui/tabbedPane.css b/third_party/blink/renderer/devtools/front_end/ui/tabbedPane.css index fff72480..0e94772a 100644 --- a/third_party/blink/renderer/devtools/front_end/ui/tabbedPane.css +++ b/third_party/blink/renderer/devtools/front_end/ui/tabbedPane.css
@@ -246,7 +246,7 @@ height: 2px; position: absolute; bottom: -1px; - background-color: #03a9f4; + background-color: var(--accent-color); left: 0; z-index: 50; transform-origin: 0 100%;
diff --git a/third_party/blink/renderer/devtools/front_end/ui/toolbar.css b/third_party/blink/renderer/devtools/front_end/ui/toolbar.css index d45a3f95..4a9b6e2 100644 --- a/third_party/blink/renderer/devtools/front_end/ui/toolbar.css +++ b/third_party/blink/renderer/devtools/front_end/ui/toolbar.css
@@ -144,12 +144,12 @@ .toolbar-button.toolbar-state-on .toolbar-glyph, .toolbar-blue-on-hover .toolbar-button:not(.toolbar-state-on):enabled:hover:not(:active), .-theme-selection-color { - background-color: var(--accent-color-b); + background-color: var(--accent-color); } .toolbar-button.toolbar-state-on .toolbar-text, .-theme-selection-color { - color: var(--accent-color-b); + color: var(--accent-color); } .toolbar-blue-on-hover .toolbar-button:not(.toolbar-state-on):enabled:hover .toolbar-glyph { @@ -163,12 +163,12 @@ .toolbar-button.toolbar-state-on:enabled:hover:not(:active) .toolbar-glyph, .toolbar-blue-on-hover .toolbar-button:not(.toolbar-state-on):enabled:active:hover, .-theme-selection-color { - background-color: var(--accent-color-b); + background-color: var(--accent-color); } .toolbar-button.toolbar-state-on:enabled:hover:not(:active) .toolbar-text, .-theme-selection-color { - color: var(--accent-color-b); + color: var(--accent-color); } .toolbar-toggled-gray .toolbar-button.toolbar-state-on {
diff --git a/third_party/blink/renderer/modules/accessibility/accessibility_object_model_test.cc b/third_party/blink/renderer/modules/accessibility/accessibility_object_model_test.cc index 27f4931a..fff684f 100644 --- a/third_party/blink/renderer/modules/accessibility/accessibility_object_model_test.cc +++ b/third_party/blink/renderer/modules/accessibility/accessibility_object_model_test.cc
@@ -240,8 +240,8 @@ auto* ax_cell = cache->GetOrCreate(cell); EXPECT_TRUE(ax_cell->IsTableCellLikeRole()); - EXPECT_EQ(8U, ax_cell->AriaColumnIndex()); - EXPECT_EQ(5U, ax_cell->AriaRowIndex()); + EXPECT_EQ(0U, ax_cell->AriaColumnIndex()); + EXPECT_EQ(0U, ax_cell->AriaRowIndex()); auto* ax_cell2 = cache->GetOrCreate(cell2); EXPECT_TRUE(ax_cell2->IsTableCellLikeRole());
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc index 5f62ae8..e87e766 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -2654,84 +2654,19 @@ } unsigned AXObject::ComputeAriaColumnIndex() const { - if (!IsTableCellLikeRole()) - return 0; - - // First see if it has an ARIA column index explicitly set. - uint32_t col_index; - if (HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kColIndex, col_index) && - col_index >= 1) { - return col_index; - } - - // Get the previous sibling. - // TODO(dmazzoni): this code depends on the DOM; move this code out of Blink - // and make it more general. - AXObject* previous = nullptr; - if (GetNode()) { - Node* previousNode = ElementTraversal::PreviousSibling(*GetNode()); - previous = AXObjectCache().GetOrCreate(previousNode); - } - - // It has a previous sibling, so if that cell has a column index, this one's - // index is one greater. - if (previous) { - col_index = previous->AriaColumnIndex(); - if (col_index) - return col_index + 1; - return 0; - } - - // No previous cell, so check the row to see if it sets a column index. - const AXObject* row = TableRowParent(); - if (!row) - return 0; - if (row->HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kColIndex, - col_index)) { - return col_index; - } - - // Otherwise there's no ARIA column index. - return 0; + // Return the ARIA column index if it has been set. Otherwise return a default + // value of 0. + uint32_t col_index = 0; + HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kColIndex, col_index); + return col_index; } unsigned AXObject::ComputeAriaRowIndex() const { - if (!IsTableCellLikeRole() && !IsTableRowLikeRole()) - return 0; - - // First check if there's an ARIA row index explicitly set. - uint32_t row_index; - if (HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kRowIndex, row_index) && - row_index >= 1) { - return row_index; - } - - // If this is a cell, return the ARIA row index of the containing row. - if (IsTableCellLikeRole()) { - const AXObject* row = TableRowParent(); - if (row) - return row->AriaRowIndex(); - return 0; - } - - // Otherwise, this is a row. Find the previous sibling row. - // TODO(dmazzoni): this code depends on the DOM; move this code out of Blink - // and make it more general. - if (!GetNode()) - return 0; - Node* previousNode = ElementTraversal::PreviousSibling(*GetNode()); - AXObject* previous = AXObjectCache().GetOrCreate(previousNode); - if (!previous || !previous->IsTableRowLikeRole()) - return 0; - - // If the previous row has an ARIA row index, this one is the same index - // plus one. - row_index = previous->AriaRowIndex(); - if (row_index) - return row_index + 1; - - // Otherwise there's no ARIA row index. - return 0; + // Return the ARIA row index if it has been set. Otherwise return a default + // value of 0. + uint32_t row_index = 0; + HasAOMPropertyOrARIAAttribute(AOMUIntProperty::kRowIndex, row_index); + return row_index; } AXObject::AXObjectVector AXObject::TableRowChildren() const {
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl.cc b/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl.cc index 478a69ec..9d508a43 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl.cc +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_cursor_impl.cc
@@ -48,9 +48,6 @@ } ResetPrefetchCache(); - // Reset all cursor prefetch caches except for this cursor. - IndexedDBDispatcher::ResetCursorPrefetchCaches(transaction_id_, this); - auto callbacks_impl = std::make_unique<IndexedDBCallbacksImpl>( std::move(callbacks), transaction_id_, weak_factory_.GetWeakPtr()); cursor_->Advance(count, GetCallbacksProxy(std::move(callbacks_impl))); @@ -94,9 +91,6 @@ ResetPrefetchCache(); } - // Reset all cursor prefetch caches except for this cursor. - IndexedDBDispatcher::ResetCursorPrefetchCaches(transaction_id_, this); - auto callbacks_impl = std::make_unique<IndexedDBCallbacksImpl>( std::move(callbacks), transaction_id_, weak_factory_.GetWeakPtr()); cursor_->CursorContinue(IDBKey::Clone(key), IDBKey::Clone(primary_key),
diff --git a/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h b/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h index 21bb8db..41c03834 100644 --- a/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h +++ b/third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h
@@ -11,8 +11,9 @@ namespace blink { /** - * TraceWrapperV8Reference is used to trace from Blink to V8. The reference is - * (strongly) traced by wrapper tracing. + * TraceWrapperV8Reference is used to hold references from Blink to V8 that are + * known to both garbage collectors. The reference is a regular traced reference + * for wrapper tracing as well as unified heap garbage collections. * * TODO(mlippautz): Use a better handle type than v8::Persistent. */ @@ -37,16 +38,6 @@ handle_.SetWeak(); } - template <typename P> - void Set(v8::Isolate* isolate, - v8::Local<T> handle, - P* parameters, - void (*callback)(const v8::WeakCallbackInfo<P>&), - v8::WeakCallbackType type = v8::WeakCallbackType::kParameter) { - InternalSet(isolate, handle); - handle_.SetWeak(parameters, callback, type); - } - ALWAYS_INLINE v8::Local<T> NewLocal(v8::Isolate* isolate) const { return v8::Local<T>::New(isolate, handle_); }
diff --git a/third_party/blink/renderer/platform/heap/BUILD.gn b/third_party/blink/renderer/platform/heap/BUILD.gn index 650d1f90..197d649 100644 --- a/third_party/blink/renderer/platform/heap/BUILD.gn +++ b/third_party/blink/renderer/platform/heap/BUILD.gn
@@ -120,6 +120,7 @@ "heap_test.cc", "heap_test_utilities.cc", "heap_test_utilities.h", + "heap_thread_test.cc", "heap_traits_test.cc", "incremental_marking_test.cc", "name_trait_test.cc",
diff --git a/third_party/blink/renderer/platform/heap/heap_test.cc b/third_party/blink/renderer/platform/heap/heap_test.cc index 2120b6a..4b1c81e 100644 --- a/third_party/blink/renderer/platform/heap/heap_test.cc +++ b/third_party/blink/renderer/platform/heap/heap_test.cc
@@ -5362,300 +5362,6 @@ EXPECT_EQ(0u, map->size()); } -static Mutex& MainThreadMutex() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(Mutex, main_mutex, ()); - return main_mutex; -} - -static ThreadCondition& MainThreadCondition() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadCondition, main_condition, - (MainThreadMutex())); - return main_condition; -} - -static void ParkMainThread() { - MainThreadCondition().Wait(); -} - -static void WakeMainThread() { - MutexLocker locker(MainThreadMutex()); - MainThreadCondition().Signal(); -} - -static Mutex& WorkerThreadMutex() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(Mutex, worker_mutex, ()); - return worker_mutex; -} - -static ThreadCondition& WorkerThreadCondition() { - DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadCondition, worker_condition, - (WorkerThreadMutex())); - return worker_condition; -} - -static void ParkWorkerThread() { - WorkerThreadCondition().Wait(); -} - -static void WakeWorkerThread() { - MutexLocker locker(WorkerThreadMutex()); - WorkerThreadCondition().Signal(); -} - -class ThreadedStrongificationTester { - public: - static void Test() { - IntWrapper::destructor_calls_ = 0; - - MutexLocker locker(MainThreadMutex()); - std::unique_ptr<Thread> worker_thread = Platform::Current()->CreateThread( - ThreadCreationParams(WebThreadType::kTestThread) - .SetThreadNameForTest("Test Worker Thread")); - PostCrossThreadTask(*worker_thread->GetTaskRunner(), FROM_HERE, - CrossThreadBind(WorkerThreadMain)); - - // Wait for the worker thread initialization. The worker - // allocates a weak collection where both collection and - // contents are kept alive via persistent pointers. - ParkMainThread(); - - // Perform two garbage collections where the worker thread does - // not wake up in between. This will cause us to remove marks - // and mark unmarked objects dead. The collection on the worker - // heap is found through the persistent and the backing should - // be marked. - PreciselyCollectGarbage(); - PreciselyCollectGarbage(); - - // Wake up the worker thread so it can continue. It will sweep - // and perform another GC where the backing store of its - // collection should be strongified. - WakeWorkerThread(); - - // Wait for the worker thread to sweep its heaps before checking. - ParkMainThread(); - } - - private: - using WeakCollectionType = - HeapHashMap<WeakMember<IntWrapper>, Member<IntWrapper>>; - - static WeakCollectionType* AllocateCollection() { - // Create a weak collection that is kept alive by a persistent - // and keep the contents alive with a persistents as - // well. - Persistent<IntWrapper> wrapper1 = IntWrapper::Create(32); - Persistent<IntWrapper> wrapper2 = IntWrapper::Create(32); - Persistent<IntWrapper> wrapper3 = IntWrapper::Create(32); - Persistent<IntWrapper> wrapper4 = IntWrapper::Create(32); - Persistent<IntWrapper> wrapper5 = IntWrapper::Create(32); - Persistent<IntWrapper> wrapper6 = IntWrapper::Create(32); - Persistent<WeakCollectionType> weak_collection = - MakeGarbageCollected<WeakCollectionType>(); - weak_collection->insert(wrapper1, wrapper1); - weak_collection->insert(wrapper2, wrapper2); - weak_collection->insert(wrapper3, wrapper3); - weak_collection->insert(wrapper4, wrapper4); - weak_collection->insert(wrapper5, wrapper5); - weak_collection->insert(wrapper6, wrapper6); - - // Signal the main thread that the worker is done with its allocation. - WakeMainThread(); - - // Wait for the main thread to do two GCs without sweeping - // this thread heap. - ParkWorkerThread(); - - return weak_collection; - } - - static void WorkerThreadMain() { - MutexLocker locker(WorkerThreadMutex()); - - ThreadState::AttachCurrentThread(); - - { - Persistent<WeakCollectionType> collection = AllocateCollection(); - { - // Prevent weak processing with an iterator and GC. - WeakCollectionType::iterator it = collection->begin(); - ConservativelyCollectGarbage(); - - // The backing should be strongified because of the iterator. - EXPECT_EQ(6u, collection->size()); - EXPECT_EQ(32, it->value->Value()); - } - - // Disregarding the iterator but keeping the collection alive - // with a persistent should lead to weak processing. - PreciselyCollectGarbage(); - EXPECT_EQ(0u, collection->size()); - } - - WakeMainThread(); - ThreadState::DetachCurrentThread(); - } - - static volatile uintptr_t worker_object_pointer_; -}; - -#if defined(THREAD_SANITIZER) -// https://crbug.com/915200 -#define MAYBE_ThreadedStrongification DISABLED_ThreadedStrongification -#else -#define MAYBE_ThreadedStrongification ThreadedStrongification -#endif - -TEST(HeapTest, MAYBE_ThreadedStrongification) { - ThreadedStrongificationTester::Test(); -} - -class MemberSameThreadCheckTester { - public: - void Test() { - IntWrapper::destructor_calls_ = 0; - - MutexLocker locker(MainThreadMutex()); - std::unique_ptr<Thread> worker_thread = Platform::Current()->CreateThread( - ThreadCreationParams(WebThreadType::kTestThread) - .SetThreadNameForTest("Test Worker Thread")); - PostCrossThreadTask( - *worker_thread->GetTaskRunner(), FROM_HERE, - CrossThreadBind(&MemberSameThreadCheckTester::WorkerThreadMain, - CrossThreadUnretained(this))); - - ParkMainThread(); - } - - private: - Member<IntWrapper> wrapper_; - - void WorkerThreadMain() { - MutexLocker locker(WorkerThreadMutex()); - - ThreadState::AttachCurrentThread(); - - // Setting an object created on the worker thread to a Member allocated on - // the main thread is not allowed. - wrapper_ = IntWrapper::Create(42); - - WakeMainThread(); - ThreadState::DetachCurrentThread(); - } -}; - -#if DCHECK_IS_ON() -// TODO(keishi) This test is flaky on mac_chromium_rel_ng bot. -// crbug.com/709069 -#if !defined(OS_MACOSX) -TEST(HeapDeathTest, MemberSameThreadCheck) { - EXPECT_DEATH(MemberSameThreadCheckTester().Test(), ""); -} -#endif -#endif - -class PersistentSameThreadCheckTester { - public: - void Test() { - IntWrapper::destructor_calls_ = 0; - - MutexLocker locker(MainThreadMutex()); - std::unique_ptr<Thread> worker_thread = Platform::Current()->CreateThread( - ThreadCreationParams(WebThreadType::kTestThread) - .SetThreadNameForTest("Test Worker Thread")); - PostCrossThreadTask( - *worker_thread->GetTaskRunner(), FROM_HERE, - CrossThreadBind(&PersistentSameThreadCheckTester::WorkerThreadMain, - CrossThreadUnretained(this))); - - ParkMainThread(); - } - - private: - Persistent<IntWrapper> wrapper_; - - void WorkerThreadMain() { - MutexLocker locker(WorkerThreadMutex()); - - ThreadState::AttachCurrentThread(); - - // Setting an object created on the worker thread to a Persistent allocated - // on the main thread is not allowed. - wrapper_ = IntWrapper::Create(42); - - WakeMainThread(); - ThreadState::DetachCurrentThread(); - } -}; - -#if DCHECK_IS_ON() -// TODO(keishi) This test is flaky on mac_chromium_rel_ng bot. -// crbug.com/709069 -#if !defined(OS_MACOSX) -TEST(HeapDeathTest, PersistentSameThreadCheck) { - EXPECT_DEATH(PersistentSameThreadCheckTester().Test(), ""); -} -#endif -#endif - -class MarkingSameThreadCheckTester { - public: - void Test() { - IntWrapper::destructor_calls_ = 0; - - MutexLocker locker(MainThreadMutex()); - std::unique_ptr<Thread> worker_thread = Platform::Current()->CreateThread( - ThreadCreationParams(WebThreadType::kTestThread) - .SetThreadNameForTest("Test Worker Thread")); - Persistent<MainThreadObject> main_thread_object = - MakeGarbageCollected<MainThreadObject>(); - PostCrossThreadTask( - *worker_thread->GetTaskRunner(), FROM_HERE, - CrossThreadBind(&MarkingSameThreadCheckTester::WorkerThreadMain, - CrossThreadUnretained(this), - WrapCrossThreadPersistent(main_thread_object.Get()))); - ParkMainThread(); - // This will try to mark MainThreadObject when it tries to mark IntWrapper - // it should crash. - PreciselyCollectGarbage(); - } - - private: - class MainThreadObject : public GarbageCollectedFinalized<MainThreadObject> { - public: - void Trace(blink::Visitor* visitor) { visitor->Trace(wrapper_set_); } - void AddToSet(IntWrapper* wrapper) { wrapper_set_.insert(42, wrapper); } - - private: - HeapHashMap<int, Member<IntWrapper>> wrapper_set_; - }; - - void WorkerThreadMain(MainThreadObject* main_thread_object) { - MutexLocker locker(WorkerThreadMutex()); - - ThreadState::AttachCurrentThread(); - - // Adding a reference to an object created on the worker thread to a - // HeapHashMap created on the main thread is not allowed. - main_thread_object->AddToSet(IntWrapper::Create(42)); - - WakeMainThread(); - ThreadState::DetachCurrentThread(); - } -}; - -#if DCHECK_IS_ON() -// TODO(keishi) This test is flaky on mac_chromium_rel_ng bot. -// crbug.com/709069 -#if !defined(OS_MACOSX) -TEST(HeapDeathTest, MarkingSameThreadCheck) { - // This will crash during marking, at the DCHECK in Visitor::markHeader() or - // earlier. - EXPECT_DEATH(MarkingSameThreadCheckTester().Test(), ""); -} -#endif -#endif - static bool AllocateAndReturnBool() { ConservativelyCollectGarbage(); return true; @@ -5714,24 +5420,6 @@ a->Verify(); } -class DestructorLockingObject - : public GarbageCollectedFinalized<DestructorLockingObject> { - public: - static DestructorLockingObject* Create() { - return MakeGarbageCollected<DestructorLockingObject>(); - } - - DestructorLockingObject() = default; - virtual ~DestructorLockingObject() { - ++destructor_calls_; - } - - static int destructor_calls_; - void Trace(blink::Visitor* visitor) {} -}; - -int DestructorLockingObject::destructor_calls_ = 0; - template <typename T> class TraceIfNeededTester : public GarbageCollectedFinalized<TraceIfNeededTester<T>> { @@ -6369,78 +6057,6 @@ namespace { -void WorkerThreadMainForCrossThreadWeakPersistentTest( - DestructorLockingObject** object) { - // Step 2: Create an object and store the pointer. - MutexLocker locker(WorkerThreadMutex()); - ThreadState::AttachCurrentThread(); - *object = DestructorLockingObject::Create(); - WakeMainThread(); - ParkWorkerThread(); - - // Step 4: Run a GC. - ThreadState::Current()->CollectGarbage( - BlinkGC::kNoHeapPointersOnStack, BlinkGC::kAtomicMarking, - BlinkGC::kEagerSweeping, BlinkGC::GCReason::kForcedGC); - WakeMainThread(); - ParkWorkerThread(); - - // Step 6: Finish. - ThreadState::DetachCurrentThread(); - WakeMainThread(); -} - -} // anonymous namespace - -#if defined(THREAD_SANITIZER) -// https://crbug.com/915200 -#define MAYBE_CrossThreadWeakPersistent DISABLED_CrossThreadWeakPersistent -#else -#define MAYBE_CrossThreadWeakPersistent CrossThreadWeakPersistent -#endif - -TEST(HeapTest, MAYBE_CrossThreadWeakPersistent) { - // Create an object in the worker thread, have a CrossThreadWeakPersistent - // pointing to it on the main thread, clear the reference in the worker - // thread, run a GC in the worker thread, and see if the - // CrossThreadWeakPersistent is cleared. - - DestructorLockingObject::destructor_calls_ = 0; - - // Step 1: Initiate a worker thread, and wait for |object| to get allocated on - // the worker thread. - MutexLocker main_thread_mutex_locker(MainThreadMutex()); - std::unique_ptr<Thread> worker_thread = Platform::Current()->CreateThread( - ThreadCreationParams(WebThreadType::kTestThread) - .SetThreadNameForTest("Test Worker Thread")); - DestructorLockingObject* object = nullptr; - PostCrossThreadTask( - *worker_thread->GetTaskRunner(), FROM_HERE, - CrossThreadBind(WorkerThreadMainForCrossThreadWeakPersistentTest, - CrossThreadUnretained(&object))); - ParkMainThread(); - - // Step 3: Set up a CrossThreadWeakPersistent. - ASSERT_TRUE(object); - CrossThreadWeakPersistent<DestructorLockingObject> - cross_thread_weak_persistent(object); - object = nullptr; - EXPECT_EQ(0, DestructorLockingObject::destructor_calls_); - - // Pretend we have no pointers on stack during the step 4. - WakeWorkerThread(); - ParkMainThread(); - - // Step 5: Make sure the weak persistent is cleared. - EXPECT_FALSE(cross_thread_weak_persistent.Get()); - EXPECT_EQ(1, DestructorLockingObject::destructor_calls_); - - WakeWorkerThread(); - ParkMainThread(); -} - -namespace { - class ThreadedClearOnShutdownTester : public ThreadedTesterBase { public: static void Test() {
diff --git a/third_party/blink/renderer/platform/heap/heap_thread_test.cc b/third_party/blink/renderer/platform/heap/heap_thread_test.cc new file mode 100644 index 0000000..b1f86ce --- /dev/null +++ b/third_party/blink/renderer/platform/heap/heap_thread_test.cc
@@ -0,0 +1,269 @@ +// Copyright 2018 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 "build/build_config.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/renderer/platform/cross_thread_functional.h" +#include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/heap/heap_test_utilities.h" +#include "third_party/blink/renderer/platform/heap/thread_state.h" +#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread.h" + +namespace blink { +namespace heap_thread_test { + +static Mutex& ActiveThreadMutex() { + DEFINE_THREAD_SAFE_STATIC_LOCAL(Mutex, active_thread_mutex, ()); + return active_thread_mutex; +} + +static ThreadCondition& ActiveThreadCondition() { + DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadCondition, active_thread_condition, + (ActiveThreadMutex())); + return active_thread_condition; +} + +enum ActiveThreadState { + kNoThreadActive, + kMainThreadActive, + kWorkerThreadActive, +}; + +static ActiveThreadState& ActiveThread() { + DEFINE_THREAD_SAFE_STATIC_LOCAL(ActiveThreadState, active_thread, + (kNoThreadActive)); + return active_thread; +} + +static void WakeMainThread() { + ActiveThread() = kMainThreadActive; + ActiveThreadCondition().Signal(); +} + +static void WakeWorkerThread() { + ActiveThread() = kWorkerThreadActive; + ActiveThreadCondition().Signal(); +} + +static void ParkMainThread() { + while (ActiveThread() != kMainThreadActive) { + ActiveThreadCondition().Wait(); + } +} + +static void ParkWorkerThread() { + while (ActiveThread() != kWorkerThreadActive) { + ActiveThreadCondition().Wait(); + } +} + +class Object : public GarbageCollected<Object> { + public: + Object() {} + ~Object() {} + void Trace(blink::Visitor* visitor) {} +}; + +class AlternatingThreadTester { + public: + void Test() { + MutexLocker locker(ActiveThreadMutex()); + ActiveThread() = kMainThreadActive; + + std::unique_ptr<Thread> worker_thread = Platform::Current()->CreateThread( + ThreadCreationParams(WebThreadType::kTestThread) + .SetThreadNameForTest("Test Worker Thread")); + PostCrossThreadTask( + *worker_thread->GetTaskRunner(), FROM_HERE, + CrossThreadBind(&AlternatingThreadTester::StartWorkerThread, + CrossThreadUnretained(this))); + + MainThreadMain(); + } + + void SwitchToWorkerThread() { + WakeWorkerThread(); + ParkMainThread(); + } + + void SwitchToMainThread() { + WakeMainThread(); + ParkWorkerThread(); + } + + protected: + // Override with code you want to execute on the main thread. + virtual void MainThreadMain() = 0; + // Override with code you want to execute on the worker thread. At the end, + // the ThreadState is detached and we switch back to the main thread + // automatically. + virtual void WorkerThreadMain() = 0; + + private: + void StartWorkerThread() { + ThreadState::AttachCurrentThread(); + + MutexLocker locker(ActiveThreadMutex()); + + WorkerThreadMain(); + + ThreadState::DetachCurrentThread(); + WakeMainThread(); + } +}; + +class MemberSameThreadCheckTester : public AlternatingThreadTester { + private: + void MainThreadMain() override { SwitchToWorkerThread(); } + + void WorkerThreadMain() override { + // Setting an object created on the worker thread to a Member allocated on + // the main thread is not allowed. + object_ = MakeGarbageCollected<Object>(); + } + + Member<Object> object_; +}; + +#if DCHECK_IS_ON() +// TODO(keishi) This test is flaky on mac_chromium_rel_ng bot. +// crbug.com/709069 +#if !defined(OS_MACOSX) +TEST(HeapDeathTest, MemberSameThreadCheck) { + EXPECT_DEATH(MemberSameThreadCheckTester().Test(), ""); +} +#endif +#endif + +class PersistentSameThreadCheckTester : public AlternatingThreadTester { + private: + void MainThreadMain() override { SwitchToWorkerThread(); } + + void WorkerThreadMain() override { + // Setting an object created on the worker thread to a Persistent allocated + // on the main thread is not allowed. + object_ = MakeGarbageCollected<Object>(); + } + + Persistent<Object> object_; +}; + +#if DCHECK_IS_ON() +// TODO(keishi) This test is flaky on mac_chromium_rel_ng bot. +// crbug.com/709069 +#if !defined(OS_MACOSX) +TEST(HeapDeathTest, PersistentSameThreadCheck) { + EXPECT_DEATH(PersistentSameThreadCheckTester().Test(), ""); +} +#endif +#endif + +class MarkingSameThreadCheckTester : public AlternatingThreadTester { + private: + class MainThreadObject : public GarbageCollectedFinalized<MainThreadObject> { + public: + void Trace(blink::Visitor* visitor) { visitor->Trace(set_); } + void AddToSet(Object* object) { set_.insert(42, object); } + + private: + HeapHashMap<int, Member<Object>> set_; + }; + + void MainThreadMain() override { + main_thread_object_ = MakeGarbageCollected<MainThreadObject>(); + + SwitchToWorkerThread(); + + // This will try to mark MainThreadObject when it tries to mark Object + // it should crash. + PreciselyCollectGarbage(); + } + + void WorkerThreadMain() override { + // Adding a reference to an object created on the worker thread to a + // HeapHashMap created on the main thread is not allowed. + main_thread_object_->AddToSet(MakeGarbageCollected<Object>()); + } + + CrossThreadPersistent<MainThreadObject> main_thread_object_; +}; + +#if DCHECK_IS_ON() +// TODO(keishi) This test is flaky on mac_chromium_rel_ng bot. +// crbug.com/709069 +#if !defined(OS_MACOSX) +TEST(HeapDeathTest, MarkingSameThreadCheck) { + // This will crash during marking, at the DCHECK in Visitor::markHeader() or + // earlier. + EXPECT_DEATH(MarkingSameThreadCheckTester().Test(), ""); +} +#endif +#endif + +class DestructorLockingObject + : public GarbageCollectedFinalized<DestructorLockingObject> { + public: + static DestructorLockingObject* Create() { + return MakeGarbageCollected<DestructorLockingObject>(); + } + + DestructorLockingObject() = default; + virtual ~DestructorLockingObject() { ++destructor_calls_; } + + static int destructor_calls_; + void Trace(blink::Visitor* visitor) {} +}; + +int DestructorLockingObject::destructor_calls_ = 0; + +class CrossThreadWeakPersistentTester : public AlternatingThreadTester { + private: + void MainThreadMain() override { + // Create an object in the worker thread, have a CrossThreadWeakPersistent + // pointing to it on the main thread, run a GC in the worker thread, and see + // if the CrossThreadWeakPersistent is cleared. + + DestructorLockingObject::destructor_calls_ = 0; + + // Step 1: Initiate a worker thread, and wait for |Object| to get allocated + // on the worker thread. + SwitchToWorkerThread(); + + // Step 3: Set up a CrossThreadWeakPersistent. + ASSERT_TRUE(object_); + EXPECT_EQ(0, DestructorLockingObject::destructor_calls_); + + // Pretend we have no pointers on stack during the step 4. + SwitchToWorkerThread(); + + // Step 5: Make sure the weak persistent is cleared. + EXPECT_FALSE(object_.Get()); + EXPECT_EQ(1, DestructorLockingObject::destructor_calls_); + + SwitchToWorkerThread(); + } + + void WorkerThreadMain() override { + // Step 2: Create an object and store the pointer. + object_ = DestructorLockingObject::Create(); + SwitchToMainThread(); + + // Step 4: Run a GC. + ThreadState::Current()->CollectGarbage( + BlinkGC::kNoHeapPointersOnStack, BlinkGC::kAtomicMarking, + BlinkGC::kEagerSweeping, BlinkGC::GCReason::kForcedGC); + SwitchToMainThread(); + } + + CrossThreadWeakPersistent<DestructorLockingObject> object_; +}; + +TEST(HeapThreadTest, CrossThreadWeakPersistent) { + CrossThreadWeakPersistentTester().Test(); +} + +} // namespace heap_thread_test +} // namespace blink
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG index 1545cb0..c9dac30f 100644 --- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
@@ -314,7 +314,6 @@ crbug.com/591099 virtual/display-lock/display-lock/lock-before-append/measure-forced-layout.html [ Failure ] crbug.com/591099 virtual/display-lock/display-lock/lock-before-append/measure-updated-layout.html [ Failure ] crbug.com/591099 virtual/exotic-color-space/ [ Skip ] -crbug.com/591099 virtual/intersection-observer-v2/intersection-observer/v2/text-shadow.html [ Failure ] crbug.com/591099 virtual/layout_ng/ [ Skip ] crbug.com/824918 virtual/layout_ng_experimental/ [ Skip ] crbug.com/591099 virtual/mouseevent_fractional/fast/events/touch/compositor-touch-hit-rects-continuation.html [ Failure ]
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/commit-while-disconnected-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/commit-while-disconnected-expected.html new file mode 100644 index 0000000..1333caeb --- /dev/null +++ b/third_party/blink/web_tests/display-lock/lock-before-append/commit-while-disconnected-expected.html
@@ -0,0 +1,4 @@ +<!doctype HTML> + +<div id="log">PASS</div> +
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/commit-while-disconnected.html b/third_party/blink/web_tests/display-lock/lock-before-append/commit-while-disconnected.html new file mode 100644 index 0000000..a5643b93 --- /dev/null +++ b/third_party/blink/web_tests/display-lock/lock-before-append/commit-while-disconnected.html
@@ -0,0 +1,33 @@ +<!doctype HTML> + +<!-- +Runs an acquire(), then commits without connecting the element. +--> + +<div id="log"></div> + +<script> +// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait. +if (window.testRunner) + window.testRunner.waitUntilDone(); + +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + if (window.testRunner) + window.testRunner.notifyDone(); +} + +function runTest() { + let container = document.createElement("div"); + container.id = "container"; + + container.getDisplayLock().acquire({ timeout: Infinity }).then(() => { + container.getDisplayLock().commit().then( + () => { finishTest("FAIL"); }, + () => { finishTest("PASS"); }); + }); +} + +window.onload = runTest; +</script>
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/update-while-disconnected-expected.html b/third_party/blink/web_tests/display-lock/lock-before-append/update-while-disconnected-expected.html new file mode 100644 index 0000000..1333caeb --- /dev/null +++ b/third_party/blink/web_tests/display-lock/lock-before-append/update-while-disconnected-expected.html
@@ -0,0 +1,4 @@ +<!doctype HTML> + +<div id="log">PASS</div> +
diff --git a/third_party/blink/web_tests/display-lock/lock-before-append/update-while-disconnected.html b/third_party/blink/web_tests/display-lock/lock-before-append/update-while-disconnected.html new file mode 100644 index 0000000..9f0e4ed --- /dev/null +++ b/third_party/blink/web_tests/display-lock/lock-before-append/update-while-disconnected.html
@@ -0,0 +1,33 @@ +<!doctype HTML> + +<!-- +Runs an acquire(), then updates without connecting the element. +--> + +<div id="log"></div> + +<script> +// TODO(vmpstr): In WPT this needs to be replaced with reftest-wait. +if (window.testRunner) + window.testRunner.waitUntilDone(); + +function finishTest(status_string) { + if (document.getElementById("log").innerHTML === "") + document.getElementById("log").innerHTML = status_string; + if (window.testRunner) + window.testRunner.notifyDone(); +} + +function runTest() { + let container = document.createElement("div"); + container.id = "container"; + + container.getDisplayLock().acquire({ timeout: Infinity }).then(() => { + container.getDisplayLock().update().then( + () => { finishTest("FAIL"); }, + () => { finishTest("PASS"); }); + }); +} + +window.onload = runTest; +</script>
diff --git a/third_party/blink/web_tests/editing/selection/select_all/select_all_contenteditable_br.html b/third_party/blink/web_tests/editing/selection/select_all/select_all_contenteditable_br.html new file mode 100644 index 0000000..9dc9134 --- /dev/null +++ b/third_party/blink/web_tests/editing/selection/select_all/select_all_contenteditable_br.html
@@ -0,0 +1,11 @@ +<!doctype html> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<div id="div" contenteditable><br>foo</div> +<script> +test(function() { + var div = document.getElementById('div'); + div.focus(); + assert_true(document.queryCommandEnabled('SelectAll')); +}, 'SelectAll is enabled if the contenteditable contains BR (at the beginning) and other content'); +</script>
diff --git a/third_party/blink/web_tests/editing/selection/select_all/select_all_contenteditable_br_only.html b/third_party/blink/web_tests/editing/selection/select_all/select_all_contenteditable_br_only.html new file mode 100644 index 0000000..44c03d4 --- /dev/null +++ b/third_party/blink/web_tests/editing/selection/select_all/select_all_contenteditable_br_only.html
@@ -0,0 +1,11 @@ +<!doctype html> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<div id="div" contenteditable><br></div> +<script> +test(function() { + var div = document.getElementById('div'); + div.focus(); + assert_false(document.queryCommandEnabled('SelectAll')); +}, 'SelectAll is not enabled if the contenteditable contains a BR only'); +</script>
diff --git a/tools/binary_size/libsupersize/archive.py b/tools/binary_size/libsupersize/archive.py index bf947922..7051d91 100644 --- a/tools/binary_size/libsupersize/archive.py +++ b/tools/binary_size/libsupersize/archive.py
@@ -85,8 +85,6 @@ '../../chrome/android/webapk/libs/runtime_library_version.gni'), 'lib/armeabi-v7a/libarcore_sdk_c_minimal.so': ( '../../third_party/arcore-android-sdk'), - 'lib/armeabi-v7a/libarcore_sdk_c.so': ( - '../../third_party/arcore-android-sdk'), } self.apk_expected_other_files = set([
diff --git a/tools/clang/plugins/FindBadConstructsAction.cpp b/tools/clang/plugins/FindBadConstructsAction.cpp index 916f0de..efaf1b3 100644 --- a/tools/clang/plugins/FindBadConstructsAction.cpp +++ b/tools/clang/plugins/FindBadConstructsAction.cpp
@@ -47,10 +47,6 @@ if (args[i] == "check-base-classes") { // TODO(rsleevi): Remove this once http://crbug.com/123295 is fixed. options_.check_base_classes = true; - } else if (args[i] == "enforce-in-thirdparty-webkit") { - // TODO(dcheng): Remove completely. - } else if (args[i] == "check-enum-max-value") { - // TODO(dcheng): Remove completely. } else if (args[i] == "check-ipc") { options_.check_ipc = true; } else if (args[i] == "check-gmock-objects") {
diff --git a/ui/compositor/compositor.cc b/ui/compositor/compositor.cc index a7654e3d..5d3c2bf 100644 --- a/ui/compositor/compositor.cc +++ b/ui/compositor/compositor.cc
@@ -190,9 +190,6 @@ settings.enable_latency_recovery = false; } - settings.always_request_presentation_time = - command_line->HasSwitch(cc::switches::kAlwaysRequestPresentationTime); - animation_host_ = cc::AnimationHost::CreateMainInstance(); cc::LayerTreeHost::InitParams params;
diff --git a/ui/events/ozone/evdev/event_device_info.cc b/ui/events/ozone/evdev/event_device_info.cc index 76085ec..60e1d52 100644 --- a/ui/events/ozone/evdev/event_device_info.cc +++ b/ui/events/ozone/evdev/event_device_info.cc
@@ -458,11 +458,21 @@ // static ui::InputDeviceType EventDeviceInfo::GetInputDeviceTypeFromId(input_id id) { - constexpr uint16_t kGoogleVendorId = 0x18d1; - constexpr uint16_t kHammerProductId = 0x5030; - if (id.bustype == BUS_USB && id.vendor == kGoogleVendorId && - id.product == kHammerProductId) - return InputDeviceType::INPUT_DEVICE_INTERNAL; + static constexpr struct { + uint16_t vid; + uint16_t pid; + } kUSBInternalDevices[] = { + { 0x18d1, 0x5030 }, // Google, Hammer PID + { 0x1fd2, 0x8103 } // LG, Internal TouchScreen PID + }; + + if (id.bustype == BUS_USB) { + for (size_t i = 0; i < arraysize(kUSBInternalDevices); ++i) { + if (id.vendor == kUSBInternalDevices[i].vid && + id.product == kUSBInternalDevices[i].pid) + return InputDeviceType::INPUT_DEVICE_INTERNAL; + } + } switch (id.bustype) { case BUS_I2C:
diff --git a/ui/views/test/platform_test_helper_mus.cc b/ui/views/test/platform_test_helper_mus.cc index 01b727aa..da05fee0 100644 --- a/ui/views/test/platform_test_helper_mus.cc +++ b/ui/views/test/platform_test_helper_mus.cc
@@ -53,7 +53,6 @@ ServiceManagerConnection() : thread_("Persistent service_manager connections"), default_service_binding_(&default_service_) { - catalog::Catalog::SetDefaultCatalogManifest(CreateViewsUnittestsCatalog()); base::WaitableEvent wait(base::WaitableEvent::ResetPolicy::AUTOMATIC, base::WaitableEvent::InitialState::NOT_SIGNALED); base::Thread::Options options; @@ -109,8 +108,8 @@ void SetUpConnectionsOnBackgroundThread(base::WaitableEvent* wait) { background_service_manager_ = - std::make_unique<service_manager::BackgroundServiceManager>(nullptr, - nullptr); + std::make_unique<service_manager::BackgroundServiceManager>( + nullptr, CreateViewsUnittestsCatalog()); service_manager::mojom::ServicePtr service; default_service_binding_.Bind(mojo::MakeRequest(&service)); background_service_manager_->RegisterService(