diff --git a/DEPS b/DEPS index 8a31716e..fc20e96 100644 --- a/DEPS +++ b/DEPS
@@ -129,7 +129,7 @@ # 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': '14c90c1ca218428418b82be5684bb71f13e81f60', + 'skia_revision': '847d55be4e6273fc3cd9c0b30c7bfc8a2d6575b7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -141,11 +141,11 @@ # 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': '82bcffa78747f26b0e4748ef6a7751fe4d5213aa', + 'angle_revision': '422c94bdab7aff1939b97d03281b22237bc4aa19', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': 'abaecd5f2ba7910b0f5a959e42e9133c93afc60d', + 'swiftshader_revision': 'f45b3881ebc6610e0ba35acbf45e048c22928493', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -196,7 +196,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': '4e967e7e447debe18c75d71d94028fd1fc541d73', + 'catapult_revision': 'f76561176b6ccfdedcf449e750ffaccc990abfce', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -272,7 +272,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. - 'quiche_revision': '546cc453efd0b1f1aa63687fddd7c8f9a2218fce', + 'quiche_revision': '2c5386eab92a1d8ff18f29464f6e6aa086e4ab87', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ios_webkit # and whatever else without interference from each other. @@ -805,7 +805,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'd635edced1d1e4eafc745bdc15610a2730b4fb27', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '060c5300eae0b645f13e82fe43f55ad8faf2436c', 'condition': 'checkout_linux', }, @@ -1256,7 +1256,7 @@ 'packages': [ { 'package': 'chromium/third_party/r8', - 'version': 'BReCwfbVwCNM2Ry4QpnrwlE3Y5gPJ2rRoyMbxFS0-4UC', + 'version': 'SlcbUnEufAQ-iuOwGOl8yYQuctmpf7bMqh59kBfpil0C', }, ], 'condition': 'checkout_android', @@ -1395,7 +1395,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@9cb73239a3ac155781b028aeca103ed1f9ca7be6', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@c8ee49fcfce8e3a24f1b38c5bf022c1d477f21f4', 'condition': 'checkout_src_internal', },
diff --git a/WATCHLISTS b/WATCHLISTS index 94cd6ad..5d96cd0 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -188,15 +188,14 @@ 'chrome/browser/android/autofill_assistant/|'\ 'components/autofill_assistant/', }, - 'autofill_credit_cards': { + 'autofill_payments': { 'filepath': 'chrome/browser/ui/autofill/chrome_autofill_client*|'\ - 'chrome/browser/ui/autofill/save_card_*|'\ - 'chrome/browser/ui/views/autofill/card_unmask_*|'\ - 'chrome/browser/ui/views/autofill/save_card_*|'\ - 'components/autofill/core/browser/autofill_save_card_infobar_*|'\ - 'components/autofill/core/browser/credit_card_save_manager*|'\ - 'components/autofill/core/browser/form_data_importer*|'\ - 'components/autofill/core/browser/ui/', + 'chrome/browser/ui/autofill/payments/|'\ + 'chrome/browser/ui/views/autofill/payments/|'\ + 'components/autofill/core/browser/payments/|'\ + 'components/autofill/core/browser/ui/payments/|'\ + 'components/autofill/core/common/autofill_payments_features*|'\ + 'components/autofill_payments_strings*', }, 'background_fetch': { 'filepath': 'background_fetch|'\ @@ -1906,13 +1905,12 @@ 'piman+watch@chromium.org'], 'autoclick': ['katie+watch@chromium.org'], 'autofill': ['anthonyvd+autofillwatch@chromium.org', - 'dlkumar+autofillwatch@google.com', 'ftirelo+autofillwatch@chromium.org', 'mathp+autofillwatch@chromium.org', 'rogerm+autofillwatch@chromium.org', 'tmartino+autofillwatch@chromium.org'], 'autofill_assistant': ['autofill_assistant+watch@google.com'], - 'autofill_credit_cards': ['jsaul+autofillwatch@google.com'], + 'autofill_payments': ['jsaul+autofillwatch@google.com'], 'background_fetch': ['peter@chromium.org', 'rayankans+watch@chromium.org', 'nator@chromium.org'],
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index a1e1487..c2f922e1 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc
@@ -542,7 +542,7 @@ return true; } -content::QuotaPermissionContext* +scoped_refptr<content::QuotaPermissionContext> AwContentBrowserClient::CreateQuotaPermissionContext() { return new AwQuotaPermissionContext; }
diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h index 476e3bf..81c9497 100644 --- a/android_webview/browser/aw_content_browser_client.h +++ b/android_webview/browser/aw_content_browser_client.h
@@ -106,7 +106,8 @@ const GURL& url, content::ResourceContext* context, const std::vector<content::GlobalFrameRoutingId>& render_frames) override; - content::QuotaPermissionContext* CreateQuotaPermissionContext() override; + scoped_refptr<content::QuotaPermissionContext> CreateQuotaPermissionContext() + override; void GetQuotaSettings( content::BrowserContext* context, content::StoragePartition* partition,
diff --git a/ash/accessibility/accessibility_controller.cc b/ash/accessibility/accessibility_controller.cc index fec3117..b06a8d74 100644 --- a/ash/accessibility/accessibility_controller.cc +++ b/ash/accessibility/accessibility_controller.cc
@@ -266,6 +266,8 @@ static_cast<int>(kDefaultAutoclickEventType)); registry->RegisterBooleanPref( prefs::kAccessibilityAutoclickRevertToLeftClick, true); + registry->RegisterBooleanPref( + prefs::kAccessibilityAutoclickStabilizePosition, false); registry->RegisterIntegerPref( prefs::kAccessibilityAutoclickMovementThreshold, kDefaultAutoclickMovementThreshold); @@ -321,6 +323,8 @@ registry->RegisterForeignPref( prefs::kAccessibilityAutoclickRevertToLeftClick); registry->RegisterForeignPref( + prefs::kAccessibilityAutoclickStabilizePosition); + registry->RegisterForeignPref( prefs::kAccessibilityAutoclickMovementThreshold); registry->RegisterForeignPref(prefs::kAccessibilityAutoclickMenuPosition); registry->RegisterForeignPref(prefs::kAccessibilityCaretHighlightEnabled); @@ -830,6 +834,11 @@ &AccessibilityController::UpdateAutoclickRevertToLeftClickFromPref, base::Unretained(this))); pref_change_registrar_->Add( + prefs::kAccessibilityAutoclickStabilizePosition, + base::BindRepeating( + &AccessibilityController::UpdateAutoclickStabilizePositionFromPref, + base::Unretained(this))); + pref_change_registrar_->Add( prefs::kAccessibilityAutoclickMovementThreshold, base::BindRepeating( &AccessibilityController::UpdateAutoclickMovementThresholdFromPref, @@ -902,6 +911,7 @@ UpdateAutoclickDelayFromPref(); UpdateAutoclickEventTypeFromPref(); UpdateAutoclickRevertToLeftClickFromPref(); + UpdateAutoclickStabilizePositionFromPref(); UpdateAutoclickMovementThresholdFromPref(); UpdateAutoclickMenuPositionFromPref(); UpdateCaretHighlightFromPref(); @@ -975,6 +985,15 @@ revert_to_left_click); } +void AccessibilityController::UpdateAutoclickStabilizePositionFromPref() { + DCHECK(active_user_prefs_); + bool stabilize_position = active_user_prefs_->GetBoolean( + prefs::kAccessibilityAutoclickStabilizePosition); + + Shell::Get()->autoclick_controller()->set_stabilize_click_position( + stabilize_position); +} + void AccessibilityController::UpdateAutoclickMovementThresholdFromPref() { DCHECK(active_user_prefs_); int movement_threshold = active_user_prefs_->GetInteger(
diff --git a/ash/accessibility/accessibility_controller.h b/ash/accessibility/accessibility_controller.h index 004305d..d28156d 100644 --- a/ash/accessibility/accessibility_controller.h +++ b/ash/accessibility/accessibility_controller.h
@@ -207,6 +207,7 @@ void UpdateAutoclickDelayFromPref(); void UpdateAutoclickEventTypeFromPref(); void UpdateAutoclickRevertToLeftClickFromPref(); + void UpdateAutoclickStabilizePositionFromPref(); void UpdateAutoclickMovementThresholdFromPref(); void UpdateAutoclickMenuPositionFromPref(); void UpdateCaretHighlightFromPref();
diff --git a/ash/app_list/app_list_controller_impl.cc b/ash/app_list/app_list_controller_impl.cc index cba5aad4..e1af3cc 100644 --- a/ash/app_list/app_list_controller_impl.cc +++ b/ash/app_list/app_list_controller_impl.cc
@@ -761,11 +761,6 @@ return ash::mojom::AppListViewState::kClosed; } -void AppListControllerImpl::SetStateTransitionAnimationCallback( - StateTransitionAnimationCallback callback) { - state_transition_animation_callback_ = std::move(callback); -} - void AppListControllerImpl::SetAppListModelForTest( std::unique_ptr<app_list::AppListModel> model) { model_->RemoveObserver(this); @@ -773,6 +768,19 @@ model_->AddObserver(this); } +void AppListControllerImpl::SetStateTransitionAnimationCallback( + StateTransitionAnimationCallback callback) { + state_transition_animation_callback_ = std::move(callback); +} + +void AppListControllerImpl::RecordShelfAppLaunched( + base::Optional<mojom::AppListViewState> recorded_app_list_view_state) { + app_list::RecordAppListAppLaunched( + mojom::AppListLaunchedFrom::kLaunchedFromShelf, + recorded_app_list_view_state.value_or(GetAppListViewState()), + IsTabletMode(), presenter_.home_launcher_shown()); +} + //////////////////////////////////////////////////////////////////////////////// // Methods of |client_|: @@ -809,6 +817,18 @@ if (!result) return; + if (launch_type == mojom::AppListLaunchType::kAppSearchResult) { + switch (launched_from) { + case mojom::AppListLaunchedFrom::kLaunchedFromSearchBox: + case mojom::AppListLaunchedFrom::kLaunchedFromSuggestionChip: + RecordAppLaunched(launched_from); + break; + case mojom::AppListLaunchedFrom::kLaunchedFromGrid: + case mojom::AppListLaunchedFrom::kLaunchedFromShelf: + break; + } + } + UMA_HISTOGRAM_ENUMERATION(app_list::kSearchResultOpenDisplayTypeHistogram, result->display_type(), ash::SearchResultDisplayType::kLast); @@ -884,7 +904,13 @@ void AppListControllerImpl::SearchResultContextMenuItemSelected( const std::string& result_id, int command_id, - int event_flags) { + int event_flags, + mojom::AppListLaunchType launch_type) { + if (launch_type == mojom::AppListLaunchType::kAppSearchResult && + app_list::IsCommandIdAnAppLaunch(command_id)) { + RecordAppLaunched(mojom::AppListLaunchedFrom::kLaunchedFromSearchBox); + } + if (client_) { client_->SearchResultContextMenuItemSelected(result_id, command_id, event_flags); @@ -904,7 +930,8 @@ void AppListControllerImpl::ViewClosing() { if (presenter_.GetView()->search_box_view()->is_search_box_active()) { - LogSearchAbandonHistogram(); + // Close the search box if it is open when the app list is closing. + presenter_.HandleCloseOpenSearchBox(); // Close the virtual keyboard before the app list view is dismissed. // Otherwise if the browser is behind the app list view, after the latter is @@ -932,8 +959,12 @@ Shell::Get()->wallpaper_controller()->GetWallpaperColors(std::move(callback)); } -void AppListControllerImpl::ActivateItem(const std::string& id, - int event_flags) { +void AppListControllerImpl::ActivateItem( + const std::string& id, + int event_flags, + mojom::AppListLaunchedFrom launched_from) { + RecordAppLaunched(launched_from); + if (client_) client_->ActivateItem(profile_id_, id, event_flags); @@ -947,9 +978,14 @@ client_->GetContextMenuModel(profile_id_, id, std::move(callback)); } -void AppListControllerImpl::ContextMenuItemSelected(const std::string& id, - int command_id, - int event_flags) { +void AppListControllerImpl::ContextMenuItemSelected( + const std::string& id, + int command_id, + int event_flags, + mojom::AppListLaunchedFrom launched_from) { + if (app_list::IsCommandIdAnAppLaunch(command_id)) + RecordAppLaunched(launched_from); + if (client_) client_->ContextMenuItemSelected(profile_id_, id, command_id, event_flags); } @@ -1042,6 +1078,13 @@ state_transition_animation_callback_.Run(state); } +void AppListControllerImpl::RecordAppLaunched( + mojom::AppListLaunchedFrom launched_from) { + app_list::RecordAppListAppLaunched(launched_from, GetAppListViewState(), + IsTabletMode(), + presenter_.home_launcher_shown()); +} + void AppListControllerImpl::AddObserver(AppListControllerObserver* observer) { observers_.AddObserver(observer); }
diff --git a/ash/app_list/app_list_controller_impl.h b/ash/app_list/app_list_controller_impl.h index c28277f..0fe4d06 100644 --- a/ash/app_list/app_list_controller_impl.h +++ b/ash/app_list/app_list_controller_impl.h
@@ -174,20 +174,26 @@ void GetSearchResultContextMenuModel( const std::string& result_id, GetContextMenuModelCallback callback) override; - void SearchResultContextMenuItemSelected(const std::string& result_id, - int command_id, - int event_flags) override; + void SearchResultContextMenuItemSelected( + const std::string& result_id, + int command_id, + int event_flags, + mojom::AppListLaunchType launch_type) override; void ViewShown(int64_t display_id) override; void ViewClosing() override; void ViewClosed() override; void GetWallpaperProminentColors( GetWallpaperProminentColorsCallback callback) override; - void ActivateItem(const std::string& id, int event_flags) override; + void ActivateItem(const std::string& id, + int event_flags, + mojom::AppListLaunchedFrom launched_from) override; void GetContextMenuModel(const std::string& id, GetContextMenuModelCallback callback) override; - void ContextMenuItemSelected(const std::string& id, - int command_id, - int event_flags) override; + void ContextMenuItemSelected( + const std::string& id, + int command_id, + int event_flags, + mojom::AppListLaunchedFrom launched_from) override; void ShowWallpaperContextMenu(const gfx::Point& onscreen_location, ui::MenuSourceType source_type) override; bool ProcessHomeLauncherGesture(ui::GestureEvent* event, @@ -294,6 +300,9 @@ void SetStateTransitionAnimationCallback( StateTransitionAnimationCallback callback); + void RecordShelfAppLaunched( + base::Optional<mojom::AppListViewState> recorded_app_list_view_state); + private: syncer::StringOrdinal GetOemFolderPos(); std::unique_ptr<app_list::AppListItem> CreateAppListItem( @@ -319,6 +328,9 @@ // Shuts down the AppListControllerImpl, removing itself as an observer. void Shutdown(); + // Record the app launch for AppListAppLaunchedV2 metric. + void RecordAppLaunched(mojom::AppListLaunchedFrom launched_from); + base::string16 last_raw_query_; mojom::AppListClientPtr client_;
diff --git a/ash/app_list/app_list_metrics.cc b/ash/app_list/app_list_metrics.cc index 7fea925..ca051e66 100644 --- a/ash/app_list/app_list_metrics.cc +++ b/ash/app_list/app_list_metrics.cc
@@ -9,6 +9,7 @@ #include "ash/app_list/model/app_list_model.h" #include "ash/app_list/model/search/search_model.h" #include "ash/app_list/model/search/search_result.h" +#include "ash/public/cpp/app_menu_constants.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/time/time.h" @@ -73,6 +74,24 @@ constexpr char kSearchAbandonQueryLengthHistogram[] = "Apps.AppListSearchAbandonQueryLength"; +// The UMA histograms that log app launches within the AppList and shelf. The +// app launches are divided by histogram for each of the the different AppList +// states. +constexpr char kAppListAppLaunchedClosed[] = "Apps.AppListAppLaunchedV2.Closed"; +constexpr char kAppListAppLaunchedPeeking[] = + "Apps.AppListAppLaunchedV2.Peeking"; +constexpr char kAppListAppLaunchedHalf[] = "Apps.AppListAppLaunchedV2.Half"; +constexpr char kAppListAppLaunchedFullscreenAllApps[] = + "Apps.AppListAppLaunchedV2.FullscreenAllApps"; +constexpr char kAppListAppLaunchedFullscreenSearch[] = + "Apps.AppListAppLaunchedV2.FullscreenSearch"; +constexpr char kAppListAppLaunchedHomecherClosed[] = + "Apps.AppListAppLaunchedV2.HomecherClosed"; +constexpr char kAppListAppLaunchedHomecherAllApps[] = + "Apps.AppListAppLaunchedV2.HomecherAllApps"; +constexpr char kAppListAppLaunchedHomecherSearch[] = + "Apps.AppListAppLaunchedV2.HomecherSearch"; + // The different sources from which a search result is displayed. These values // are written to logs. New enum values can be added, but existing enums must // never be renumbered or deleted and reused. @@ -171,4 +190,112 @@ removal_decision); } +void RecordAppListAppLaunched(ash::mojom::AppListLaunchedFrom launched_from, + ash::mojom::AppListViewState app_list_state, + bool is_tablet_mode, + bool home_launcher_shown) { + switch (app_list_state) { + case ash::mojom::AppListViewState::kClosed: + UMA_HISTOGRAM_ENUMERATION(kAppListAppLaunchedClosed, launched_from); + break; + case ash::mojom::AppListViewState::kPeeking: + UMA_HISTOGRAM_ENUMERATION(kAppListAppLaunchedPeeking, launched_from); + break; + case ash::mojom::AppListViewState::kHalf: + UMA_HISTOGRAM_ENUMERATION(kAppListAppLaunchedHalf, launched_from); + break; + case ash::mojom::AppListViewState::kFullscreenAllApps: + if (is_tablet_mode) { + if (home_launcher_shown) { + UMA_HISTOGRAM_ENUMERATION(kAppListAppLaunchedHomecherAllApps, + launched_from); + } else { + UMA_HISTOGRAM_ENUMERATION(kAppListAppLaunchedHomecherClosed, + launched_from); + } + } else { + UMA_HISTOGRAM_ENUMERATION(kAppListAppLaunchedFullscreenAllApps, + launched_from); + } + break; + case ash::mojom::AppListViewState::kFullscreenSearch: + if (is_tablet_mode) { + if (home_launcher_shown) { + UMA_HISTOGRAM_ENUMERATION(kAppListAppLaunchedHomecherSearch, + launched_from); + } else { + // (http://crbug.com/947729) Search box still expanded when opening + // launcher in tablet mode + UMA_HISTOGRAM_ENUMERATION(kAppListAppLaunchedHomecherClosed, + launched_from); + } + } else { + UMA_HISTOGRAM_ENUMERATION(kAppListAppLaunchedFullscreenSearch, + launched_from); + } + break; + } +} + +bool IsCommandIdAnAppLaunch(int command_id_number) { + ash::CommandId command_id = static_cast<ash::CommandId>(command_id_number); + + // Consider all platform app menu options as launches. + if (command_id >= ash::CommandId::USE_LAUNCH_TYPE_COMMAND_END && + command_id < ash::CommandId::LAUNCH_APP_SHORTCUT_FIRST) { + return true; + } + + // Consider all arc app shortcut options as launches. + if (command_id >= ash::CommandId::LAUNCH_APP_SHORTCUT_FIRST && + command_id < ash::CommandId::LAUNCH_APP_SHORTCUT_LAST) { + return true; + } + + switch (command_id) { + // Used by LauncherContextMenu (shelf). + case ash::CommandId::MENU_OPEN_NEW: + case ash::CommandId::MENU_NEW_WINDOW: + case ash::CommandId::MENU_NEW_INCOGNITO_WINDOW: + // Used by AppContextMenu. + case ash::CommandId::LAUNCH_NEW: + case ash::CommandId::SHOW_APP_INFO: + case ash::CommandId::OPTIONS: + case ash::CommandId::APP_CONTEXT_MENU_NEW_WINDOW: + case ash::CommandId::APP_CONTEXT_MENU_NEW_INCOGNITO_WINDOW: + // Used by both AppContextMenu and LauncherContextMenu for app shortcuts. + case ash::CommandId::LAUNCH_APP_SHORTCUT_FIRST: + case ash::CommandId::LAUNCH_APP_SHORTCUT_LAST: + return true; + + // Used by LauncherContextMenu (shelf). + case ash::CommandId::MENU_CLOSE: + case ash::CommandId::MENU_PIN: + case ash::CommandId::LAUNCH_TYPE_PINNED_TAB: + case ash::CommandId::LAUNCH_TYPE_REGULAR_TAB: + case ash::CommandId::LAUNCH_TYPE_FULLSCREEN: + case ash::CommandId::LAUNCH_TYPE_WINDOW: + // Used by AppMenuModelAdapter + case ash::CommandId::NOTIFICATION_CONTAINER: + // Used by CrostiniShelfContextMenu. + case ash::CommandId::CROSTINI_USE_LOW_DENSITY: + case ash::CommandId::CROSTINI_USE_HIGH_DENSITY: + // Used by AppContextMenu. + case ash::CommandId::TOGGLE_PIN: + case ash::CommandId::UNINSTALL: + case ash::CommandId::REMOVE_FROM_FOLDER: + case ash::CommandId::INSTALL: + case ash::CommandId::USE_LAUNCH_TYPE_PINNED: + case ash::CommandId::USE_LAUNCH_TYPE_REGULAR: + case ash::CommandId::USE_LAUNCH_TYPE_FULLSCREEN: + case ash::CommandId::USE_LAUNCH_TYPE_WINDOW: + case ash::CommandId::USE_LAUNCH_TYPE_COMMAND_END: + case ash::CommandId::STOP_APP: + case ash::CommandId::COMMAND_ID_COUNT: + return false; + } + NOTREACHED(); + return false; +} + } // namespace app_list
diff --git a/ash/app_list/app_list_metrics.h b/ash/app_list/app_list_metrics.h index b8fb46c..8ef8de1 100644 --- a/ash/app_list/app_list_metrics.h +++ b/ash/app_list/app_list_metrics.h
@@ -6,6 +6,8 @@ #define ASH_APP_LIST_APP_LIST_METRICS_H_ #include "ash/app_list/app_list_export.h" +#include "ash/public/interfaces/app_list.mojom.h" +#include "ash/public/interfaces/app_list_view.mojom.h" namespace app_list { @@ -23,14 +25,6 @@ constexpr char kAppListHideInputLatencyHistogram[] = "Apps.AppListHide.InputLatency"; -// The UMA histogram that logs usage of suggested and regular apps. -constexpr char kAppListAppLaunched[] = "Apps.AppListAppLaunched"; - -// The UMA histogram that logs usage of suggested and regular apps while the -// fullscreen launcher is enabled. -constexpr char kAppListAppLaunchedFullscreen[] = - "Apps.AppListAppLaunchedFullscreen"; - // The UMA histogram that logs different ways to move an app in app list's apps // grid. constexpr char kAppListAppMovingType[] = "Apps.AppListAppMovingType"; @@ -240,6 +234,14 @@ int query_length, int suggestion_index); +APP_LIST_EXPORT void RecordAppListAppLaunched( + ash::mojom::AppListLaunchedFrom launched_from, + ash::mojom::AppListViewState app_list_state, + bool is_tablet_mode, + bool home_launcher_shown); + +APP_LIST_EXPORT bool IsCommandIdAnAppLaunch(int command_id); + } // namespace app_list #endif // ASH_APP_LIST_APP_LIST_METRICS_H_
diff --git a/ash/app_list/app_list_presenter_delegate_impl.cc b/ash/app_list/app_list_presenter_delegate_impl.cc index f8f8f310..67ad066 100644 --- a/ash/app_list/app_list_presenter_delegate_impl.cc +++ b/ash/app_list/app_list_presenter_delegate_impl.cc
@@ -243,10 +243,6 @@ if (status_window && status_window->Contains(target)) auto_hide_lock.emplace(shelf); - // Since event happened outside the app list, close the open search box if - // it is open. - presenter_->HandleCloseOpenSearchBox(); - // Keep app list opened if event happened in the shelf area. if (!shelf_window || !shelf_window->Contains(target)) presenter_->Dismiss(event->time_stamp());
diff --git a/ash/app_list/app_list_view_delegate.h b/ash/app_list/app_list_view_delegate.h index 71b912c..2a834a7 100644 --- a/ash/app_list/app_list_view_delegate.h +++ b/ash/app_list/app_list_view_delegate.h
@@ -97,9 +97,11 @@ // |result_id| is the clicked SearchResult's id // |command_id| is the clicked menu item's command id // |event_flags| is flags from the event which triggered this command - virtual void SearchResultContextMenuItemSelected(const std::string& result_id, - int command_id, - int event_flags) = 0; + virtual void SearchResultContextMenuItemSelected( + const std::string& result_id, + int command_id, + int event_flags, + ash::mojom::AppListLaunchType launch_type) = 0; // Invoked when the app list is shown. virtual void ViewShown(int64_t display_id) = 0; @@ -121,7 +123,9 @@ GetWallpaperProminentColorsCallback callback) = 0; // Activates (opens) the item. - virtual void ActivateItem(const std::string& id, int event_flags) = 0; + virtual void ActivateItem(const std::string& id, + int event_flags, + ash::mojom::AppListLaunchedFrom launched_from) = 0; // Returns the context menu model for a ChromeAppListItem with |id|, or NULL // if there is currently no menu for the item (e.g. during install). @@ -133,9 +137,11 @@ // |id| is the clicked AppListItem's id // |command_id| is the clicked menu item's command id // |event_flags| is flags from the event which triggered this command - virtual void ContextMenuItemSelected(const std::string& id, - int command_id, - int event_flags) = 0; + virtual void ContextMenuItemSelected( + const std::string& id, + int command_id, + int event_flags, + ash::mojom::AppListLaunchedFrom launched_from) = 0; // Show wallpaper context menu from the specified onscreen location. virtual void ShowWallpaperContextMenu(const gfx::Point& onscreen_location,
diff --git a/ash/app_list/presenter/app_list_presenter_impl.cc b/ash/app_list/presenter/app_list_presenter_impl.cc index 6f1776bf..d0a0c7a8 100644 --- a/ash/app_list/presenter/app_list_presenter_impl.cc +++ b/ash/app_list/presenter/app_list_presenter_impl.cc
@@ -163,7 +163,7 @@ } bool AppListPresenterImpl::HandleCloseOpenSearchBox() { - return is_visible_ && view_ && view_->HandleCloseOpenSearchBox(); + return view_ && view_->HandleCloseOpenSearchBox(); } ash::ShelfAction AppListPresenterImpl::ToggleAppList( @@ -379,6 +379,16 @@ aura::Window* lost_focus) { if (view_ && is_visible_) { aura::Window* applist_window = view_->GetWidget()->GetNativeView(); + + if (delegate_->IsTabletMode()) { + if (applist_window->Contains(lost_focus)) { + home_launcher_shown_ = false; + HandleCloseOpenSearchBox(); + } else if (applist_window->Contains(gained_focus)) { + home_launcher_shown_ = true; + } + } + aura::Window* applist_container = applist_window->parent(); if (applist_container->Contains(lost_focus) && (!gained_focus || !applist_container->Contains(gained_focus)) &&
diff --git a/ash/app_list/presenter/app_list_presenter_impl.h b/ash/app_list/presenter/app_list_presenter_impl.h index ad54a25..4f4c536 100644 --- a/ash/app_list/presenter/app_list_presenter_impl.h +++ b/ash/app_list/presenter/app_list_presenter_impl.h
@@ -131,6 +131,9 @@ // Show/hide the expand arrow view button. void SetExpandArrowViewVisibility(bool show); + // Returns whether home launcher is currently shown. + bool home_launcher_shown() const { return home_launcher_shown_; } + private: // Sets the app list view and attempts to show it. void SetView(AppListView* view); @@ -201,6 +204,9 @@ // If true, dismiss the app list immediately. bool dismiss_without_animation_ = false; + // Whether the home launcher is currently shown. + bool home_launcher_shown_ = false; + DISALLOW_COPY_AND_ASSIGN(AppListPresenterImpl); };
diff --git a/ash/app_list/test/app_list_test_view_delegate.cc b/ash/app_list/test/app_list_test_view_delegate.cc index 6c223b2..5d29935 100644 --- a/ash/app_list/test/app_list_test_view_delegate.cc +++ b/ash/app_list/test/app_list_test_view_delegate.cc
@@ -53,6 +53,18 @@ } } ++open_search_result_count_; + + if (launch_type == ash::mojom::AppListLaunchType::kAppSearchResult) { + switch (launched_from) { + case ash::mojom::AppListLaunchedFrom::kLaunchedFromSearchBox: + case ash::mojom::AppListLaunchedFrom::kLaunchedFromSuggestionChip: + RecordAppLaunched(launched_from); + return; + case ash::mojom::AppListLaunchedFrom::kLaunchedFromGrid: + case ash::mojom::AppListLaunchedFrom::kLaunchedFromShelf: + return; + } + } } void AppListTestViewDelegate::DismissAppList() { @@ -69,13 +81,16 @@ search_model_->SetSearchEngineIsGoogle(is_google); } -void AppListTestViewDelegate::ActivateItem(const std::string& id, - int event_flags) { +void AppListTestViewDelegate::ActivateItem( + const std::string& id, + int event_flags, + ash::mojom::AppListLaunchedFrom launched_from) { app_list::AppListItem* item = model_->FindItem(id); if (!item) return; DCHECK(!item->is_folder()); static_cast<AppListTestModel::AppListTestItem*>(item)->Activate(event_flags); + RecordAppLaunched(launched_from); } void AppListTestViewDelegate::GetContextMenuModel( @@ -140,6 +155,13 @@ void AppListTestViewDelegate::OnStateTransitionAnimationCompleted( ash::mojom::AppListViewState state) {} +void AppListTestViewDelegate::RecordAppLaunched( + ash::mojom::AppListLaunchedFrom launched_from) { + app_list::RecordAppListAppLaunched(launched_from, model_->state_fullscreen(), + false /*tablet mode*/, + false /*home launcher shown*/); +} + bool AppListTestViewDelegate::IsCommandIdChecked(int command_id) const { return true; }
diff --git a/ash/app_list/test/app_list_test_view_delegate.h b/ash/app_list/test/app_list_test_view_delegate.h index b832494e..a26cbf7 100644 --- a/ash/app_list/test/app_list_test_view_delegate.h +++ b/ash/app_list/test/app_list_test_view_delegate.h
@@ -15,6 +15,7 @@ #include "ash/app_list/app_list_view_delegate.h" #include "ash/app_list/model/search/search_model.h" #include "ash/app_list/test/app_list_test_model.h" +#include "ash/public/interfaces/app_list.mojom.h" #include "base/callback_forward.h" #include "base/compiler_specific.h" #include "base/macros.h" @@ -74,21 +75,27 @@ void GetSearchResultContextMenuModel( const std::string& result_id, GetContextMenuModelCallback callback) override; - void SearchResultContextMenuItemSelected(const std::string& result_id, - int command_id, - int event_flags) override {} + void SearchResultContextMenuItemSelected( + const std::string& result_id, + int command_id, + int event_flags, + ash::mojom::AppListLaunchType launch_type) override {} void ViewShown(int64_t display_id) override {} void DismissAppList() override; void ViewClosing() override {} void ViewClosed() override {} void GetWallpaperProminentColors( GetWallpaperProminentColorsCallback callback) override {} - void ActivateItem(const std::string& id, int event_flags) override; + void ActivateItem(const std::string& id, + int event_flags, + ash::mojom::AppListLaunchedFrom launched_from) override; void GetContextMenuModel(const std::string& id, GetContextMenuModelCallback callback) override; - void ContextMenuItemSelected(const std::string& id, - int command_id, - int event_flags) override {} + void ContextMenuItemSelected( + const std::string& id, + int command_id, + int event_flags, + ash::mojom::AppListLaunchedFrom launched_from) override {} void ShowWallpaperContextMenu(const gfx::Point& onscreen_location, ui::MenuSourceType source_type) override; bool ProcessHomeLauncherGesture(ui::GestureEvent* event, @@ -111,6 +118,8 @@ AppListTestModel* GetTestModel() { return model_.get(); } private: + void RecordAppLaunched(ash::mojom::AppListLaunchedFrom launched_from); + // ui::SimpleMenuModel::Delegate overrides: bool IsCommandIdChecked(int command_id) const override; bool IsCommandIdEnabled(int command_id) const override;
diff --git a/ash/app_list/views/app_list_item_view.cc b/ash/app_list/views/app_list_item_view.cc index 80d9005..f451e25 100644 --- a/ash/app_list/views/app_list_item_view.cc +++ b/ash/app_list/views/app_list_item_view.cc
@@ -8,12 +8,14 @@ #include <utility> #include <vector> +#include "ash/app_list/app_list_metrics.h" #include "ash/app_list/app_list_view_delegate.h" #include "ash/app_list/model/app_list_folder_item.h" #include "ash/app_list/model/app_list_item.h" #include "ash/app_list/views/apps_grid_view.h" #include "ash/public/cpp/app_list/app_list_config.h" #include "ash/public/cpp/app_list/app_list_switches.h" +#include "ash/public/interfaces/app_list.mojom.h" #include "base/auto_reset.h" #include "base/bind.h" #include "base/strings/utf_string_conversions.h" @@ -508,8 +510,9 @@ void AppListItemView::ExecuteCommand(int command_id, int event_flags) { if (item_weak_) { - delegate_->ContextMenuItemSelected(item_weak_->id(), command_id, - event_flags); + delegate_->ContextMenuItemSelected( + item_weak_->id(), command_id, event_flags, + ash::mojom::AppListLaunchedFrom::kLaunchedFromGrid); } }
diff --git a/ash/app_list/views/app_list_main_view.cc b/ash/app_list/views/app_list_main_view.cc index 444fd70..4df7a50 100644 --- a/ash/app_list/views/app_list_main_view.cc +++ b/ash/app_list/views/app_list_main_view.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include <memory> +#include "ash/app_list/app_list_metrics.h" #include "ash/app_list/app_list_view_delegate.h" #include "ash/app_list/model/app_list_folder_item.h" #include "ash/app_list/model/app_list_item.h" @@ -163,9 +164,8 @@ kFullscreenAppListFolders, kMaxFolderOpened); } else { base::RecordAction(base::UserMetricsAction("AppList_ClickOnApp")); - delegate_->ActivateItem(item->id(), event_flags); - UMA_HISTOGRAM_BOOLEAN(kAppListAppLaunchedFullscreen, - false /*not a suggested app*/); + delegate_->ActivateItem(item->id(), event_flags, + ash::mojom::AppListLaunchedFrom::kLaunchedFromGrid); } }
diff --git a/ash/app_list/views/apps_grid_view_unittest.cc b/ash/app_list/views/apps_grid_view_unittest.cc index 18c15c6..a8a9124 100644 --- a/ash/app_list/views/apps_grid_view_unittest.cc +++ b/ash/app_list/views/apps_grid_view_unittest.cc
@@ -408,23 +408,23 @@ base::HistogramTester histogram_tester; model_->PopulateApps(5); - // Select the first suggested app and launch it. + // Select the first app in grid and launch it. contents_view_->GetAppListMainView()->ActivateApp(GetItemViewAt(0)->item(), 0); - // Test that histograms recorded that a regular app launched. - histogram_tester.ExpectBucketCount("Apps.AppListAppLaunchedFullscreen", 0, 1); - // Test that histograms did not record that a suggested launched. - histogram_tester.ExpectBucketCount("Apps.AppListAppLaunchedFullscreen", 1, 0); + // Test that histogram recorded app launch from grid. + histogram_tester.ExpectBucketCount( + "Apps.AppListAppLaunchedV2.FullscreenAllApps", 1 /* kAppListItem */, + 1 /* Times kAppListItem launched */); // Launch a suggested app. suggestions_container_->child_at(0)->OnKeyPressed( ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RETURN, ui::EF_NONE)); - // Test that histograms recorded that a suggested app launched, and that the - // count for regular apps launched is unchanged. - histogram_tester.ExpectBucketCount("Apps.AppListAppLaunchedFullscreen", 0, 1); - histogram_tester.ExpectBucketCount("Apps.AppListAppLaunchedFullscreen", 1, 1); + // Test that histogram recorded app launched from suggestion chip. + histogram_tester.ExpectBucketCount( + "Apps.AppListAppLaunchedV2.FullscreenAllApps", 2 /* kSuggestionChip */, + 1 /* Times kSuggestionChip Launched */); } TEST_F(AppsGridViewTest, ItemLabelShortNameOverride) {
diff --git a/ash/app_list/views/search_result_suggestion_chip_view.cc b/ash/app_list/views/search_result_suggestion_chip_view.cc index f3bbc3be..813b829 100644 --- a/ash/app_list/views/search_result_suggestion_chip_view.cc +++ b/ash/app_list/views/search_result_suggestion_chip_view.cc
@@ -49,9 +49,6 @@ base::UmaHistogramSparse("Apps.AppListSuggestedChipLaunched", index_in_suggestion_chip_container); - UMA_HISTOGRAM_BOOLEAN(kAppListAppLaunchedFullscreen, - true /* suggested app */); - base::RecordAction(base::UserMetricsAction("AppList_OpenSuggestedApp")); }
diff --git a/ash/app_list/views/search_result_tile_item_view.cc b/ash/app_list/views/search_result_tile_item_view.cc index 6983d99..3e4906e 100644 --- a/ash/app_list/views/search_result_tile_item_view.cc +++ b/ash/app_list/views/search_result_tile_item_view.cc
@@ -381,7 +381,8 @@ void SearchResultTileItemView::ExecuteCommand(int command_id, int event_flags) { if (result()) { view_delegate_->SearchResultContextMenuItemSelected( - result()->id(), command_id, event_flags); + result()->id(), command_id, event_flags, + ash::mojom::AppListLaunchType::kAppSearchResult); } }
diff --git a/ash/app_list/views/search_result_view.cc b/ash/app_list/views/search_result_view.cc index 117b4507..478e77f6 100644 --- a/ash/app_list/views/search_result_view.cc +++ b/ash/app_list/views/search_result_view.cc
@@ -17,6 +17,7 @@ #include "ash/app_list/views/search_result_list_view.h" #include "ash/public/cpp/app_list/app_list_config.h" #include "ash/public/cpp/app_list/app_list_switches.h" +#include "ash/public/interfaces/app_list.mojom.h" #include "base/bind.h" #include "base/strings/utf_string_conversions.h" #include "ui/gfx/canvas.h" @@ -531,7 +532,8 @@ void SearchResultView::ExecuteCommand(int command_id, int event_flags) { if (result()) { view_delegate_->SearchResultContextMenuItemSelected( - result()->id(), command_id, event_flags); + result()->id(), command_id, event_flags, + ash::mojom::AppListLaunchType::kSearchResult); } }
diff --git a/ash/autoclick/autoclick_controller.cc b/ash/autoclick/autoclick_controller.cc index c03ceee..3ab1aca 100644 --- a/ash/autoclick/autoclick_controller.cc +++ b/ash/autoclick/autoclick_controller.cc
@@ -425,6 +425,11 @@ } else if (start_gesture_timer_->IsRunning()) { // Keep track of where the gesture will be anchored. gesture_anchor_location_ = point_in_screen; + } else if (autoclick_timer_->IsRunning() && !stabilize_click_position_) { + // If we are not stabilizing the click position, update the gesture + // center with each mouse move event. + anchor_location_ = point_in_screen; + autoclick_ring_handler_->SetGestureCenter(point_in_screen, widget_.get()); } } else if (event->type() == ui::ET_MOUSE_PRESSED || event->type() == ui::ET_MOUSE_RELEASED) {
diff --git a/ash/autoclick/autoclick_controller.h b/ash/autoclick/autoclick_controller.h index 26729b9..b0d26008 100644 --- a/ash/autoclick/autoclick_controller.h +++ b/ash/autoclick/autoclick_controller.h
@@ -66,6 +66,17 @@ revert_to_left_click_ = revert_to_left_click; } + // Sets whether to stabilize the cursor position during a click. + // If |stabilize_position|, the click position will not change after the + // autoclick timer and gesture animation begin, so long as the cursor does + // not move outside of the movement threshold. If the position is not + // stabilized, the cursor movements will translate into autoclick position + // movements (but a cursor movement larger than the movement threshold from + // the starting position will still cancel the click). + void set_stabilize_click_position(bool stabilize_position) { + stabilize_click_position_ = stabilize_position; + } + // Functionality for testing. static float GetStartGestureDelayRatioForTesting(); AutoclickMenuBubbleController* GetMenuBubbleControllerForTesting() { @@ -103,6 +114,7 @@ bool enabled_ = false; mojom::AutoclickEventType event_type_ = kDefaultAutoclickEventType; bool revert_to_left_click_ = true; + bool stabilize_click_position_ = false; int movement_threshold_ = kDefaultAutoclickMovementThreshold; // TODO(katie): The default position should flex with the user's choice of // language (RTL vs LTR) and shelf position, following the same behavior
diff --git a/ash/autoclick/autoclick_unittest.cc b/ash/autoclick/autoclick_unittest.cc index d245f1c..ab87cfe 100644 --- a/ash/autoclick/autoclick_unittest.cc +++ b/ash/autoclick/autoclick_unittest.cc
@@ -278,13 +278,13 @@ int animation_delay = 5; int full_delay = UpdateAnimationDelayAndGetFullDelay(animation_delay); + GetAutoclickController()->set_stabilize_click_position(true); GetEventGenerator()->MoveMouseTo(100, 100); FastForwardBy(animation_delay + 1); // Move the mouse within the threshold. It shouldn't change the eventual // target of the event, or cancel the click. GetEventGenerator()->MoveMouseTo(110, 110); - ClearMouseEvents(); FastForwardBy(full_delay); std::vector<ui::MouseEvent> events = GetMouseEvents(); @@ -297,6 +297,25 @@ EXPECT_EQ(ui::ET_MOUSE_RELEASED, events[1].type()); EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, events[1].flags()); + // When the click position is not stabilized, the mouse movement should + // translate into the target of the event, but not cancel the click. + GetAutoclickController()->set_stabilize_click_position(false); + GetEventGenerator()->MoveMouseTo(200, 200); + FastForwardBy(animation_delay + 1); + GetEventGenerator()->MoveMouseTo(210, 210); + + ClearMouseEvents(); + FastForwardBy(full_delay); + events = GetMouseEvents(); + + EXPECT_EQ(2u, events.size()); + EXPECT_EQ(gfx::Point(210, 210), events[0].location()); + EXPECT_EQ(ui::ET_MOUSE_PRESSED, events[0].type()); + EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, events[0].flags()); + EXPECT_EQ(gfx::Point(210, 210), events[1].location()); + EXPECT_EQ(ui::ET_MOUSE_RELEASED, events[1].type()); + EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, events[1].flags()); + // Reset delay. GetAutoclickController()->SetAutoclickDelay(base::TimeDelta()); } @@ -595,8 +614,7 @@ FastForwardBy(animation_delay - 1); GetEventGenerator()->MoveMouseTo(105, 105); - // Fast forward until the animation would have started. Now moving the mouse - // a little does not change the center point. + // Moving the mouse during the animation changes the center point. FastForwardBy(animation_delay); GetEventGenerator()->MoveMouseTo(110, 110); @@ -605,7 +623,29 @@ FastForwardBy(full_delay); events = GetMouseEvents(); ASSERT_EQ(2u, events.size()); - EXPECT_EQ(gfx::Point(105, 105), events[0].location()); + EXPECT_EQ(gfx::Point(110, 110), events[0].location()); + + // Turn off stabilize_click_position and try again, the position should update + // with the cursor's new position until the click occurs. + GetAutoclickController()->set_stabilize_click_position(true); + ClearMouseEvents(); + GetEventGenerator()->MoveMouseTo(200, 200); + + // (205, 205) will become the center of the animation. + FastForwardBy(animation_delay - 1); + GetEventGenerator()->MoveMouseTo(205, 205); + + // Fast forward until the animation would have started. Now moving the mouse + // a little does not change the center point because we have stabilize on. + FastForwardBy(animation_delay); + GetEventGenerator()->MoveMouseTo(210, 210); + FastForwardBy(full_delay); + events = GetMouseEvents(); + ASSERT_EQ(2u, events.size()); + EXPECT_EQ(gfx::Point(205, 205), events[0].location()); + + // Reset state. + GetAutoclickController()->set_stabilize_click_position(false); } TEST_F(AutoclickTest, DoesActionOnBubbleWhenInDifferentModes) {
diff --git a/ash/components/shortcut_viewer/views/keyboard_shortcut_view.cc b/ash/components/shortcut_viewer/views/keyboard_shortcut_view.cc index c673255..b65dd99 100644 --- a/ash/components/shortcut_viewer/views/keyboard_shortcut_view.cc +++ b/ash/components/shortcut_viewer/views/keyboard_shortcut_view.cc
@@ -92,11 +92,17 @@ class ShortcutsListScrollView : public views::ScrollView { public: - ShortcutsListScrollView() = default; + ShortcutsListScrollView() { + GetViewAccessibility().OverrideRole(ax::mojom::Role::kScrollView); + } + ~ShortcutsListScrollView() override = default; // views::View: - void OnFocus() override { SetHasFocusIndicator(true); } + void OnFocus() override { + SetHasFocusIndicator(true); + NotifyAccessibilityEvent(ax::mojom::Event::kFocus, true); + } void OnBlur() override { SetHasFocusIndicator(false); }
diff --git a/ash/login/login_screen_test_api.cc b/ash/login/login_screen_test_api.cc index 9cdbc73..dcea068 100644 --- a/ash/login/login_screen_test_api.cc +++ b/ash/login/login_screen_test_api.cc
@@ -147,6 +147,14 @@ IsLoginShelfViewButtonShown(LoginShelfView::kShutdown)); } +void LoginScreenTestApi::IsAuthErrorBubbleShown( + IsAuthErrorBubbleShownCallback callback) { + ash::LockScreen::TestApi lock_screen_test(ash::LockScreen::Get()); + ash::LockContentsView::TestApi lock_contents_test( + lock_screen_test.contents_view()); + std::move(callback).Run(lock_contents_test.auth_error_bubble()->visible()); +} + void LoginScreenTestApi::SubmitPassword(const AccountId& account_id, const std::string& password, SubmitPasswordCallback callback) {
diff --git a/ash/login/login_screen_test_api.h b/ash/login/login_screen_test_api.h index 907881df..9d93a211 100644 --- a/ash/login/login_screen_test_api.h +++ b/ash/login/login_screen_test_api.h
@@ -27,6 +27,7 @@ void IsLoginShelfShown(IsLoginShelfShownCallback callback) override; void IsRestartButtonShown(IsRestartButtonShownCallback callback) override; void IsShutdownButtonShown(IsShutdownButtonShownCallback callback) override; + void IsAuthErrorBubbleShown(IsAuthErrorBubbleShownCallback callback) override; void SubmitPassword(const AccountId& account_id, const std::string& password, SubmitPasswordCallback callback) override;
diff --git a/ash/public/cpp/ash_pref_names.cc b/ash/public/cpp/ash_pref_names.cc index 79830f1..090c816f 100644 --- a/ash/public/cpp/ash_pref_names.cc +++ b/ash/public/cpp/ash_pref_names.cc
@@ -57,6 +57,10 @@ // another event type action, or whether it should stay as the other event type. const char kAccessibilityAutoclickRevertToLeftClick[] = "settings.a11y.autoclick_revert_to_left_click"; +// Whether Autoclick should stabilize the cursor movement before a click occurs +// or not. +const char kAccessibilityAutoclickStabilizePosition[] = + "settings.a11y.autoclick_stabilize_position"; // The default threshold of mouse movement, measured in DIP, that will initiate // a new autoclick. const char kAccessibilityAutoclickMovementThreshold[] =
diff --git a/ash/public/cpp/ash_pref_names.h b/ash/public/cpp/ash_pref_names.h index ab9792c..a8b8d71 100644 --- a/ash/public/cpp/ash_pref_names.h +++ b/ash/public/cpp/ash_pref_names.h
@@ -25,6 +25,7 @@ ASH_PUBLIC_EXPORT extern const char kAccessibilityAutoclickDelayMs[]; ASH_PUBLIC_EXPORT extern const char kAccessibilityAutoclickEventType[]; ASH_PUBLIC_EXPORT extern const char kAccessibilityAutoclickRevertToLeftClick[]; +ASH_PUBLIC_EXPORT extern const char kAccessibilityAutoclickStabilizePosition[]; ASH_PUBLIC_EXPORT extern const char kAccessibilityAutoclickMovementThreshold[]; ASH_PUBLIC_EXPORT extern const char kAccessibilityAutoclickMenuPosition[]; ASH_PUBLIC_EXPORT extern const char kAccessibilityCaretHighlightEnabled[];
diff --git a/ash/public/interfaces/app_list.mojom b/ash/public/interfaces/app_list.mojom index fbd8f7a..45128e1a 100644 --- a/ash/public/interfaces/app_list.mojom +++ b/ash/public/interfaces/app_list.mojom
@@ -103,11 +103,14 @@ // The UI component the user launched the search result from. Must match // chrome/browser/ui/app_list/app_launch_event_logger.proto. +// This enum is used in a histogram, do not remove/renumber entries. If you're +// adding to this enum with the intention that it will be logged, update the +// AppListLaunchedFrom enum listing in tools/metrics/histograms/enums.xml. enum AppListLaunchedFrom { kLaunchedFromGrid = 1, - kLaunchedFromSuggestionChip, - kLaunchedFromShelf, - kLaunchedFromSearchBox, + kLaunchedFromSuggestionChip = 2, + kLaunchedFromShelf = 3, + kLaunchedFromSearchBox = 4, }; // The UI representation of the search result. Currently all search results
diff --git a/ash/public/interfaces/login_screen_test_api.test-mojom b/ash/public/interfaces/login_screen_test_api.test-mojom index 3598b59..f9ccc56 100644 --- a/ash/public/interfaces/login_screen_test_api.test-mojom +++ b/ash/public/interfaces/login_screen_test_api.test-mojom
@@ -20,6 +20,9 @@ // Returns true if Shutdown button is currently being shown. IsShutdownButtonShown() => (bool is_shown); + // Returns true if Auth Error Button is currently being shown. + IsAuthErrorBubbleShown() => (bool is_shown); + // Submit |password| for |account_id|. SubmitPassword(signin.mojom.AccountId account_id, string password) => ();
diff --git a/ash/shelf/shelf_application_menu_model.cc b/ash/shelf/shelf_application_menu_model.cc index dcaf03d..2418a0c 100644 --- a/ash/shelf/shelf_application_menu_model.cc +++ b/ash/shelf/shelf_application_menu_model.cc
@@ -9,7 +9,9 @@ #include <limits> #include <utility> +#include "ash/app_list/app_list_controller_impl.h" #include "ash/public/cpp/shelf_item_delegate.h" +#include "ash/shell.h" #include "base/metrics/histogram_macros.h" #include "ui/display/types/display_constants.h" #include "ui/gfx/image/image.h" @@ -57,6 +59,9 @@ DCHECK(IsCommandIdEnabled(command_id)); // Have the delegate execute its own custom command id for the given item. if (delegate_) { + // Record app launch when selecting window to open from disambiguation menu. + Shell::Get()->app_list_controller()->RecordShelfAppLaunched(base::nullopt); + // The display hosting the menu is irrelevant, windows activate in-place. delegate_->ExecuteCommand(false, items_[command_id]->command_id, event_flags, display::kInvalidDisplayId);
diff --git a/ash/shelf/shelf_context_menu_model.cc b/ash/shelf/shelf_context_menu_model.cc index 5d49eeb..e6e7b7c 100644 --- a/ash/shelf/shelf_context_menu_model.cc +++ b/ash/shelf/shelf_context_menu_model.cc
@@ -8,6 +8,8 @@ #include <string> #include <utility> +#include "ash/app_list/app_list_controller_impl.h" +#include "ash/app_list/app_list_metrics.h" #include "ash/public/cpp/app_menu_constants.h" #include "ash/public/cpp/ash_pref_names.h" #include "ash/public/cpp/menu_utils.h" @@ -215,9 +217,14 @@ Shell::Get()->wallpaper_controller()->OpenWallpaperPickerIfAllowed(); break; default: - // Have the shelf item delegate execute the context menu command. - if (delegate_) + if (delegate_) { + if (app_list::IsCommandIdAnAppLaunch(command_id)) { + Shell::Get()->app_list_controller()->RecordShelfAppLaunched( + base::nullopt); + } + delegate_->ExecuteCommand(true, command_id, event_flags, display_id_); + } break; } }
diff --git a/ash/shelf/shelf_context_menu_model_unittest.cc b/ash/shelf/shelf_context_menu_model_unittest.cc index 114c8b4..272fd68 100644 --- a/ash/shelf/shelf_context_menu_model_unittest.cc +++ b/ash/shelf/shelf_context_menu_model_unittest.cc
@@ -177,14 +177,14 @@ MenuItemList items; mojom::MenuItemPtr item(mojom::MenuItem::New()); item->type = ui::MenuModel::TYPE_COMMAND; - item->command_id = 123; + item->command_id = 203; item->label = base::ASCIIToUTF16("item"); item->enabled = true; items.push_back(std::move(item)); mojom::MenuItemPtr check(mojom::MenuItem::New()); check->type = ui::MenuModel::TYPE_CHECK; - check->command_id = 999; + check->command_id = 107; check->label = base::ASCIIToUTF16("check"); check->enabled = true; check->checked = false; @@ -192,7 +192,7 @@ mojom::MenuItemPtr radio(mojom::MenuItem::New()); radio->type = ui::MenuModel::TYPE_RADIO; - radio->command_id = 1337; + radio->command_id = 101; radio->label = base::ASCIIToUTF16("radio"); radio->enabled = false; radio->checked = true; @@ -209,25 +209,25 @@ ASSERT_EQ(3, menu.GetItemCount()); EXPECT_EQ(ui::MenuModel::TYPE_COMMAND, menu.GetTypeAt(0)); - EXPECT_EQ(123, menu.GetCommandIdAt(0)); + EXPECT_EQ(203, menu.GetCommandIdAt(0)); EXPECT_EQ(base::ASCIIToUTF16("item"), menu.GetLabelAt(0)); EXPECT_TRUE(menu.IsEnabledAt(0)); EXPECT_EQ(ui::MenuModel::TYPE_CHECK, menu.GetTypeAt(1)); - EXPECT_EQ(999, menu.GetCommandIdAt(1)); + EXPECT_EQ(107, menu.GetCommandIdAt(1)); EXPECT_EQ(base::ASCIIToUTF16("check"), menu.GetLabelAt(1)); EXPECT_TRUE(menu.IsEnabledAt(1)); EXPECT_FALSE(menu.IsItemCheckedAt(1)); EXPECT_EQ(ui::MenuModel::TYPE_RADIO, menu.GetTypeAt(2)); - EXPECT_EQ(1337, menu.GetCommandIdAt(2)); + EXPECT_EQ(101, menu.GetCommandIdAt(2)); EXPECT_EQ(base::ASCIIToUTF16("radio"), menu.GetLabelAt(2)); EXPECT_FALSE(menu.IsEnabledAt(2)); EXPECT_TRUE(menu.IsItemCheckedAt(2)); // Invoking a custom item should execute the command id on the delegate. menu.ActivatedAt(1); - EXPECT_EQ(999, delegate.last_executed_command()); + EXPECT_EQ(107, delegate.last_executed_command()); } // Tests the prepending of a custom submenu in a shelf context menu.
diff --git a/ash/shelf/shelf_view.cc b/ash/shelf/shelf_view.cc index 6c53f29..6d08ef7 100644 --- a/ash/shelf/shelf_view.cc +++ b/ash/shelf/shelf_view.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include <memory> +#include "ash/app_list/app_list_controller_impl.h" #include "ash/drag_drop/drag_image_view.h" #include "ash/focus_cycler.h" #include "ash/keyboard/keyboard_util.h" @@ -724,6 +725,12 @@ break; } + // Record the current AppListViewState to be used later for metrics. The + // AppListViewState will change on app launch, so this will record the + // AppListViewState before the app was launched. + recorded_app_list_view_state_ = + Shell::Get()->app_list_controller()->GetAppListViewState(); + // Run AfterItemSelected directly if the item has no delegate (ie. in tests). const ShelfItem& item = model_->items()[last_pressed_index_]; if (!model_->GetShelfItemDelegate(item.id)) { @@ -2325,6 +2332,13 @@ item_awaiting_response_ = ShelfID(); shelf_button_pressed_metric_tracker_.ButtonPressed(*event, sender, action); + // Record AppList metric for any action considered an app launch. + if (action == SHELF_ACTION_NEW_WINDOW_CREATED || + action == SHELF_ACTION_WINDOW_ACTIVATED) { + Shell::Get()->app_list_controller()->RecordShelfAppLaunched( + recorded_app_list_view_state_); + } + // The app list handles its own ink drop effect state changes. if (action == SHELF_ACTION_APP_LIST_DISMISSED) { ink_drop->SnapToActivated();
diff --git a/ash/shelf/shelf_view.h b/ash/shelf/shelf_view.h index 67daa75..5eb105c 100644 --- a/ash/shelf/shelf_view.h +++ b/ash/shelf/shelf_view.h
@@ -12,6 +12,7 @@ #include "ash/app_list/views/app_list_drag_and_drop_host.h" #include "ash/public/cpp/shelf_model_observer.h" +#include "ash/public/interfaces/app_list_view.mojom.h" #include "ash/public/interfaces/shelf.mojom.h" #include "ash/shelf/ink_drop_button_listener.h" #include "ash/shelf/overflow_bubble.h" @@ -695,6 +696,11 @@ // Used to call SpeedUpDragScrolling. base::OneShotTimer speed_up_drag_scrolling_; + // The AppListViewState recorded before a button press, used to record app + // launching metrics. This allows an accurate AppListViewState to be recorded + // before AppListViewState changes. + ash::mojom::AppListViewState recorded_app_list_view_state_; + base::WeakPtrFactory<ShelfView> weak_factory_; DISALLOW_COPY_AND_ASSIGN(ShelfView);
diff --git a/ash/wm/base_state.cc b/ash/wm/base_state.cc index 8759fb2..0858c5c 100644 --- a/ash/wm/base_state.cc +++ b/ash/wm/base_state.cc
@@ -150,12 +150,16 @@ // Save the previous show state when it is not minimized so that we can // correctly restore it after exiting the minimized mode. if (!IsMinimizedWindowStateType(previous_state_type)) { - window->SetProperty( - aura::client::kPreMinimizedShowStateKey, - ToWindowShowState( - previous_state_type == mojom::WindowStateType::PIP - ? window->GetProperty(ash::kPrePipWindowStateTypeKey) - : previous_state_type)); + // We must not save PIP to |kPreMinimizedShowStateKey|. + if (previous_state_type != mojom::WindowStateType::PIP) + window->SetProperty(aura::client::kPreMinimizedShowStateKey, + ToWindowShowState(previous_state_type)); + // We must not save MINIMIZED to |kPreMinimizedShowStateKey|. + else if (window->GetProperty(ash::kPrePipWindowStateTypeKey) != + mojom::WindowStateType::MINIMIZED) + window->SetProperty(aura::client::kPreMinimizedShowStateKey, + ToWindowShowState(window->GetProperty( + ash::kPrePipWindowStateTypeKey))); } // Count minimizing a PIP window as dismissing it. Android apps in PIP mode // don't exit when they are dismissed, they just go back to being a regular
diff --git a/ash/wm/window_animations_unittest.cc b/ash/wm/window_animations_unittest.cc index 412ec96..dc5d0026 100644 --- a/ash/wm/window_animations_unittest.cc +++ b/ash/wm/window_animations_unittest.cc
@@ -335,25 +335,61 @@ window->Show(); EXPECT_TRUE(window->layer()->visible()); - EXPECT_EQ("8,8 100x100", window->layer()->GetTargetBounds().ToString()); + EXPECT_EQ(gfx::Rect(8, 8, 100, 100), window->layer()->GetTargetBounds()); window->Hide(); EXPECT_EQ(0.0f, window->layer()->GetTargetOpacity()); EXPECT_FALSE(window->layer()->GetTargetVisibility()); EXPECT_FALSE(window->layer()->visible()); - EXPECT_EQ("-142,8 100x100", window->layer()->GetTargetBounds().ToString()); + EXPECT_EQ(gfx::Rect(-142, 8, 100, 100), window->layer()->GetTargetBounds()); // Reset the position and try again. window->Show(); window->SetBounds(gfx::Rect(8, 8, 100, 100)); EXPECT_TRUE(window->layer()->visible()); - EXPECT_EQ("8,8 100x100", window->layer()->GetTargetBounds().ToString()); + EXPECT_EQ(gfx::Rect(8, 8, 100, 100), window->layer()->GetTargetBounds()); window->Hide(); EXPECT_EQ(0.0f, window->layer()->GetTargetOpacity()); EXPECT_FALSE(window->layer()->GetTargetVisibility()); EXPECT_FALSE(window->layer()->visible()); - EXPECT_EQ("-142,8 100x100", window->layer()->GetTargetBounds().ToString()); + EXPECT_EQ(gfx::Rect(-142, 8, 100, 100), window->layer()->GetTargetBounds()); +} + +TEST_F(WindowAnimationsTest, ResetAnimationAfterDismissingArcPip) { + ui::ScopedAnimationDurationScaleMode test_duration_mode( + ui::ScopedAnimationDurationScaleMode::ZERO_DURATION); + + std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0)); + window->SetBounds(gfx::Rect(8, 8, 100, 100)); + + wm::WindowState* window_state = wm::GetWindowState(window.get()); + const wm::WMEvent enter_pip(wm::WM_EVENT_PIP); + window_state->OnWMEvent(&enter_pip); + EXPECT_TRUE(window_state->IsPip()); + + window->Show(); + EXPECT_TRUE(window->layer()->visible()); + EXPECT_EQ(gfx::Rect(8, 8, 100, 100), window->layer()->GetTargetBounds()); + + // Ensure the window is slided out. + wm::GetWindowState(window.get())->Minimize(); + EXPECT_EQ(0.0f, window->layer()->GetTargetOpacity()); + EXPECT_FALSE(window->layer()->GetTargetVisibility()); + EXPECT_FALSE(window->layer()->visible()); + EXPECT_EQ(gfx::Rect(-142, 8, 100, 100), window->layer()->GetTargetBounds()); + + wm::GetWindowState(window.get())->Maximize(); + EXPECT_EQ(1.0f, window->layer()->GetTargetOpacity()); + EXPECT_TRUE(window->layer()->visible()); + EXPECT_EQ(gfx::Rect(0, 0, 800, 544), window->layer()->GetTargetBounds()); + + // Ensure the window is not slided out. + window->Hide(); + EXPECT_EQ(0.0f, window->layer()->GetTargetOpacity()); + EXPECT_FALSE(window->layer()->GetTargetVisibility()); + EXPECT_FALSE(window->layer()->visible()); + EXPECT_EQ(gfx::Rect(0, 0, 800, 544), window->layer()->GetTargetBounds()); } } // namespace ash
diff --git a/ash/wm/window_state.cc b/ash/wm/window_state.cc index 91e67a7d6..7600889 100644 --- a/ash/wm/window_state.cc +++ b/ash/wm/window_state.cc
@@ -551,7 +551,7 @@ ignore_property_change_(false), current_state_(new DefaultState(ToWindowStateType(GetShowState()))) { window_->AddObserver(this); - UpdatePipState(mojom::WindowStateType::DEFAULT); + OnPrePipStateChange(mojom::WindowStateType::DEFAULT); } bool WindowState::GetAlwaysOnTop() const { @@ -624,13 +624,24 @@ mojom::WindowStateType old_window_state_type) { for (auto& observer : observer_list_) observer.OnPreWindowStateTypeChange(this, old_window_state_type); - UpdatePipState(old_window_state_type); + OnPrePipStateChange(old_window_state_type); } void WindowState::NotifyPostStateTypeChange( mojom::WindowStateType old_window_state_type) { for (auto& observer : observer_list_) observer.OnPostWindowStateTypeChange(this, old_window_state_type); + OnPostPipStateChange(old_window_state_type); +} + +void WindowState::OnPostPipStateChange( + mojom::WindowStateType old_window_state_type) { + if (old_window_state_type == mojom::WindowStateType::PIP) { + // The animation type may be FADE_OUT_SLIDE_IN at this point, which we don't + // want it to be anymore if the window is not PIP anymore. + ::wm::SetWindowVisibilityAnimationType( + window_, ::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_DEFAULT); + } } void WindowState::SetBoundsDirect(const gfx::Rect& bounds) { @@ -709,7 +720,8 @@ CrossFadeAnimation(window_, std::move(old_layer_owner), animation_type); } -void WindowState::UpdatePipState(mojom::WindowStateType old_window_state_type) { +void WindowState::OnPrePipStateChange( + mojom::WindowStateType old_window_state_type) { auto* widget = views::Widget::GetWidgetForNativeWindow(window()); if (IsPip()) { // widget may not exit in some unit tests.
diff --git a/ash/wm/window_state.h b/ash/wm/window_state.h index cb121fc..40e4aad4 100644 --- a/ash/wm/window_state.h +++ b/ash/wm/window_state.h
@@ -423,9 +423,13 @@ const gfx::Rect& bounds, gfx::Tween::Type animation_type = gfx::Tween::EASE_OUT); - // Update PIP related state, such as next window animation type, upon - // state change. - void UpdatePipState(mojom::WindowStateType old_window_state_type); + // Called before the state change and update PIP related state, such as next + // window animation type, upon state change. + void OnPrePipStateChange(mojom::WindowStateType old_window_state_type); + + // Called after the state change and update PIP related state, such as next + // window animation type, upon state change. + void OnPostPipStateChange(mojom::WindowStateType old_window_state_type); // Update the PIP bounds if necessary. This may need to happen when the // display work area changes, or if system ui regions like the virtual
diff --git a/ash/wm/window_state_unittest.cc b/ash/wm/window_state_unittest.cc index 8d83bff..3296d6f 100644 --- a/ash/wm/window_state_unittest.cc +++ b/ash/wm/window_state_unittest.cc
@@ -673,39 +673,81 @@ EXPECT_TRUE(window_state->CanConsumeSystemKeys()); } -TEST_F(WindowStateTest, RestoreStateAfterDismissingPip) { +TEST_F(WindowStateTest, + RestoreStateAfterEnteringPipViaOcculusionAndDismissingPip) { std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0)); wm::WindowState* window_state = wm::GetWindowState(window.get()); window->Show(); EXPECT_TRUE(window->layer()->visible()); - // Ensure a maximized window gets maximized again after it enters PIP, gets - // minimized, and unminimized. + // Ensure a maximized window gets maximized again after it enters PIP via + // occlusion, gets minimized, and unminimized. window_state->Maximize(); - ASSERT_TRUE(window_state->IsMaximized()); + EXPECT_TRUE(window_state->IsMaximized()); const wm::WMEvent enter_pip(wm::WM_EVENT_PIP); window_state->OnWMEvent(&enter_pip); EXPECT_TRUE(window_state->IsPip()); window_state->Minimize(); - ASSERT_TRUE(window_state->IsMinimized()); + EXPECT_TRUE(window_state->IsMinimized()); window_state->Unminimize(); - ASSERT_TRUE(window_state->IsMaximized()); + EXPECT_TRUE(window_state->IsMaximized()); - // Ensure a freeform window gets freeform again after it enters PIP, gets - // minimized, and unminimized. + // Ensure a freeform window gets freeform again after it enters PIP via + // occulusion, gets minimized, and unminimized. ::wm::SetWindowState(window.get(), ui::SHOW_STATE_NORMAL); window_state->OnWMEvent(&enter_pip); EXPECT_TRUE(window_state->IsPip()); window_state->Minimize(); - ASSERT_TRUE(window_state->IsMinimized()); + EXPECT_TRUE(window_state->IsMinimized()); window_state->Unminimize(); - ASSERT_TRUE(window_state->GetStateType() == mojom::WindowStateType::NORMAL); + EXPECT_TRUE(window_state->GetStateType() == mojom::WindowStateType::NORMAL); +} + +TEST_F(WindowStateTest, RestoreStateAfterEnterPipViaMinimizeAndDismissingPip) { + std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithId(0)); + wm::WindowState* window_state = wm::GetWindowState(window.get()); + window->Show(); + EXPECT_TRUE(window->layer()->visible()); + + // Ensure a maximized window gets maximized again after it enters PIP via + // minimize, gets minimized, and unminimized. + window_state->Maximize(); + EXPECT_TRUE(window_state->IsMaximized()); + + window_state->Minimize(); + EXPECT_TRUE(window_state->IsMinimized()); + + const wm::WMEvent enter_pip(wm::WM_EVENT_PIP); + window_state->OnWMEvent(&enter_pip); + EXPECT_TRUE(window_state->IsPip()); + + window_state->Minimize(); + EXPECT_TRUE(window_state->IsMinimized()); + + window_state->Unminimize(); + EXPECT_TRUE(window_state->IsMaximized()); + + // Ensure a freeform window gets freeform again after it enters PIP via + // minimize, gets minimized, and unminimized. + ::wm::SetWindowState(window.get(), ui::SHOW_STATE_NORMAL); + + window_state->Minimize(); + EXPECT_TRUE(window_state->IsMinimized()); + + window_state->OnWMEvent(&enter_pip); + EXPECT_TRUE(window_state->IsPip()); + + window_state->Minimize(); + EXPECT_TRUE(window_state->IsMinimized()); + + window_state->Unminimize(); + EXPECT_TRUE(window_state->GetStateType() == mojom::WindowStateType::NORMAL); } TEST_F(WindowStateTest, SetBoundsUpdatesSizeOfPipRestoreBounds) {
diff --git a/base/BUILD.gn b/base/BUILD.gn index ccf866f..9aed800 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -757,6 +757,8 @@ "task/lazy_task_runner.h", "task/post_task.cc", "task/post_task.h", + "task/promise/dependent_list.cc", + "task/promise/dependent_list.h", "task/scoped_set_task_priority_for_current_thread.cc", "task/scoped_set_task_priority_for_current_thread.h", "task/sequence_manager/associated_thread_id.cc", @@ -2569,6 +2571,7 @@ "task/common/task_annotator_unittest.cc", "task/lazy_task_runner_unittest.cc", "task/post_task_unittest.cc", + "task/promise/dependent_list_unittest.cc", "task/scoped_set_task_priority_for_current_thread_unittest.cc", "task/sequence_manager/atomic_flag_set_unittest.cc", "task/sequence_manager/lazily_deallocated_deque_unittest.cc", @@ -3150,6 +3153,7 @@ "android/java/src/org/chromium/base/task/AsyncTask.java", "android/java/src/org/chromium/base/task/BackgroundOnlyAsyncTask.java", "android/java/src/org/chromium/base/task/DefaultTaskExecutor.java", + "android/java/src/org/chromium/base/task/ChoreographerTaskRunner.java", "android/java/src/org/chromium/base/task/ChromeThreadPoolExecutor.java", "android/java/src/org/chromium/base/task/PostTask.java", "android/java/src/org/chromium/base/task/SequencedTaskRunner.java",
diff --git a/base/android/java/src/org/chromium/base/process_launcher/BindService.java b/base/android/java/src/org/chromium/base/process_launcher/BindService.java index bde1f2f..bd1b9764 100644 --- a/base/android/java/src/org/chromium/base/process_launcher/BindService.java +++ b/base/android/java/src/org/chromium/base/process_launcher/BindService.java
@@ -15,6 +15,7 @@ import android.os.UserHandle; import java.lang.reflect.Method; +import java.util.concurrent.Executor; /** * Class of static helper methods to call Context.bindService variants. @@ -25,7 +26,7 @@ // Note that handler is not guaranteed to be used, and client still need to correctly handle // callbacks on the UI thread. static boolean doBindService(Context context, Intent intent, ServiceConnection connection, - int flags, Handler handler) { + int flags, Handler handler, Executor executor, String instanceName) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { return bindServiceByCall(context, intent, connection, flags); }
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildConnectionAllocator.java b/base/android/java/src/org/chromium/base/process_launcher/ChildConnectionAllocator.java index 43ae2591..0233c39 100644 --- a/base/android/java/src/org/chromium/base/process_launcher/ChildConnectionAllocator.java +++ b/base/android/java/src/org/chromium/base/process_launcher/ChildConnectionAllocator.java
@@ -40,12 +40,12 @@ @Override public ChildProcessConnection createConnection(Context context, ComponentName serviceName, boolean bindToCaller, boolean bindAsExternalService, Bundle serviceBundle) { - return new ChildProcessConnection( - context, serviceName, bindToCaller, bindAsExternalService, serviceBundle); + return new ChildProcessConnection(context, serviceName, bindToCaller, + bindAsExternalService, serviceBundle, null /* instanceName */); } } - // Delay between the call to freeConnection and the connection actually beeing freed. + // Delay between the call to freeConnection and the connection actually beeing freed. private static final long FREE_CONNECTION_DELAY_MILLIS = 1; // The handler of the thread on which all interations should happen. @@ -225,7 +225,7 @@ return connection; } - /** Frees a connection and notifies listeners. */ + /** Free connection allocated by this allocator. */ private void free(ChildProcessConnection connection) { assert isRunningOnLauncherThread();
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java index fe89894..06f7c82c 100644 --- a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java +++ b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java
@@ -26,6 +26,7 @@ import java.util.Arrays; import java.util.List; +import java.util.concurrent.Executor; import javax.annotation.concurrent.GuardedBy; @@ -85,8 +86,8 @@ @VisibleForTesting protected interface ChildServiceConnectionFactory { - ChildServiceConnection createConnection( - Intent bindIntent, int bindFlags, ChildServiceConnectionDelegate delegate); + ChildServiceConnection createConnection(Intent bindIntent, int bindFlags, + ChildServiceConnectionDelegate delegate, String instanceName); } /** Interface representing a connection to the Android service. Can be mocked in unit-tests. */ @@ -104,16 +105,21 @@ private final Intent mBindIntent; private final int mBindFlags; private final Handler mHandler; + private final Executor mExecutor; private final ChildServiceConnectionDelegate mDelegate; + private final String mInstanceName; private boolean mBound; private ChildServiceConnectionImpl(Context context, Intent bindIntent, int bindFlags, - Handler handler, ChildServiceConnectionDelegate delegate) { + Handler handler, Executor executor, ChildServiceConnectionDelegate delegate, + String instanceName) { mContext = context; mBindIntent = bindIntent; mBindFlags = bindFlags; mHandler = handler; + mExecutor = executor; mDelegate = delegate; + mInstanceName = instanceName; } @Override @@ -121,8 +127,8 @@ if (!mBound) { try { TraceEvent.begin("ChildProcessConnection.ChildServiceConnectionImpl.bind"); - mBound = BindService.doBindService( - mContext, mBindIntent, this, mBindFlags, mHandler); + mBound = BindService.doBindService(mContext, mBindIntent, this, mBindFlags, + mHandler, mExecutor, mInstanceName); } finally { TraceEvent.end("ChildProcessConnection.ChildServiceConnectionImpl.bind"); } @@ -171,6 +177,7 @@ } private final Handler mLauncherHandler; + private final Executor mLauncherExecutor; private final ComponentName mServiceName; // Parameters passed to the child process through the service binding intent. @@ -263,16 +270,19 @@ private boolean mCleanExit; public ChildProcessConnection(Context context, ComponentName serviceName, boolean bindToCaller, - boolean bindAsExternalService, Bundle serviceBundle) { + boolean bindAsExternalService, Bundle serviceBundle, String instanceName) { this(context, serviceName, bindToCaller, bindAsExternalService, serviceBundle, - null /* connectionFactory */); + null /* connectionFactory */, instanceName); } @VisibleForTesting public ChildProcessConnection(final Context context, ComponentName serviceName, boolean bindToCaller, boolean bindAsExternalService, Bundle serviceBundle, - ChildServiceConnectionFactory connectionFactory) { + ChildServiceConnectionFactory connectionFactory, String instanceName) { mLauncherHandler = new Handler(); + mLauncherExecutor = (Runnable runnable) -> { + mLauncherHandler.post(runnable); + }; assert isRunningOnLauncherThread(); mServiceName = serviceName; mServiceBundle = serviceBundle != null ? serviceBundle : new Bundle(); @@ -282,10 +292,10 @@ if (connectionFactory == null) { connectionFactory = new ChildServiceConnectionFactory() { @Override - public ChildServiceConnection createConnection( - Intent bindIntent, int bindFlags, ChildServiceConnectionDelegate delegate) { - return new ChildServiceConnectionImpl( - context, bindIntent, bindFlags, mLauncherHandler, delegate); + public ChildServiceConnection createConnection(Intent bindIntent, int bindFlags, + ChildServiceConnectionDelegate delegate, String instanceName) { + return new ChildServiceConnectionImpl(context, bindIntent, bindFlags, + mLauncherHandler, mLauncherExecutor, delegate, instanceName); } }; } @@ -321,11 +331,12 @@ int defaultFlags = Context.BIND_AUTO_CREATE | (bindAsExternalService ? Context.BIND_EXTERNAL_SERVICE : 0); - mModerateBinding = connectionFactory.createConnection(intent, defaultFlags, delegate); + mModerateBinding = + connectionFactory.createConnection(intent, defaultFlags, delegate, instanceName); mStrongBinding = connectionFactory.createConnection( - intent, defaultFlags | Context.BIND_IMPORTANT, delegate); + intent, defaultFlags | Context.BIND_IMPORTANT, delegate, instanceName); mWaivedBinding = connectionFactory.createConnection( - intent, defaultFlags | Context.BIND_WAIVE_PRIORITY, delegate); + intent, defaultFlags | Context.BIND_WAIVE_PRIORITY, delegate, instanceName); } public final IChildProcessService getService() {
diff --git a/base/android/java/src/org/chromium/base/task/ChoreographerTaskRunner.java b/base/android/java/src/org/chromium/base/task/ChoreographerTaskRunner.java new file mode 100644 index 0000000..d44ef4e --- /dev/null +++ b/base/android/java/src/org/chromium/base/task/ChoreographerTaskRunner.java
@@ -0,0 +1,63 @@ +// 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. + +package org.chromium.base.task; + +import android.view.Choreographer; + +/** + * An adapter that allows PostTask to submit Choreographer frame callbacks which + * run after the next vsync. + */ +final class ChoreographerTaskRunner implements SingleThreadTaskRunner { + private final Choreographer mChoreographer; + + ChoreographerTaskRunner(Choreographer choreographer) { + mChoreographer = choreographer; + } + + @Override + public boolean belongsToCurrentThread() { + try { + return mChoreographer == Choreographer.getInstance(); + } catch (IllegalStateException e) { + return false; + } + } + + @Override + public void postTask(Runnable task) { + mChoreographer.postFrameCallback(new Choreographer.FrameCallback() { + @Override + public void doFrame(long frameTimeNanos) { + task.run(); + } + }); + } + + @Override + public void destroy() { + // NOP + } + + @Override + public void disableLifetimeCheck() { + // NOP + } + + @Override + public void postDelayedTask(Runnable task, long delayMillis) { + mChoreographer.postFrameCallbackDelayed(new Choreographer.FrameCallback() { + @Override + public void doFrame(long frameTimeNanos) { + task.run(); + } + }, delayMillis); + } + + @Override + public void initNativeTaskRunner() { + // NOP + } +}
diff --git a/base/android/java/src/org/chromium/base/task/DefaultTaskExecutor.java b/base/android/java/src/org/chromium/base/task/DefaultTaskExecutor.java index 0613e38..9952c42 100644 --- a/base/android/java/src/org/chromium/base/task/DefaultTaskExecutor.java +++ b/base/android/java/src/org/chromium/base/task/DefaultTaskExecutor.java
@@ -4,6 +4,10 @@ package org.chromium.base.task; +import android.view.Choreographer; + +import org.chromium.base.ThreadUtils; + import java.util.HashMap; import java.util.Map; @@ -11,15 +15,18 @@ * The default {@link TaskExecutor} which maps directly to base::ThreadPool. */ class DefaultTaskExecutor implements TaskExecutor { - Map<TaskTraits, TaskRunner> mTraitsToRunnerMap = new HashMap<>(); + private final Map<TaskTraits, TaskRunner> mTraitsToRunnerMap = new HashMap<>(); + private ChoreographerTaskRunner mChoreographerTaskRunner; @Override public TaskRunner createTaskRunner(TaskTraits taskTraits) { + if (taskTraits.mIsChoreographerFrame) return getChoreographerTaskRunner(); return new TaskRunnerImpl(taskTraits); } @Override public SequencedTaskRunner createSequencedTaskRunner(TaskTraits taskTraits) { + if (taskTraits.mIsChoreographerFrame) return getChoreographerTaskRunner(); return new SequencedTaskRunnerImpl(taskTraits); } @@ -29,12 +36,13 @@ */ @Override public SingleThreadTaskRunner createSingleThreadTaskRunner(TaskTraits taskTraits) { + if (taskTraits.mIsChoreographerFrame) return getChoreographerTaskRunner(); // Tasks posted via this API will not execute until after native has started. return new SingleThreadTaskRunnerImpl(null, taskTraits); } @Override - public void postDelayedTask(TaskTraits taskTraits, Runnable task, long delay) { + public synchronized void postDelayedTask(TaskTraits taskTraits, Runnable task, long delay) { if (taskTraits.hasExtension()) { TaskRunner runner = createTaskRunner(taskTraits); runner.postDelayedTask(task, delay); @@ -57,4 +65,14 @@ public boolean canRunTaskImmediately(TaskTraits traits) { return false; } + + private synchronized ChoreographerTaskRunner getChoreographerTaskRunner() { + // TODO(alexclarke): Migrate to the new Android UI thread trait when available. + ChoreographerTaskRunner choreographerTaskRunner = + ThreadUtils.runOnUiThreadBlockingNoException( + () -> { return new ChoreographerTaskRunner(Choreographer.getInstance()); }); + + mTraitsToRunnerMap.put(TaskTraits.CHOREOGRAPHER_FRAME, choreographerTaskRunner); + return choreographerTaskRunner; + } }
diff --git a/base/android/java/src/org/chromium/base/task/TaskTraits.java b/base/android/java/src/org/chromium/base/task/TaskTraits.java index 4b91a323..0633fc78 100644 --- a/base/android/java/src/org/chromium/base/task/TaskTraits.java +++ b/base/android/java/src/org/chromium/base/task/TaskTraits.java
@@ -54,6 +54,11 @@ public static final TaskTraits USER_BLOCKING = new TaskTraits().taskPriority(TaskPriority.USER_BLOCKING); + // A bit like requestAnimationFrame, this task will be posted onto the Choreographer + // and will be run on the android main thread after the next vsync. + public static final TaskTraits CHOREOGRAPHER_FRAME = + new TaskTraits().setIsChoreographerFrame(true); + public TaskTraits() {} private TaskTraits(TaskTraits other) { @@ -89,6 +94,11 @@ return taskTraits; } + private TaskTraits setIsChoreographerFrame(boolean isChoreographerFrame) { + mIsChoreographerFrame = isChoreographerFrame; + return this; + } + // For convenience of the JNI code, we use primitive types only. // Note shutdown behavior is not supported on android. boolean mPrioritySetExplicitly; @@ -96,6 +106,7 @@ boolean mMayBlock; byte mExtensionId = INVALID_EXTENSION_ID; byte mExtensionData[]; + boolean mIsChoreographerFrame; /** * @return true if this task is using some TaskTraits extension. @@ -152,6 +163,7 @@ hash = 37 * hash + (mMayBlock ? 0 : 1); hash = 37 * hash + (int) mExtensionId; hash = 37 * hash + Arrays.hashCode(mExtensionData); + hash = 37 * hash + (mIsChoreographerFrame ? 0 : 1); return hash; } }
diff --git a/base/android/javatests/src/org/chromium/base/task/PostTaskTest.java b/base/android/javatests/src/org/chromium/base/task/PostTaskTest.java index 022013b..c7ad98c 100644 --- a/base/android/javatests/src/org/chromium/base/task/PostTaskTest.java +++ b/base/android/javatests/src/org/chromium/base/task/PostTaskTest.java
@@ -18,6 +18,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; /** @@ -95,4 +96,34 @@ taskQueue.destroy(); } } + + @Test + @SmallTest + public void testChoreographerFrameTrait() throws Exception { + List<Integer> orderList = new ArrayList<>(); + CountDownLatch latch = new CountDownLatch(2); + PostTask.postTask(TaskTraits.CHOREOGRAPHER_FRAME, new Runnable() { + @Override + public void run() { + synchronized (orderList) { + orderList.add(1); + latch.countDown(); + } + } + }); + + PostTask.postTask(TaskTraits.CHOREOGRAPHER_FRAME, new Runnable() { + @Override + public void run() { + synchronized (orderList) { + orderList.add(2); + latch.countDown(); + } + } + }); + + latch.await(); + + assertThat(orderList, contains(1, 2)); + } }
diff --git a/base/android/junit/src/org/chromium/base/process_launcher/ChildProcessConnectionTest.java b/base/android/junit/src/org/chromium/base/process_launcher/ChildProcessConnectionTest.java index 85ef7018..f5cf7df 100644 --- a/base/android/junit/src/org/chromium/base/process_launcher/ChildProcessConnectionTest.java +++ b/base/android/junit/src/org/chromium/base/process_launcher/ChildProcessConnectionTest.java
@@ -92,7 +92,8 @@ @Override public ChildProcessConnection.ChildServiceConnection createConnection( Intent bindIntent, int bindFlags, - ChildProcessConnection.ChildServiceConnectionDelegate delegate) { + ChildProcessConnection.ChildServiceConnectionDelegate delegate, + String instanceName) { ChildServiceConnectionMock connection = spy(new ChildServiceConnectionMock(bindIntent, delegate)); if (mFirstServiceConnection == null) { @@ -154,7 +155,7 @@ String serviceName = "TestService"; return new ChildProcessConnection(null /* context */, new ComponentName(packageName, serviceName), bindToCaller, bindAsExternalService, - serviceBundle, mServiceConnectionFactory); + serviceBundle, mServiceConnectionFactory, null /* instanceName */); } @Test
diff --git a/base/task/common/task_annotator.cc b/base/task/common/task_annotator.cc index 5b74def..76294de 100644 --- a/base/task/common/task_annotator.cc +++ b/base/task/common/task_annotator.cc
@@ -78,11 +78,6 @@ TRACE_DISABLED_BY_DEFAULT("toplevel.flow"), trace_event_name, TRACE_ID_MANGLE(GetTaskTraceID(*pending_task)), TRACE_EVENT_FLAG_FLOW_IN); - // Trace-parsing tools (DevTools, Lighthouse, etc) consume this event - // to determine long tasks. - // See https://crbug.com/681863 and https://crbug.com/874982 - TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "RunTask"); - // Before running the task, store the task backtrace with the chain of // PostTasks that resulted in this call and deliberately alias it to ensure // it is on the stack if the task crashes. Be careful not to assume that the
diff --git a/base/task/promise/dependent_list.cc b/base/task/promise/dependent_list.cc new file mode 100644 index 0000000..cfe0b7d4 --- /dev/null +++ b/base/task/promise/dependent_list.cc
@@ -0,0 +1,103 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/task/promise/dependent_list.h" + +namespace base { +namespace internal { + +DependentList::DependentList(ConstructUnresolved) : head_(0) {} + +DependentList::DependentList(ConstructResolved) : head_(kResolvedSentinel) {} + +DependentList::DependentList(ConstructRejected) : head_(kRejectedSentinel) {} + +DependentList::~DependentList() = default; + +DependentList::Node::Node() = default; + +DependentList::InsertResult DependentList::Insert(Node* node) { + // This method uses std::memory_order_acquire semantics on read (the failure + // case of compare_exchange_weak() below is a read) to ensure setting + // |node->next| happens-after all memory modifications applied to |prev_head| + // before it became |head_|. Conversely it uses std::memory_order_release + // semantics on write to ensure that all memory modifications applied to + // |node| happened-before it becomes |head_|. + DCHECK(!node->next); + uintptr_t prev_head = head_.load(std::memory_order_acquire); + do { + if (prev_head == kResolvedSentinel) { + node->next = 0; + return InsertResult::FAIL_PROMISE_RESOLVED; + } + + if (prev_head == kRejectedSentinel) { + node->next = 0; + return InsertResult::FAIL_PROMISE_REJECTED; + } + + if (prev_head == kCanceledSentinel) { + node->next = 0; + return InsertResult::FAIL_PROMISE_CANCELED; + } + + node->next = reinterpret_cast<Node*>(prev_head); + } while (!head_.compare_exchange_weak( + prev_head, reinterpret_cast<uintptr_t>(node), std::memory_order_release, + std::memory_order_acquire)); + return InsertResult::SUCCESS; +} + +DependentList::Node* DependentList::ConsumeOnceForResolve() { + // The Consume*() methods require std::memory_order_acq_rel semantics because: + // * Need release semantics to ensure that future calls to Insert() (which + // will fail) happen-after memory modifications performed prior to this + // Consume*(). + // * Need acquire semantics to synchronize with the last Insert() and ensure + // all memory modifications applied to |head_| before the last Insert() + // happen-before this Consume*(). + uintptr_t prev_head = std::atomic_exchange_explicit( + &head_, kResolvedSentinel, std::memory_order_acq_rel); + DCHECK_NE(prev_head, kResolvedSentinel); + DCHECK_NE(prev_head, kRejectedSentinel); + DCHECK_NE(prev_head, kCanceledSentinel); + return reinterpret_cast<Node*>(prev_head); +} + +DependentList::Node* DependentList::ConsumeOnceForReject() { + uintptr_t prev_head = std::atomic_exchange_explicit( + &head_, kRejectedSentinel, std::memory_order_acq_rel); + DCHECK_NE(prev_head, kResolvedSentinel); + DCHECK_NE(prev_head, kRejectedSentinel); + DCHECK_NE(prev_head, kCanceledSentinel); + return reinterpret_cast<Node*>(prev_head); +} + +DependentList::Node* DependentList::ConsumeOnceForCancel() { + uintptr_t prev_head = std::atomic_exchange_explicit( + &head_, kCanceledSentinel, std::memory_order_acq_rel); + DCHECK_NE(prev_head, kResolvedSentinel); + DCHECK_NE(prev_head, kRejectedSentinel); + DCHECK_NE(prev_head, kCanceledSentinel); + return reinterpret_cast<Node*>(prev_head); +} + +bool DependentList::IsResolved() const { + return head_.load(std::memory_order_acquire) == kResolvedSentinel; +} + +bool DependentList::IsRejected() const { + return head_.load(std::memory_order_acquire) == kRejectedSentinel; +} + +bool DependentList::IsCancelled() const { + return head_.load(std::memory_order_acquire) == kCanceledSentinel; +} + +constexpr uintptr_t DependentList::kResolvedSentinel; +constexpr uintptr_t DependentList::kRejectedSentinel; +constexpr uintptr_t DependentList::kCanceledSentinel; + +} // namespace internal +} // namespace base
diff --git a/base/task/promise/dependent_list.h b/base/task/promise/dependent_list.h new file mode 100644 index 0000000..02ab141 --- /dev/null +++ b/base/task/promise/dependent_list.h
@@ -0,0 +1,83 @@ +// Copyright 2019 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 BASE_TASK_PROMISE_DEPENDENT_LIST_H_ +#define BASE_TASK_PROMISE_DEPENDENT_LIST_H_ + +#include <atomic> + +#include "base/base_export.h" +#include "base/logging.h" +#include "base/macros.h" + +namespace base { +namespace internal { + +class AbstractPromise; + +// AbstractPromise needs to know which promises depend upon it. This lock free +// class stores the list of dependents. This is not a general purpose list +// because the data can only be consumed once. This class' methods have implicit +// acquire/release semantics (i.e., callers can assume the result they get +// happens-after memory changes which lead to it). +class BASE_EXPORT DependentList { + public: + struct ConstructUnresolved {}; + struct ConstructResolved {}; + struct ConstructRejected {}; + + explicit DependentList(ConstructUnresolved); + explicit DependentList(ConstructResolved); + explicit DependentList(ConstructRejected); + ~DependentList(); + + enum class InsertResult { + SUCCESS, + FAIL_PROMISE_RESOLVED, + FAIL_PROMISE_REJECTED, + FAIL_PROMISE_CANCELED, + }; + + struct BASE_EXPORT Node { + Node(); + + // TODO(alexclarke): Make this a scoped_refptr. + AbstractPromise* dependent; + std::atomic<Node*> next{nullptr}; + }; + + // Insert will only succeed if one of the Consume operations hasn't been + // called yet. |node| must outlive DependentList, and it can't be altered + // after Insert or the release barrier will be ineffective. + InsertResult Insert(Node* node); + + // A ConsumeXXX function may only be called once. + Node* ConsumeOnceForResolve(); + + // A ConsumeXXX function may only be called once. + Node* ConsumeOnceForReject(); + + // A ConsumeXXX function may only be called once. + Node* ConsumeOnceForCancel(); + + bool IsResolved() const; + bool IsRejected() const; + bool IsCancelled() const; + + private: + std::atomic<uintptr_t> head_; + + // Special values for |head_| which correspond to various states. If |head_| + // contains one of these then Insert() will fail. + static constexpr uintptr_t kResolvedSentinel = 1; + static constexpr uintptr_t kRejectedSentinel = 2; + static constexpr uintptr_t kCanceledSentinel = 3; + + DISALLOW_COPY_AND_ASSIGN(DependentList); +}; + +} // namespace internal +} // namespace base + +#endif // BASE_TASK_PROMISE_DEPENDENT_LIST_H_
diff --git a/base/task/promise/dependent_list_unittest.cc b/base/task/promise/dependent_list_unittest.cc new file mode 100644 index 0000000..9df62a29 --- /dev/null +++ b/base/task/promise/dependent_list_unittest.cc
@@ -0,0 +1,119 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/task/promise/dependent_list.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { +namespace internal { + +TEST(DependentList, ConstructUnresolved) { + DependentList list(DependentList::ConstructUnresolved{}); + DependentList::Node node; + EXPECT_EQ(DependentList::InsertResult::SUCCESS, list.Insert(&node)); + EXPECT_FALSE(list.IsRejected()); + EXPECT_FALSE(list.IsCancelled()); + EXPECT_FALSE(list.IsResolved()); +} + +TEST(DependentList, ConstructResolved) { + DependentList list(DependentList::ConstructResolved{}); + DependentList::Node node; + EXPECT_EQ(DependentList::InsertResult::FAIL_PROMISE_RESOLVED, + list.Insert(&node)); + EXPECT_TRUE(list.IsResolved()); + EXPECT_FALSE(list.IsRejected()); + EXPECT_FALSE(list.IsCancelled()); +} + +TEST(DependentList, ConstructRejected) { + DependentList list(DependentList::ConstructRejected{}); + DependentList::Node node; + EXPECT_EQ(DependentList::InsertResult::FAIL_PROMISE_REJECTED, + list.Insert(&node)); + EXPECT_TRUE(list.IsRejected()); + EXPECT_FALSE(list.IsCancelled()); + EXPECT_FALSE(list.IsResolved()); +} + +TEST(DependentList, ConsumeOnceForResolve) { + DependentList list(DependentList::ConstructUnresolved{}); + DependentList::Node node1; + DependentList::Node node2; + DependentList::Node node3; + EXPECT_EQ(DependentList::InsertResult::SUCCESS, list.Insert(&node1)); + EXPECT_EQ(DependentList::InsertResult::SUCCESS, list.Insert(&node2)); + EXPECT_EQ(DependentList::InsertResult::SUCCESS, list.Insert(&node3)); + + EXPECT_FALSE(list.IsResolved()); + DependentList::Node* result = list.ConsumeOnceForResolve(); + EXPECT_TRUE(list.IsResolved()); + EXPECT_FALSE(list.IsRejected()); + EXPECT_FALSE(list.IsCancelled()); + + EXPECT_EQ(&node3, result); + EXPECT_EQ(&node2, result->next.load()); + EXPECT_EQ(&node1, result->next.load()->next.load()); + EXPECT_EQ(nullptr, result->next.load()->next.load()->next.load()); + + // Can't insert any more nodes. + DependentList::Node node4; + EXPECT_EQ(DependentList::InsertResult::FAIL_PROMISE_RESOLVED, + list.Insert(&node4)); +} + +TEST(DependentList, ConsumeOnceForReject) { + DependentList list(DependentList::ConstructUnresolved{}); + DependentList::Node node1; + DependentList::Node node2; + DependentList::Node node3; + EXPECT_EQ(DependentList::InsertResult::SUCCESS, list.Insert(&node1)); + EXPECT_EQ(DependentList::InsertResult::SUCCESS, list.Insert(&node2)); + EXPECT_EQ(DependentList::InsertResult::SUCCESS, list.Insert(&node3)); + + EXPECT_FALSE(list.IsRejected()); + DependentList::Node* result = list.ConsumeOnceForReject(); + EXPECT_TRUE(list.IsRejected()); + EXPECT_FALSE(list.IsResolved()); + EXPECT_FALSE(list.IsCancelled()); + + EXPECT_EQ(&node3, result); + EXPECT_EQ(&node2, result->next.load()); + EXPECT_EQ(&node1, result->next.load()->next.load()); + EXPECT_EQ(nullptr, result->next.load()->next.load()->next.load()); + + // Can't insert any more nodes. + DependentList::Node node4; + EXPECT_EQ(DependentList::InsertResult::FAIL_PROMISE_REJECTED, + list.Insert(&node4)); +} + +TEST(DependentList, ConsumeOnceForCancel) { + DependentList list(DependentList::ConstructUnresolved{}); + DependentList::Node node1; + DependentList::Node node2; + DependentList::Node node3; + EXPECT_EQ(DependentList::InsertResult::SUCCESS, list.Insert(&node1)); + EXPECT_EQ(DependentList::InsertResult::SUCCESS, list.Insert(&node2)); + EXPECT_EQ(DependentList::InsertResult::SUCCESS, list.Insert(&node3)); + + EXPECT_FALSE(list.IsCancelled()); + DependentList::Node* result = list.ConsumeOnceForCancel(); + EXPECT_TRUE(list.IsCancelled()); + EXPECT_FALSE(list.IsResolved()); + EXPECT_FALSE(list.IsRejected()); + + EXPECT_EQ(&node3, result); + EXPECT_EQ(&node2, result->next.load()); + EXPECT_EQ(&node1, result->next.load()->next.load()); + EXPECT_EQ(nullptr, result->next.load()->next.load()->next.load()); + + // Can't insert any more nodes. + DependentList::Node node4; + EXPECT_EQ(DependentList::InsertResult::FAIL_PROMISE_CANCELED, + list.Insert(&node4)); +} + +} // namespace internal +} // namespace base
diff --git a/base/task/sequence_manager/task_queue.h b/base/task/sequence_manager/task_queue.h index e9dbcbe..e90891c3 100644 --- a/base/task/sequence_manager/task_queue.h +++ b/base/task/sequence_manager/task_queue.h
@@ -208,6 +208,8 @@ // created on. void SetVoteToEnable(bool enabled); + bool IsVotingToEnable() const { return enabled_; } + private: friend class TaskQueue; explicit QueueEnabledVoter(scoped_refptr<TaskQueue> task_queue);
diff --git a/base/task/sequence_manager/thread_controller_impl.cc b/base/task/sequence_manager/thread_controller_impl.cc index aba6306..d8754f4 100644 --- a/base/task/sequence_manager/thread_controller_impl.cc +++ b/base/task/sequence_manager/thread_controller_impl.cc
@@ -182,6 +182,12 @@ // Trace events should finish before we call DidRunTask to ensure that // SequenceManager trace events do not interfere with them. TRACE_TASK_EXECUTION("ThreadControllerImpl::RunTask", *task); + + // Trace-parsing tools (DevTools, Lighthouse, etc) consume this event + // to determine long tasks. + // See https://crbug.com/681863 and https://crbug.com/874982 + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "RunTask"); + task_annotator_.RunTask("SequenceManager RunTask", &*task); }
diff --git a/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc b/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc index e748957..cb4369f5 100644 --- a/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc +++ b/base/task/sequence_manager/thread_controller_with_message_pump_impl.cc
@@ -349,6 +349,11 @@ work_id_provider_->IncrementWorkId(); + // Trace-parsing tools (DevTools, Lighthouse, etc) consume this event + // to determine long tasks. + // See https://crbug.com/681863 and https://crbug.com/874982 + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "RunTask"); + { // Trace events should finish before we call DidRunTask to ensure that // SequenceManager trace events do not interfere with them.
diff --git a/base/task/thread_pool/platform_native_worker_pool_win.cc b/base/task/thread_pool/platform_native_worker_pool_win.cc index 5771063..9b16a5e5 100644 --- a/base/task/thread_pool/platform_native_worker_pool_win.cc +++ b/base/task/thread_pool/platform_native_worker_pool_win.cc
@@ -4,26 +4,13 @@ #include "base/task/thread_pool/platform_native_worker_pool_win.h" -#include "base/no_destructor.h" +#include "base/optional.h" #include "base/task/thread_pool/task_tracker.h" -#include "base/threading/thread_local.h" #include "base/win/scoped_com_initializer.h" namespace base { namespace internal { -namespace { - -// Used to enable COM MTA when creating threads via the Windows Thread Pool API. -ThreadLocalOwnedPointer<win::ScopedCOMInitializer>& -ScopedCOMInitializerForCurrentThread() { - static base::NoDestructor<ThreadLocalOwnedPointer<win::ScopedCOMInitializer>> - scoped_com_initializer; - return *scoped_com_initializer; -} - -} // namespace - PlatformNativeWorkerPoolWin::PlatformNativeWorkerPoolWin( TrackedRef<TaskTracker> task_tracker, TrackedRef<Delegate> delegate, @@ -69,20 +56,12 @@ auto* worker_pool = static_cast<PlatformNativeWorkerPoolWin*>( scheduler_worker_pool_windows_impl); - if (worker_pool->worker_environment_ == WorkerEnvironment::COM_MTA) { - if (!ScopedCOMInitializerForCurrentThread().Get()) { - ScopedCOMInitializerForCurrentThread().Set( - std::make_unique<win::ScopedCOMInitializer>( - win::ScopedCOMInitializer::kMTA)); - } - } else if (worker_pool->worker_environment_ == WorkerEnvironment::NONE) { - // Upon destruction, a PTP_POOL object might not destroy the threads it - // created, and another PTP_POOL object created in the same process might - // reuse the old threads. Consequently, it is possible to be on a COM - // initialized thread even if |worker_environment_| is NONE. In this case, - // COM is uninitialized by explicitly resetting the ScopedCOMInitializer. - ScopedCOMInitializerForCurrentThread().Set(nullptr); - } + // Windows Thread Pool API best practices state that all resources created + // in the callback function should be cleaned up before returning from the + // function. This includes COM initialization. + Optional<win::ScopedCOMInitializer> com_initializer; + if (worker_pool->worker_environment_ == WorkerEnvironment::COM_MTA) + com_initializer.emplace(win::ScopedCOMInitializer::kMTA); worker_pool->RunNextSequenceImpl(); }
diff --git a/base/test/android/javatests/src/org/chromium/base/test/TestChildProcessConnection.java b/base/test/android/javatests/src/org/chromium/base/test/TestChildProcessConnection.java index ae91b44..9f58a83 100644 --- a/base/test/android/javatests/src/org/chromium/base/test/TestChildProcessConnection.java +++ b/base/test/android/javatests/src/org/chromium/base/test/TestChildProcessConnection.java
@@ -43,14 +43,14 @@ */ public TestChildProcessConnection(ComponentName serviceName, boolean bindToCaller, boolean bindAsExternalService, Bundle serviceBundle) { - super(null /* context */, serviceName, bindToCaller, bindAsExternalService, serviceBundle, - new ChildServiceConnectionFactory() { + super(null /* context */, serviceName, bindToCaller, bindAsExternalService, + serviceBundle, new ChildServiceConnectionFactory() { @Override public ChildServiceConnection createConnection(Intent bindIntent, int bindFlags, - ChildServiceConnectionDelegate delegate) { + ChildServiceConnectionDelegate delegate, String instanceName) { return new MockChildServiceConnection(); } - }); + }, null /* instanceName */); } public void setPid(int pid) {
diff --git a/base/test/values_test_util.cc b/base/test/values_test_util.cc index 007e6f6..5016d569 100644 --- a/base/test/values_test_util.cc +++ b/base/test/values_test_util.cc
@@ -8,6 +8,7 @@ #include <utility> #include "base/json/json_reader.h" +#include "base/json/json_writer.h" #include "base/memory/ptr_util.h" #include "base/strings/string_number_conversions.h" #include "testing/gtest/include/gtest/gtest.h" @@ -61,6 +62,132 @@ namespace test { +namespace { + +std::string FormatAsJSON(const base::Value& value) { + std::string json; + JSONWriter::Write(value, &json); + return json; +} + +class DictionaryHasValueMatcher + : public testing::MatcherInterface<const base::Value&> { + public: + DictionaryHasValueMatcher(const std::string& key, + const base::Value& expected_value) + : key_(key), expected_value_(expected_value.Clone()) {} + + ~DictionaryHasValueMatcher() = default; + + bool MatchAndExplain(const base::Value& value, + testing::MatchResultListener* listener) const override { + if (!value.is_dict()) { + *listener << "The value '" << FormatAsJSON(value) + << "' is not a dictionary"; + return false; + } + const base::Value* sub_value = value.FindKey(key_); + if (!sub_value) { + *listener << "Dictionary '" << FormatAsJSON(value) + << "' does not have key '" << key_ << "'"; + return false; + } + if (*sub_value != expected_value_) { + *listener << "Dictionary value under key '" << key_ << "' is '" + << FormatAsJSON(*sub_value) << "', expected '" + << FormatAsJSON(expected_value_) << "'"; + return false; + } + return true; + } + + void DescribeTo(std::ostream* os) const override { + *os << "has key '" << key_ << "' with value '" + << FormatAsJSON(expected_value_) << "'"; + } + + void DescribeNegationTo(std::ostream* os) const override { + *os << "does not have key '" << key_ << "' with value '" + << FormatAsJSON(expected_value_) << "'"; + } + + private: + DictionaryHasValueMatcher& operator=(const DictionaryHasValueMatcher& other) = + delete; + + const std::string key_; + const base::Value expected_value_; +}; + +class DictionaryHasValuesMatcher + : public testing::MatcherInterface<const base::Value&> { + public: + DictionaryHasValuesMatcher(const base::Value& template_value) + : template_value_(template_value.Clone()) { + CHECK(template_value.is_dict()); + } + + ~DictionaryHasValuesMatcher() = default; + + bool MatchAndExplain(const base::Value& value, + testing::MatchResultListener* listener) const override { + if (!value.is_dict()) { + *listener << "The value '" << FormatAsJSON(value) + << "' is not a dictionary"; + return false; + } + + bool ok = true; + for (const auto& template_dict_item : template_value_.DictItems()) { + const base::Value* sub_value = value.FindKey(template_dict_item.first); + if (!sub_value) { + *listener << "\nDictionary does not have key '" + << template_dict_item.first << "'"; + ok = false; + continue; + } + if (*sub_value != template_dict_item.second) { + *listener << "\nDictionary value under key '" + << template_dict_item.first << "' is '" + << FormatAsJSON(*sub_value) << "', expected '" + << FormatAsJSON(template_dict_item.second) << "'"; + ok = false; + } + } + return ok; + } + + void DescribeTo(std::ostream* os) const override { + *os << "contains all key-values from '" << FormatAsJSON(template_value_) + << "'"; + } + + void DescribeNegationTo(std::ostream* os) const override { + *os << "does not contain key-values from '" << FormatAsJSON(template_value_) + << "'"; + } + + private: + DictionaryHasValueMatcher& operator=(const DictionaryHasValueMatcher& other) = + delete; + + const base::Value template_value_; +}; + +} // namespace + +testing::Matcher<const base::Value&> DictionaryHasValue( + const std::string& key, + const base::Value& expected_value) { + return testing::MakeMatcher( + new DictionaryHasValueMatcher(key, expected_value)); +} + +testing::Matcher<const base::Value&> DictionaryHasValues( + const base::Value& template_value) { + return testing::MakeMatcher(new DictionaryHasValuesMatcher(template_value)); +} + IsJsonMatcher::IsJsonMatcher(base::StringPiece json) : expected_value_(test::ParseJson(json)) {}
diff --git a/base/test/values_test_util.h b/base/test/values_test_util.h index c7d5509..7f48bfd3 100644 --- a/base/test/values_test_util.h +++ b/base/test/values_test_util.h
@@ -42,6 +42,17 @@ namespace test { +// A custom GMock matcher which matches if a base::Value is a dictionary which +// has a key |key| that is equal to |value|. +testing::Matcher<const base::Value&> DictionaryHasValue( + const std::string& key, + const base::Value& expected_value); + +// A custom GMock matcher which matches if a base::Value is a dictionary which +// contains all key/value pairs from |template_value|. +testing::Matcher<const base::Value&> DictionaryHasValues( + const base::Value& template_value); + // A custom GMock matcher. For details, see // https://github.com/google/googletest/blob/644319b9f06f6ca9bf69fe791be399061044bc3d/googlemock/docs/CookBook.md#writing-new-polymorphic-matchers class IsJsonMatcher {
diff --git a/build/android/gyp/create_app_bundle.py b/build/android/gyp/create_app_bundle.py index 9666feb3..b7b5106f 100755 --- a/build/android/gyp/create_app_bundle.py +++ b/build/android/gyp/create_app_bundle.py
@@ -25,11 +25,11 @@ # Location of language-based assets in bundle modules. _LOCALES_SUBDIR = 'assets/locales/' -# The fallback locale should always have its .pak file included in +# The fallback language should always have its .pak files included in # the base apk, i.e. not use language-based asset targetting. This ensures # that Chrome won't crash on startup if its bundle is installed on a device # with an unsupported system locale (e.g. fur-rIT). -_FALLBACK_LOCALE = 'en-US' +_FALLBACK_LANGUAGE = 'en' # List of split dimensions recognized by this tool. _ALL_SPLIT_DIMENSIONS = [ 'ABI', 'SCREEN_DENSITY', 'LANGUAGE' ] @@ -178,9 +178,6 @@ # Whether other .so files are compressed is controlled by # "uncompressNativeLibraries". uncompressed_globs = ['lib/*/crazy.*'] - # Locale-specific pak files stored in bundle splits need not be compressed. - uncompressed_globs.extend( - ['assets/locales#lang_*/*.pak', 'assets/fallback-locales/*.pak']) uncompressed_globs.extend('assets/' + x for x in uncompressed_assets) # NOTE: Use '**' instead of '*' to work through directories! uncompressed_globs.extend('**.' + ext for ext in _UNCOMPRESSED_FILE_EXTS) @@ -230,8 +227,8 @@ else: android_language = android_locale - if locale == _FALLBACK_LOCALE: - # Fallback locale .pak files must be placed in a different directory + if android_language == _FALLBACK_LANGUAGE: + # Fallback language .pak files must be placed in a different directory # to ensure they are always stored in the base module. result_path = 'assets/fallback-locales/%s.pak' % locale else:
diff --git a/build/chromeos/create_test_runner_script.py b/build/chromeos/create_test_runner_script.py index 0cbe38ba..161b9a71 100755 --- a/build/chromeos/create_test_runner_script.py +++ b/build/chromeos/create_test_runner_script.py
@@ -63,13 +63,7 @@ run_test_path = RelativizePathToScript( os.path.join(os.path.dirname(__file__), 'test_runner.py')) - vm_test_args = [ - '--board', args.board, - '-v', - ] - if args.use_vm: - vm_test_args += ['--use-vm'] - + vm_test_args = [] if args.test_exe: vm_test_args.extend([ 'vm-test', @@ -95,6 +89,13 @@ if args.deploy_chrome: vm_test_args.append('--deploy-chrome') + vm_test_args += [ + '--board', args.board, + '-v', + ] + if args.use_vm: + vm_test_args += ['--use-vm'] + vm_test_path_args = [ ('--cros-cache', RelativizePathToScript(args.cros_cache)), ]
diff --git a/build/chromeos/test_runner.py b/build/chromeos/test_runner.py index 6b26cb1..e3581fb5 100755 --- a/build/chromeos/test_runner.py +++ b/build/chromeos/test_runner.py
@@ -679,45 +679,46 @@ return env -def add_common_args(parser): - parser.add_argument( - '--cros-cache', type=str, default=DEFAULT_CROS_CACHE, - help='Path to cros cache.') - parser.add_argument( - '--path-to-outdir', type=str, required=True, - help='Path to output directory, all of whose contents will be ' - 'deployed to the device.') - parser.add_argument( - '--runtime-deps-path', type=str, - help='Runtime data dependency file from GN.') - parser.add_argument( - '--vpython-dir', type=str, - help='Location on host of a directory containing a vpython binary to ' - 'deploy to the device before the test starts. The location of this ' - 'dir will be added onto PATH in the device. WARNING: The arch of ' - 'the device might not match the arch of the host, so avoid using ' - '"${platform}" when downloading vpython via CIPD.') - # TODO(bpastene): Switch all uses of "--vm-logs-dir" to "--logs-dir". - parser.add_argument( - '--vm-logs-dir', '--logs-dir', type=str, dest='logs_dir', - help='Will copy everything under /var/log/ from the device after the ' - 'test into the specified dir.') +def add_common_args(*parsers): + for parser in parsers: + parser.add_argument('--verbose', '-v', action='store_true') + parser.add_argument( + '--board', type=str, required=True, help='Type of CrOS device.') + parser.add_argument( + '--cros-cache', type=str, default=DEFAULT_CROS_CACHE, + help='Path to cros cache.') + parser.add_argument( + '--path-to-outdir', type=str, required=True, + help='Path to output directory, all of whose contents will be ' + 'deployed to the device.') + parser.add_argument( + '--runtime-deps-path', type=str, + help='Runtime data dependency file from GN.') + parser.add_argument( + '--vpython-dir', type=str, + help='Location on host of a directory containing a vpython binary to ' + 'deploy to the device before the test starts. The location of ' + 'this dir will be added onto PATH in the device. WARNING: The ' + 'arch of the device might not match the arch of the host, so ' + 'avoid using "${platform}" when downloading vpython via CIPD.') + # TODO(bpastene): Switch all uses of "--vm-logs-dir" to "--logs-dir". + parser.add_argument( + '--vm-logs-dir', '--logs-dir', type=str, dest='logs_dir', + help='Will copy everything under /var/log/ from the device after the ' + 'test into the specified dir.') + + vm_or_device_group = parser.add_mutually_exclusive_group() + vm_or_device_group.add_argument( + '--use-vm', action='store_true', + help='Will run the test in the VM instead of a device.') + vm_or_device_group.add_argument( + '--device', type=str, + help='Hostname (or IP) of device to run the test on. This arg is not ' + 'required if --use-vm is set.') def main(): parser = argparse.ArgumentParser() - parser.add_argument('--verbose', '-v', action='store_true') - # Required args. - parser.add_argument( - '--board', type=str, required=True, help='Type of CrOS device.') - vm_or_device_group = parser.add_mutually_exclusive_group() - vm_or_device_group.add_argument( - '--use-vm', action='store_true', - help='Will run the test in the VM instead of a device.') - vm_or_device_group.add_argument( - '--device', type=str, - help='Hostname (or IP) of device to run the test on. This arg is not ' - 'required if --use-vm is set.') subparsers = parser.add_subparsers(dest='test_type') # Host-side test args. host_cmd_parser = subparsers.add_parser( @@ -727,13 +728,6 @@ 'will be 127.0.0.1:9222.') host_cmd_parser.set_defaults(func=host_cmd) host_cmd_parser.add_argument( - '--cros-cache', type=str, default=DEFAULT_CROS_CACHE, - help='Path to cros cache.') - host_cmd_parser.add_argument( - '--path-to-outdir', type=os.path.realpath, - help='Path to output directory, all of whose contents will be deployed ' - 'to the device.') - host_cmd_parser.add_argument( '--deploy-chrome', action='store_true', help='Will deploy a locally built Chrome binary to the device before ' 'running the host-cmd.') @@ -797,8 +791,7 @@ help='Use the host-side Tast bin to run the tests instead of the ' 'DUT-side local_test_runner. TODO(bpastene): Make this default.') - add_common_args(gtest_parser) - add_common_args(tast_test_parser) + add_common_args(gtest_parser, tast_test_parser, host_cmd_parser) args, unknown_args = parser.parse_known_args() logging.basicConfig(level=logging.DEBUG if args.verbose else logging.WARN)
diff --git a/cc/input/scroll_snap_data.cc b/cc/input/scroll_snap_data.cc index de776f3..b09ded1e 100644 --- a/cc/input/scroll_snap_data.cc +++ b/cc/input/scroll_snap_data.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "cc/input/scroll_snap_data.h" +#include "base/numerics/ranges.h" #include "cc/input/snap_selection_strategy.h" #include <algorithm> @@ -61,10 +62,10 @@ } void SnapSearchResult::Clip(float max_snap, float max_visible) { - snap_offset_ = std::max(std::min(snap_offset_, max_snap), 0.0f); + snap_offset_ = base::ClampToRange(snap_offset_, 0.0f, max_snap); visible_range_ = - gfx::RangeF(std::max(std::min(visible_range_.start(), max_visible), 0.0f), - std::max(std::min(visible_range_.end(), max_visible), 0.0f)); + gfx::RangeF(base::ClampToRange(visible_range_.start(), 0.0f, max_visible), + base::ClampToRange(visible_range_.end(), 0.0f, max_visible)); } void SnapSearchResult::Union(const SnapSearchResult& other) { @@ -124,16 +125,20 @@ // A region that includes every reachable scroll position. gfx::RectF scrollable_region(0, 0, max_position_.x(), max_position_.y()); if (should_snap_on_x) { - // Start from current position in the cross axis and assume it's always - // visible. + // Start from current position in the cross axis. The search algorithm + // expects the cross axis position to be inside scroller bounds. But since + // we cannot always assume that the incoming value fits this criteria we + // clamp it to the bounds to ensure this variant. SnapSearchResult initial_snap_position_y = { - base_position.y(), gfx::RangeF(0, max_position_.x())}; + base::ClampToRange(base_position.y(), 0.f, max_position_.y()), + gfx::RangeF(0, max_position_.x())}; closest_x = FindClosestValidArea(SearchAxis::kX, strategy, initial_snap_position_y); } if (should_snap_on_y) { SnapSearchResult initial_snap_position_x = { - base_position.x(), gfx::RangeF(0, max_position_.y())}; + base::ClampToRange(base_position.x(), 0.f, max_position_.x()), + gfx::RangeF(0, max_position_.y())}; closest_y = FindClosestValidArea(SearchAxis::kY, strategy, initial_snap_position_x); } @@ -170,9 +175,9 @@ base::Optional<SnapSearchResult> SnapContainerData::FindClosestValidArea( SearchAxis axis, const SnapSelectionStrategy& strategy, - const SnapSearchResult& cros_axis_snap_result) const { + const SnapSearchResult& cross_axis_snap_result) const { base::Optional<SnapSearchResult> result = - FindClosestValidAreaInternal(axis, strategy, cros_axis_snap_result); + FindClosestValidAreaInternal(axis, strategy, cross_axis_snap_result); // For EndAndDirectionStrategy, if there is a snap area with snap-stop:always, // and is between the starting position and the above result, we should choose @@ -189,7 +194,7 @@ SnapStopAlwaysFilter::kRequire); base::Optional<SnapSearchResult> must_only_result = FindClosestValidAreaInternal(axis, *must_only_strategy, - cros_axis_snap_result, false); + cross_axis_snap_result, false); result = ClosestSearchResult(strategy.current_position(), axis, result, must_only_result); } @@ -209,15 +214,21 @@ strategy.ShouldSnapOnX(), strategy.ShouldSnapOnY()); return FindClosestValidAreaInternal(axis, *relaxed_strategy, - cros_axis_snap_result); + cross_axis_snap_result); } base::Optional<SnapSearchResult> SnapContainerData::FindClosestValidAreaInternal( SearchAxis axis, const SnapSelectionStrategy& strategy, - const SnapSearchResult& cros_axis_snap_result, + const SnapSearchResult& cross_axis_snap_result, bool should_consider_covering) const { + // The cross axis result is expected to be within bounds otherwise no snap + // area will meet the mutual visibility requirement. + DCHECK(cross_axis_snap_result.snap_offset() >= 0 && + cross_axis_snap_result.snap_offset() <= + (axis == SearchAxis::kX ? max_position_.y() : max_position_.x())); + // The search result from the snap area that's closest to the search origin. base::Optional<SnapSearchResult> closest; // The search result with the intended position if it makes a snap area cover @@ -251,7 +262,7 @@ // position as a valid snap position. SnapSearchResult covering_candidate = candidate; covering_candidate.set_snap_offset(intended_position); - if (IsMutualVisible(covering_candidate, cros_axis_snap_result)) + if (IsMutualVisible(covering_candidate, cross_axis_snap_result)) SetOrUpdateResult(covering_candidate, &covering); // Even if a snap area covers the snapport, we need to continue this // search to find previous and next snap positions and also to have @@ -259,7 +270,7 @@ // rejected. And this covering snap area has its own alignment that may // generates a snap position rejecting the current inplace candidate. } - if (!IsMutualVisible(candidate, cros_axis_snap_result)) + if (!IsMutualVisible(candidate, cross_axis_snap_result)) continue; float distance = std::abs(candidate.snap_offset() - base_position);
diff --git a/cc/raster/one_copy_raster_buffer_provider.cc b/cc/raster/one_copy_raster_buffer_provider.cc index bbdf3744..4a24864 100644 --- a/cc/raster/one_copy_raster_buffer_provider.cc +++ b/cc/raster/one_copy_raster_buffer_provider.cc
@@ -292,13 +292,12 @@ const RasterSource::PlaybackSettings& playback_settings, uint64_t previous_content_id, uint64_t new_content_id) { - // Allocate GpuMemoryBuffer if necessary. If using partial raster, we - // must allocate a buffer with BufferUsage CPU_READ_WRITE_PERSISTENT. + // Allocate GpuMemoryBuffer if necessary. if (!staging_buffer->gpu_memory_buffer) { staging_buffer->gpu_memory_buffer = gpu_memory_buffer_manager_->CreateGpuMemoryBuffer( - staging_buffer->size, BufferFormat(format), StagingBufferUsage(), - gpu::kNullSurfaceHandle); + staging_buffer->size, BufferFormat(format), + gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, gpu::kNullSurfaceHandle); } gfx::Rect playback_rect = raster_full_rect; @@ -483,12 +482,6 @@ return out_sync_token; } -gfx::BufferUsage OneCopyRasterBufferProvider::StagingBufferUsage() const { - return use_partial_raster_ - ? gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT - : gfx::BufferUsage::GPU_READ_CPU_READ_WRITE; -} - bool OneCopyRasterBufferProvider::CheckRasterFinishedQueries() { return false; }
diff --git a/cc/raster/one_copy_raster_buffer_provider.h b/cc/raster/one_copy_raster_buffer_provider.h index 40aaf1d..a307c01 100644 --- a/cc/raster/one_copy_raster_buffer_provider.h +++ b/cc/raster/one_copy_raster_buffer_provider.h
@@ -144,7 +144,6 @@ bool mailbox_texture_is_overlay_candidate, const gpu::SyncToken& sync_token, const gfx::ColorSpace& color_space); - gfx::BufferUsage StagingBufferUsage() const; viz::ContextProvider* const compositor_context_provider_; viz::RasterContextProvider* const worker_context_provider_;
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 9b29f365..5548c43 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -2439,6 +2439,7 @@ "java/src/org/chromium/chrome/browser/omnibox/OmniboxUrlEmphasizer.java", "java/src/org/chromium/chrome/browser/omnibox/OmniboxViewUtil.java", "java/src/org/chromium/chrome/browser/omnibox/geo/GeolocationHeader.java", + "java/src/org/chromium/chrome/browser/omnibox/suggestions/AnswersImageFetcher.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteController.java", "java/src/org/chromium/chrome/browser/page_info/CertificateChainHelper.java", "java/src/org/chromium/chrome/browser/page_info/CertificateViewer.java",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index 9ef806e3..bc6831a 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -1138,6 +1138,7 @@ "java/src/org/chromium/chrome/browser/omnibox/status/StatusViewBinder.java", "java/src/org/chromium/chrome/browser/omnibox/status/StatusProperties.java", "java/src/org/chromium/chrome/browser/omnibox/status/StatusViewCoordinator.java", + "java/src/org/chromium/chrome/browser/omnibox/suggestions/AnswersImageFetcher.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteController.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java", "java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java",
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni index 7e24eed..32fcfbc5 100644 --- a/chrome/android/chrome_test_java_sources.gni +++ b/chrome/android/chrome_test_java_sources.gni
@@ -473,6 +473,7 @@ "javatests/src/org/chromium/chrome/browser/tabmodel/TestTabModelDirectory.java", "javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java", "javatests/src/org/chromium/chrome/browser/tabmodel/document/MockDocumentTabModel.java", + "javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeTest.java", "javatests/src/org/chromium/chrome/browser/test/ChromeBrowserTestRule.java", "javatests/src/org/chromium/chrome/browser/test/ClearAppDataTestRule.java", "javatests/src/org/chromium/chrome/browser/test/CommandLineInitRule.java",
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridContainerViewBinderTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridContainerViewBinderTest.java index 89644e5..fd6613b 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridContainerViewBinderTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridContainerViewBinderTest.java
@@ -21,6 +21,7 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.test.util.CallbackHelper; +import org.chromium.base.test.util.DisabledTest; import org.chromium.chrome.R; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.ui.DummyUiActivity; @@ -97,6 +98,8 @@ @Test @MediumTest + @DisabledTest + // Failed multiple times on Android CFI https://crbug.com/954145 public void testShowWithAnimation() throws Exception { TestThreadUtils.runOnUiThreadBlocking(() -> { mContainerModel.set(
diff --git a/chrome/android/java/res/values/colors.xml b/chrome/android/java/res/values/colors.xml index f7015d4..4280f4a2 100644 --- a/chrome/android/java/res/values/colors.xml +++ b/chrome/android/java/res/values/colors.xml
@@ -10,7 +10,7 @@ <color name="default_primary_color">#F2F2F2</color> <color name="input_underline_error_color">#D32F2F</color> <color name="explanation_text_color">#909090</color> - <color name="text_highlight_color">#C6DAFC</color> + <color name="text_highlight_color">@color/highlight_color_on_dark_text</color> <!-- Control colors for toggles, checkboxes, ratio buttons, list item highlight, and accent. Note that these should NOT be used for icon tint. --> @@ -141,7 +141,6 @@ <!-- LocationBar colors --> <color name="locationbar_dark_hint_text">@color/search_box_hint</color> <color name="locationbar_light_hint_text">@color/white_alpha_70</color> - <color name="locationbar_light_selection_color">#CC5595FE</color> <color name="locationbar_status_offline_color">@color/modern_grey_900</color> <color name="locationbar_status_offline_color_light">@android:color/white</color> <color name="locationbar_status_preview_color">@color/modern_blue_600</color>
diff --git a/chrome/android/java/res_night/values-night/colors.xml b/chrome/android/java/res_night/values-night/colors.xml index cd9130f8..4939b20 100644 --- a/chrome/android/java/res_night/values-night/colors.xml +++ b/chrome/android/java/res_night/values-night/colors.xml
@@ -6,6 +6,7 @@ <resources> <color name="light_active_color">@color/modern_blue_300</color> <color name="control_normal_color">@color/modern_grey_500</color> + <color name="text_highlight_color">@color/highlight_color_on_light_text</color> <color name="toolbar_text_box_background">@color/modern_grey_800</color>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/BitmapCache.java b/chrome/android/java/src/org/chromium/chrome/browser/BitmapCache.java index 67b9806..d7b2d53 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/BitmapCache.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/BitmapCache.java
@@ -121,14 +121,6 @@ sDeduplicationCache.put(key, new WeakReference<>(bitmap)); } - /** - * Evict all bitmaps from the cache. - */ - public void clear() { - getBitmapCache().evictAll(); - scheduleDeduplicationCache(); - } - /** @return The total number of bytes taken by the bitmaps in this cache. */ public int size() { return getBitmapCache().size();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeInactivityTracker.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeInactivityTracker.java index 0693c2ba..ee35000 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeInactivityTracker.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeInactivityTracker.java
@@ -11,13 +11,15 @@ import org.chromium.base.VisibleForTesting; import org.chromium.chrome.browser.init.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.lifecycle.Destroyable; +import org.chromium.chrome.browser.lifecycle.PauseResumeWithNativeObserver; import org.chromium.chrome.browser.lifecycle.StartStopWithNativeObserver; import org.chromium.content_public.browser.UiThreadTaskTraits; /** * Manages pref that can track the delay since the last stop of the tracked activity. */ -public class ChromeInactivityTracker implements StartStopWithNativeObserver, Destroyable { +public class ChromeInactivityTracker + implements StartStopWithNativeObserver, PauseResumeWithNativeObserver, Destroyable { private static final String TAG = "InactivityTracker"; private static final long UNKNOWN_LAST_BACKGROUNDED_TIME = -1; @@ -90,12 +92,8 @@ FEATURE_NAME, NTP_LAUNCH_DELAY_IN_MINS_PARAM, DEFAULT_LAUNCH_DELAY_IN_MINS); mIsEnabled = ChromeFeatureList.isEnabled(FEATURE_NAME); - if (mIsEnabled) { - mLifecycleDispatcher = lifecycleDispatcher; - mLifecycleDispatcher.register(this); - } else { - mLifecycleDispatcher = null; - } + mLifecycleDispatcher = lifecycleDispatcher; + mLifecycleDispatcher.register(this); } /** @@ -107,7 +105,15 @@ ContextUtils.getAppSharedPreferences().edit().putLong(mPrefName, timeInMillis).apply(); } - private long getLastBackgroundedTimeMs() { + /** + * Updates shared preferences such that the last backgrounded time is no + * longer valid. This will prevent multiple new intents from firing. + */ + private void clearLastBackgroundedTimeInPrefs() { + setLastBackgroundedTimeInPrefs(UNKNOWN_LAST_BACKGROUNDED_TIME); + } + + long getLastBackgroundedTimeMs() { return ContextUtils.getAppSharedPreferences().getLong( mPrefName, UNKNOWN_LAST_BACKGROUNDED_TIME); } @@ -150,12 +156,29 @@ @Override public void onStartWithNative() { - setLastBackgroundedTimeInPrefs(UNKNOWN_LAST_BACKGROUNDED_TIME); cancelCurrentTask(); } @Override + public void onResumeWithNative() { + // We clear the backgrounded time here, rather than in #onStartWithNative, to give + // handlers the chance to respond to inactivity during any onStartWithNative handler + // regardless of ordering. onResume is always called after onStart, and it should be fine to + // consider Chrome active if it reaches onResume. + clearLastBackgroundedTimeInPrefs(); + } + + @Override + public void onPauseWithNative() {} + + @Override public void onStopWithNative() { + // Always track the last backgrounded time in case others are using the pref. + long timeInMillis = System.currentTimeMillis(); + setLastBackgroundedTimeInPrefs(timeInMillis); + + if (!mIsEnabled) return; + Log.i(TAG, "onStop, scheduling for " + mNtpLaunchDelayInMins + " minutes"); cancelCurrentTask(); @@ -164,7 +187,6 @@ return; } mCurrentlyPostedInactiveCallback = new CancelableRunnableTask(mInactiveCallback); - setLastBackgroundedTimeInPrefs(System.currentTimeMillis()); org.chromium.base.task.PostTask.postDelayedTask(UiThreadTaskTraits.DEFAULT, mCurrentlyPostedInactiveCallback, mNtpLaunchDelayInMins * DateUtils.MINUTE_IN_MILLIS);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index e3ba8b3..5552922 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -922,8 +922,7 @@ boolean isOverviewVisible = mOverviewModeController.overviewVisible(); // Experiment: show tab switcher on return after {x} minutes (enable-tab-switcher-on-return} - long lastBackgroundedTimeMillis = - ContextUtils.getAppSharedPreferences().getLong(LAST_BACKGROUNDED_TIME_MS_PREF, -1); + long lastBackgroundedTimeMillis = mInactivityTracker.getLastBackgroundedTimeMs(); if (ReturnToChromeExperimentsUtil.shouldShowTabSwitcher(lastBackgroundedTimeMillis) && isMainIntentFromLauncher(getIntent()) && !isOverviewVisible) { toggleOverview();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionManager.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionManager.java index 329c86e..adfc1a37 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionManager.java
@@ -7,6 +7,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.support.annotation.Nullable; +import android.support.annotation.UiThread; import android.text.TextUtils; import org.chromium.base.ContextUtils; @@ -31,7 +32,7 @@ * {@link InstalledWebappBridge}. * * Lifecycle: This is a singleton. - * Thread safety: Only call methods on a single thread. + * Thread safety: Only call methods on the UI thread as this class may call into native. * Native: Does not require native. */ @Singleton @@ -74,6 +75,7 @@ return permissions.toArray(new InstalledWebappBridge.Permission[permissions.size()]); } + @UiThread void register(Origin origin, String packageName, boolean notificationsEnabled) { // TODO(peconn): Only trigger if this is for the first time? @@ -84,15 +86,21 @@ // did it the other way around there'd be a small moment in time where the website's // notification permission could flicker from SET -> UNSET -> SET. This way we transition // straight from the channel's permission to the app's permission. - mStore.setStateForOrigin(origin, packageName, appName, notificationsEnabled); + boolean stateChanged = + mStore.setStateForOrigin(origin, packageName, appName, notificationsEnabled); NotificationChannelPreserver.deleteChannelIfNeeded(mPermissionPreserver, origin); + + if (stateChanged) InstalledWebappBridge.notifyPermissionsChange(); } + @UiThread void unregister(Origin origin) { mStore.removeOrigin(origin); NotificationChannelPreserver.restoreChannelIfNeeded(mPermissionPreserver, origin); + + InstalledWebappBridge.notifyPermissionsChange(); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionStore.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionStore.java index 0cbbf8dc..6b2a346 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionStore.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionStore.java
@@ -102,15 +102,34 @@ } } - /** Sets the notification state for the origin. */ - void setStateForOrigin(Origin origin, String packageName, String appName, boolean enabled) { + /** + * Sets the notification state for the origin. + * Returns whether {@code true} if state was changed, {@code false} if the provided state was + * the same as the state beforehand. + */ + boolean setStateForOrigin(Origin origin, String packageName, String appName, boolean enabled) { + boolean modified = !getStoredOrigins().contains(origin.toString()); + + if (!modified) { + // Don't bother with these extra checks if we have a brand new origin. + boolean enabledChanged = enabled != + mPreferences.getBoolean(createNotificationPermissionKey(origin), false); + boolean packageChanged = !packageName.equals( + mPreferences.getString(createPackageNameKey(origin), null)); + boolean appNameChanged = !appName.equals( + mPreferences.getString(createAppNameKey(origin), null)); + modified = enabledChanged || packageChanged || appNameChanged; + } + addOrigin(origin); - SharedPreferences.Editor editor = mPreferences.edit(); - editor.putBoolean(createNotificationPermissionKey(origin), enabled); - editor.putString(createPackageNameKey(origin), packageName); - editor.putString(createAppNameKey(origin), appName); - editor.apply(); + mPreferences.edit() + .putBoolean(createNotificationPermissionKey(origin), enabled) + .putString(createPackageNameKey(origin), packageName) + .putString(createAppNameKey(origin), appName) + .apply(); + + return modified; } /** Removes the origin from the store. */ @@ -118,19 +137,19 @@ Set<String> origins = getStoredOrigins(); origins.remove(origin.toString()); - SharedPreferences.Editor editor = mPreferences.edit(); - editor.putStringSet(KEY_ALL_ORIGINS, origins); - editor.remove(createNotificationPermissionKey(origin)); - editor.remove(createAppNameKey(origin)); - editor.remove(createPackageNameKey(origin)); - editor.apply(); + mPreferences.edit() + .putStringSet(KEY_ALL_ORIGINS, origins) + .remove(createNotificationPermissionKey(origin)) + .remove(createAppNameKey(origin)) + .remove(createPackageNameKey(origin)) + .apply(); } /** Stores the notification state the origin had before the TWA was installed. */ void setPreTwaNotificationState(Origin origin, boolean enabled) { - SharedPreferences.Editor editor = mPreferences.edit(); - editor.putBoolean(createNotificationPreTwaPermissionKey(origin), enabled); - editor.apply(); + mPreferences.edit() + .putBoolean(createNotificationPreTwaPermissionKey(origin), enabled) + .apply(); } /** @@ -144,9 +163,7 @@ boolean enabled = mPreferences.getBoolean(key, false); - SharedPreferences.Editor editor = mPreferences.edit(); - editor.remove(key); - editor.apply(); + mPreferences.edit().remove(key).apply(); return enabled; } @@ -154,18 +171,16 @@ /** Clears the store, for testing. */ @VisibleForTesting public void clearForTesting() { - SharedPreferences.Editor editor = mPreferences.edit(); - editor.clear(); - editor.apply(); + mPreferences.edit().clear().apply(); } private void addOrigin(Origin origin) { Set<String> origins = getStoredOrigins(); origins.add(origin.toString()); - SharedPreferences.Editor editor = mPreferences.edit(); - editor.putStringSet(KEY_ALL_ORIGINS, origins); - editor.apply(); + mPreferences.edit() + .putStringSet(KEY_ALL_ORIGINS, origins) + .apply(); } private String createNotificationPermissionKey(Origin origin) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/CachedImageFetcher.java b/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/CachedImageFetcher.java index 96f6eeb..d351d36d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/CachedImageFetcher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/CachedImageFetcher.java
@@ -112,9 +112,6 @@ } @Override - public void clear() {} - - @Override public @ImageFetcherConfig int getConfig() { return ImageFetcherConfig.DISK_CACHE_ONLY; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/ImageFetcher.java b/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/ImageFetcher.java index 114652c..d05a052 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/ImageFetcher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/ImageFetcher.java
@@ -19,7 +19,6 @@ */ public abstract class ImageFetcher { // All UMA client names collected here to prevent duplicates. - public static final String ANSWER_SUGGESTIONS_UMA_CLIENT_NAME = "AnswerSuggestions"; public static final String ASSISTANT_DETAILS_UMA_CLIENT_NAME = "AssistantDetails"; public static final String ASSISTANT_INFO_BOX_UMA_CLIENT_NAME = "AssistantInfoBox"; public static final String CONTEXTUAL_SUGGESTIONS_UMA_CLIENT_NAME = "ContextualSuggestions"; @@ -101,11 +100,6 @@ } /** - * Clear the cache of any bitmaps that may be in-memory. - */ - public abstract void clear(); - - /** * Returns the type of Image Fetcher this is based on class arrangements. See * image_fetcher_service.h for a detailed description of the available configurations. *
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/ImageFetcherFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/ImageFetcherFactory.java index 14b76ab3..748fd4a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/ImageFetcherFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/ImageFetcherFactory.java
@@ -16,28 +16,25 @@ /** * Alias for createImageFetcher below. + * + * @param config The type of ImageFetcher you need. + * @return The correct ImageFetcher according to the provided config. */ public static ImageFetcher createImageFetcher(@ImageFetcherConfig int config) { - return createImageFetcher(config, ImageFetcherBridge.getInstance(), null, - InMemoryCachedImageFetcher.DEFAULT_CACHE_SIZE); + return createImageFetcher(config, null); } /** * Alias for createImageFetcher below. + * + * @param config The type of ImageFetcher you need. + * @param discardableReferencePool Used to store images in-memory. + * @return The correct ImageFetcher according to the provided config. */ public static ImageFetcher createImageFetcher( @ImageFetcherConfig int config, DiscardableReferencePool discardableReferencePool) { - return createImageFetcher(config, ImageFetcherBridge.getInstance(), - discardableReferencePool, InMemoryCachedImageFetcher.DEFAULT_CACHE_SIZE); - } - - /** - * Alias for createImageFetcher below. - */ - public static ImageFetcher createImageFetcher(@ImageFetcherConfig int config, - DiscardableReferencePool discardableReferencePool, int inMemoryCacheSize) { - return createImageFetcher(config, ImageFetcherBridge.getInstance(), - discardableReferencePool, inMemoryCacheSize); + return createImageFetcher( + config, discardableReferencePool, ImageFetcherBridge.getInstance()); } /** @@ -45,14 +42,13 @@ * config that you must destroy. * * @param config The type of ImageFetcher you need. - * @param imageFetcherBridge Bridge to use. * @param discardableReferencePool Used to store images in-memory. - * @param inMemoryCacheSize The size of the in memory cache (in bytes). + * @param imageFetcherBridge Bridge to use. * @return The correct ImageFetcher according to the provided config. */ public static ImageFetcher createImageFetcher(@ImageFetcherConfig int config, - ImageFetcherBridge imageFetcherBridge, - DiscardableReferencePool discardableReferencePool, int inMemoryCacheSize) { + DiscardableReferencePool discardableReferencePool, + ImageFetcherBridge imageFetcherBridge) { // TODO(crbug.com/947191):Allow server-side configuration image fetcher clients. switch (config) { case ImageFetcherConfig.NETWORK_ONLY: @@ -68,15 +64,15 @@ case ImageFetcherConfig.IN_MEMORY_ONLY: assert discardableReferencePool != null; return new InMemoryCachedImageFetcher( - createImageFetcher(ImageFetcherConfig.NETWORK_ONLY, imageFetcherBridge, - discardableReferencePool, inMemoryCacheSize), - discardableReferencePool, inMemoryCacheSize); + createImageFetcher( + ImageFetcherConfig.NETWORK_ONLY, null, imageFetcherBridge), + discardableReferencePool); case ImageFetcherConfig.IN_MEMORY_WITH_DISK_CACHE: assert discardableReferencePool != null; return new InMemoryCachedImageFetcher( - createImageFetcher(ImageFetcherConfig.DISK_CACHE_ONLY, imageFetcherBridge, - discardableReferencePool, inMemoryCacheSize), - discardableReferencePool, inMemoryCacheSize); + createImageFetcher( + ImageFetcherConfig.DISK_CACHE_ONLY, null, imageFetcherBridge), + discardableReferencePool); default: return null; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/InMemoryCachedImageFetcher.java b/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/InMemoryCachedImageFetcher.java index 2cecdfe..e1bc4b8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/InMemoryCachedImageFetcher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/InMemoryCachedImageFetcher.java
@@ -19,7 +19,7 @@ * ImageFetcher implementation with an in-memory cache. Can also be configured to use a disk cache. */ public class InMemoryCachedImageFetcher extends ImageFetcher { - public static final int DEFAULT_CACHE_SIZE = 20 * ConversionUtils.BYTES_PER_MEGABYTE; // 20mb + private static final int DEFAULT_CACHE_SIZE = 20 * ConversionUtils.BYTES_PER_MEGABYTE; // 20mb private static final float PORTION_OF_AVAILABLE_MEMORY = 1.f / 8.f; // Will do the work if the image isn't cached in memory. @@ -111,11 +111,6 @@ } @Override - public void clear() { - mBitmapCache.clear(); - } - - @Override public @ImageFetcherConfig int getConfig() { return mConfig; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/NetworkImageFetcher.java b/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/NetworkImageFetcher.java index aae248a..52b4f31 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/NetworkImageFetcher.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/image_fetcher/NetworkImageFetcher.java
@@ -43,9 +43,6 @@ } @Override - public void clear() {} - - @Override public @ImageFetcherConfig int getConfig() { return ImageFetcherConfig.NETWORK_ONLY; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBar.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBar.java index 0b07d9d..03cee93 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBar.java
@@ -25,11 +25,6 @@ */ public interface LocationBar extends UrlBarDelegate { /** - * Cleanup resources when this goes out of scope. - */ - void destroy(); - - /** * Handles native dependent initialization for this class. */ void onNativeLibraryReady();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java index cea7caa..b670f3a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
@@ -193,12 +193,6 @@ } @Override - public void destroy() { - mAutocompleteCoordinator.destroy(); - mAutocompleteCoordinator = null; - } - - @Override protected void onFinishInflate() { super.onFinishInflate();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBarViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBarViewBinder.java index b9920bf..6ed4066 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBarViewBinder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/UrlBarViewBinder.java
@@ -100,7 +100,7 @@ hintColor = ApiCompatibilityUtils.getColor(resources, R.color.locationbar_light_hint_text); highlightColor = ApiCompatibilityUtils.getColor( - resources, R.color.locationbar_light_selection_color); + resources, R.color.highlight_color_on_light_text); } view.setTextColor(textColor);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AnswersImageFetcher.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AnswersImageFetcher.java new file mode 100644 index 0000000..39a6122 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AnswersImageFetcher.java
@@ -0,0 +1,104 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.omnibox.suggestions; + +import android.graphics.Bitmap; +import android.support.v4.util.LruCache; + +import org.chromium.base.annotations.CalledByNative; +import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.util.ConversionUtils; + +/** + * Provides access to images used by Answers in Suggest. + */ +public class AnswersImageFetcher { + // Matches the value in BitmapFetcherService. + private static final int INVALID_IMAGE_REQUEST_ID = 0; + private static final int MAX_CACHE_SIZE = 500 * ConversionUtils.BYTES_PER_KILOBYTE; + + /** + * Observer for updating an image when it is available. + */ + public interface AnswersImageObserver { + /** + * Called when the image is updated. + * + * @param bitmap the image + */ + @CalledByNative("AnswersImageObserver") + void onAnswersImageChanged(Bitmap bitmap); + } + + // Intentionally not using BitmapCache as that does not cache for low end devices (it ensures + // the bitmaps are de-dups across instances, but discards them if there is not an active + // reference to one). + private final LruCache<String, Bitmap> mBitmapCache = + new LruCache<String, Bitmap>(MAX_CACHE_SIZE) { + @Override + protected int sizeOf(String key, Bitmap value) { + return value.getByteCount(); + } + }; + + /** + * Clears the cached answer images. + */ + public void clearCache() { + mBitmapCache.evictAll(); + } + + /** + * Request image, observer is notified when image is loaded. + * @param profile Profile that the request is for. + * @param imageUrl URL for image data. + * @param observer Observer to be notified when image is updated. The C++ side will hold a + * strong reference to this. + * @return A request_id. + */ + public int requestAnswersImage( + Profile profile, String imageUrl, AnswersImageObserver observer) { + if (!profile.isOffTheRecord()) { + Bitmap bitmap = mBitmapCache.get(imageUrl); + if (bitmap != null) { + observer.onAnswersImageChanged(bitmap); + return INVALID_IMAGE_REQUEST_ID; + } + } + AnswersImageObserver cacheObserver = observer; + if (!profile.isOffTheRecord()) { + cacheObserver = new AnswersImageObserver() { + @Override + public void onAnswersImageChanged(Bitmap bitmap) { + if (bitmap == null) return; + mBitmapCache.put(imageUrl, bitmap); + observer.onAnswersImageChanged(bitmap); + } + }; + } + return nativeRequestAnswersImage(profile, imageUrl, cacheObserver); + } + + /** + * Cancel a pending image request. + * @param profile Profile the request was issued for. + * @param requestId The ID of the request to be cancelled. + */ + public void cancelAnswersImageRequest(Profile profile, int requestId) { + nativeCancelAnswersImageRequest(profile, requestId); + } + + /** + * Requests an image at |imageUrl| for the given |profile| with |observer| being notified. + * @returns an AnswersImageRequest + */ + private static native int nativeRequestAnswersImage( + Profile profile, String imageUrl, AnswersImageObserver observer); + + /** + * Cancels a pending request. + */ + private static native void nativeCancelAnswersImageRequest(Profile profile, int requestId); +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java index 74624f95..a77cf3d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java
@@ -50,7 +50,7 @@ */ public class AutocompleteCoordinator implements UrlFocusChangeListener, UrlTextChangeListener { private final ViewGroup mParent; - private AutocompleteMediator mMediator; + private final AutocompleteMediator mMediator; private ListView mListView; @@ -170,11 +170,6 @@ new AutocompleteMediator(context, delegate, urlBarEditingTextProvider, listModel); } - public void destroy() { - mMediator.destroy(); - mMediator = null; - } - private ViewProvider<SuggestionListViewHolder> createViewProvider(Context context) { return new ViewProvider<SuggestionListViewHolder>() { private List<Callback<SuggestionListViewHolder>> mCallbacks = new ArrayList<>();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java index e63d273..77d63a4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
@@ -93,7 +93,7 @@ private final Handler mHandler; private final BasicSuggestionProcessor mBasicSuggestionProcessor; private EditUrlSuggestionProcessor mEditUrlProcessor; - private AnswerSuggestionProcessor mAnswerSuggestionProcessor; + private final AnswerSuggestionProcessor mAnswerSuggestionProcessor; private ToolbarDataProvider mDataProvider; private boolean mNativeInitialized; @@ -157,11 +157,6 @@ delegate, (suggestion) -> onSelection(suggestion, 0)); } - public void destroy() { - mAnswerSuggestionProcessor.destroy(); - mAnswerSuggestionProcessor = null; - } - @Override public void onStartWithNative() {}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java index 4be65e7..7ddabaed 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/answer/AnswerSuggestionProcessor.java
@@ -11,13 +11,10 @@ import android.view.View; import org.chromium.base.ThreadUtils; -import org.chromium.chrome.browser.ChromeApplication; import org.chromium.chrome.browser.ChromeFeatureList; -import org.chromium.chrome.browser.image_fetcher.ImageFetcher; -import org.chromium.chrome.browser.image_fetcher.ImageFetcherConfig; -import org.chromium.chrome.browser.image_fetcher.ImageFetcherFactory; import org.chromium.chrome.browser.omnibox.OmniboxSuggestionType; import org.chromium.chrome.browser.omnibox.UrlBarEditingTextStateProvider; +import org.chromium.chrome.browser.omnibox.suggestions.AnswersImageFetcher; import org.chromium.chrome.browser.omnibox.suggestions.AutocompleteCoordinator.SuggestionProcessor; import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestion; import org.chromium.chrome.browser.omnibox.suggestions.OmniboxSuggestionUiType; @@ -27,7 +24,6 @@ import org.chromium.chrome.browser.omnibox.suggestions.basic.SuggestionViewProperties; import org.chromium.chrome.browser.omnibox.suggestions.basic.SuggestionViewProperties.SuggestionIcon; import org.chromium.chrome.browser.omnibox.suggestions.basic.SuggestionViewProperties.SuggestionTextContainer; -import org.chromium.chrome.browser.util.ConversionUtils; import org.chromium.components.omnibox.AnswerType; import org.chromium.components.omnibox.SuggestionAnswer; import org.chromium.ui.modelutil.PropertyModel; @@ -39,12 +35,10 @@ /** A class that handles model and view creation for the most commonly used omnibox suggestion. */ public class AnswerSuggestionProcessor implements SuggestionProcessor { - private static final int MAX_CACHE_SIZE = 500 * ConversionUtils.BYTES_PER_KILOBYTE; - private final Map<String, List<PropertyModel>> mPendingAnswerRequestUrls; private final Context mContext; private final SuggestionHost mSuggestionHost; - private ImageFetcher mImageFetcher; + private final AnswersImageFetcher mImageFetcher; private final UrlBarEditingTextStateProvider mUrlBarEditingTextProvider; private boolean mEnableNewAnswerLayout; @@ -57,16 +51,10 @@ mContext = context; mSuggestionHost = suggestionHost; mPendingAnswerRequestUrls = new HashMap<>(); + mImageFetcher = new AnswersImageFetcher(); mUrlBarEditingTextProvider = editingTextProvider; } - public void destroy() { - if (mImageFetcher != null) { - mImageFetcher.destroy(); - mImageFetcher = null; - } - } - @Override public boolean doesProcessSuggestion(OmniboxSuggestion suggestion) { // Calculation answers are specific in a way that these are basic suggestions, but processed @@ -108,10 +96,7 @@ @Override public void onUrlFocusChange(boolean hasFocus) { - // This clear is necessary for memory as well as clearing when switching to/from incognito. - if (!hasFocus && mImageFetcher != null) { - mImageFetcher.clear(); - } + if (!hasFocus) mImageFetcher.clearCache(); } private void maybeFetchAnswerIcon(OmniboxSuggestion suggestion, PropertyModel model) { @@ -132,35 +117,30 @@ return; } - if (mImageFetcher == null) { - mImageFetcher = ImageFetcherFactory.createImageFetcher( - ImageFetcherConfig.IN_MEMORY_ONLY, - ((ChromeApplication) mContext.getApplicationContext()).getReferencePool(), - MAX_CACHE_SIZE); - } - List<PropertyModel> models = new ArrayList<>(); models.add(model); mPendingAnswerRequestUrls.put(url, models); + mImageFetcher.requestAnswersImage(mSuggestionHost.getCurrentProfile(), url, + new AnswersImageFetcher.AnswersImageObserver() { + @Override + public void onAnswersImageChanged(Bitmap bitmap) { + ThreadUtils.assertOnUiThread(); - mImageFetcher.fetchImage( - url, ImageFetcher.ANSWER_SUGGESTIONS_UMA_CLIENT_NAME, (Bitmap bitmap) -> { - ThreadUtils.assertOnUiThread(); + List<PropertyModel> models = mPendingAnswerRequestUrls.remove(url); + boolean didUpdate = false; + for (int i = 0; i < models.size(); i++) { + PropertyModel model = models.get(i); + if (!mSuggestionHost.isActiveModel(model)) continue; - List<PropertyModel> currentModels = mPendingAnswerRequestUrls.remove(url); - boolean didUpdate = false; - for (int i = 0; i < currentModels.size(); i++) { - PropertyModel currentModel = currentModels.get(i); - if (!mSuggestionHost.isActiveModel(currentModel)) continue; - - if (mEnableNewAnswerLayout) { - model.set(AnswerSuggestionViewProperties.ANSWER_IMAGE, bitmap); - } else { - model.set(SuggestionViewProperties.ANSWER_IMAGE, bitmap); + if (mEnableNewAnswerLayout) { + model.set(AnswerSuggestionViewProperties.ANSWER_IMAGE, bitmap); + } else { + model.set(SuggestionViewProperties.ANSWER_IMAGE, bitmap); + } + didUpdate = true; } - didUpdate = true; + if (didUpdate) mSuggestionHost.notifyPropertyModelsChanged(); } - if (didUpdate) mSuggestionHost.notifyPropertyModelsChanged(); }); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationPopupAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationPopupAdapter.java index 19960010..8a095f23 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationPopupAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/password_manager/PasswordGenerationPopupAdapter.java
@@ -9,7 +9,6 @@ import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; -import android.widget.RelativeLayout.LayoutParams; import android.widget.TextView; import org.chromium.chrome.R; @@ -21,7 +20,6 @@ public class PasswordGenerationPopupAdapter extends BaseAdapter { private final Context mContext; private final String mExplanationText; - private final int mWidth; /** * UI shows an explanation about storing passwords in Chrome. @@ -44,11 +42,6 @@ Context context, String explanationText, float anchorWidthInDp) { mContext = context; mExplanationText = explanationText; - int horizontalMarginInPx = Math.round(mContext.getResources().getDimensionPixelSize( - R.dimen.password_generation_horizontal_margin)); - int anchorWidthInPx = - Math.round(anchorWidthInDp * mContext.getResources().getDisplayMetrics().density); - mWidth = anchorWidthInPx - 2 * horizontalMarginInPx; } @Override @@ -61,7 +54,6 @@ R.layout.password_generation_popup_explanation, null); TextView explanation = view.findViewById(R.id.password_generation_explanation); explanation.setText(mExplanationText); - explanation.setLayoutParams(new LayoutParams(mWidth, LayoutParams.WRAP_CONTENT)); return view; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeExperimentsUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeExperimentsUtil.java index ee705790..27d2836e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeExperimentsUtil.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeExperimentsUtil.java
@@ -4,13 +4,15 @@ package org.chromium.chrome.browser.tasks; +import org.chromium.base.VisibleForTesting; import org.chromium.chrome.browser.ChromeFeatureList; /** * This is a utility class for managing experiments related to returning to Chrome. */ public final class ReturnToChromeExperimentsUtil { - private static final String TAB_SWITCHER_ON_RETURN_MS = "tab_switcher_on_return_time_ms"; + @VisibleForTesting + public static final String TAB_SWITCHER_ON_RETURN_MS = "tab_switcher_on_return_time_ms"; private ReturnToChromeExperimentsUtil() {}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java index fa02707..34311da 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/CustomTabToolbar.java
@@ -198,9 +198,6 @@ } @Override - public void destroy() {} - - @Override void initialize(ToolbarDataProvider toolbarDataProvider, ToolbarTabController tabController, AppMenuButtonHelper appMenuButtonHelper) { super.initialize(toolbarDataProvider, tabController, appMenuButtonHelper);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java index b5d5327..e2d5d0c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java
@@ -137,8 +137,6 @@ mThemeColorProvider.removeThemeColorObserver(this); mThemeColorProvider = null; } - - getLocationBar().destroy(); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionsTest.java index 529684d7..962d43e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/browserservices/permissiondelegation/TrustedWebActivityPermissionsTest.java
@@ -25,6 +25,7 @@ import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule; import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.net.test.EmbeddedTestServer; import org.chromium.net.test.ServerCertificate; @@ -78,24 +79,29 @@ @Test @MediumTest public void allowNotifications() throws TimeoutException, InterruptedException { - mPermissionManager.register(mOrigin, mPackage, true); + TestThreadUtils.runOnUiThreadBlocking(() -> + mPermissionManager.register(mOrigin, mPackage, true)); assertEquals("\"granted\"", getNotificationPermission()); } @Test @MediumTest public void blockNotifications() throws TimeoutException, InterruptedException { - mPermissionManager.register(mOrigin, mPackage, false); + TestThreadUtils.runOnUiThreadBlocking(() -> + mPermissionManager.register(mOrigin, mPackage, false)); assertEquals("\"denied\"", getNotificationPermission()); } @Test @MediumTest public void unregisterTwa() throws TimeoutException, InterruptedException { - mPermissionManager.register(mOrigin, mPackage, true); + TestThreadUtils.runOnUiThreadBlocking(() -> + mPermissionManager.register(mOrigin, mPackage, true)); assertEquals("\"granted\"", getNotificationPermission()); - mPermissionManager.unregister(mOrigin); + TestThreadUtils.runOnUiThreadBlocking(() -> { + mPermissionManager.unregister(mOrigin); + }); assertEquals("\"default\"", getNotificationPermission()); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/explore_sites/ExploreSitesPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/explore_sites/ExploreSitesPageTest.java index a89efdd..eb5ce7a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/explore_sites/ExploreSitesPageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/explore_sites/ExploreSitesPageTest.java
@@ -5,19 +5,25 @@ package org.chromium.chrome.browser.explore_sites; import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.matcher.ViewMatchers.isAssignableFrom; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.instanceOf; import android.annotation.TargetApi; import android.os.Build; import android.os.SystemClock; import android.support.test.InstrumentationRegistry; +import android.support.test.espresso.UiController; +import android.support.test.espresso.ViewAction; import android.support.test.espresso.contrib.RecyclerViewActions; import android.support.test.filters.SmallTest; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; +import org.hamcrest.Matcher; import org.junit.After; import org.junit.Assert; import org.junit.Assume; @@ -27,7 +33,6 @@ import org.junit.runner.RunWith; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeActivity; @@ -57,6 +62,34 @@ public class ExploreSitesPageTest { // clang-format on + private static final class ScrollToPositionWithOffsetViewAction implements ViewAction { + private final int mPosition; + private final int mOffset; + + private ScrollToPositionWithOffsetViewAction(int position, int offset) { + this.mPosition = position; + mOffset = offset; + } + + @SuppressWarnings("unchecked") + @Override + public Matcher<View> getConstraints() { + return allOf(isAssignableFrom(RecyclerView.class), isDisplayed()); + } + + @Override + public String getDescription() { + return "scroll RecyclerView to mPosition: " + mPosition; + } + + @Override + public void perform(UiController uiController, View view) { + RecyclerView recyclerView = (RecyclerView) view; + ((LinearLayoutManager) recyclerView.getLayoutManager()) + .scrollToPositionWithOffset(mPosition, mOffset); + } + } + ArrayList<ExploreSitesCategory> getTestingCatalog() { final ArrayList<ExploreSitesCategory> categoryList = new ArrayList<>(); for (int i = 0; i < 5; i++) { @@ -112,16 +145,19 @@ .findFirstCompletelyVisibleItemPosition(); } + private void scrollToPosition(int scrollPosition) { + onView(instanceOf(RecyclerView.class)) + .perform(new ScrollToPositionWithOffsetViewAction(scrollPosition, 0)); + } + @Test @SmallTest - @DisabledTest @Feature({"ExploreSites", "RenderTest"}) public void testScrolledLayout_withBack() throws Exception { - final int scrollPosition = 2; - onView(instanceOf(RecyclerView.class)) - .perform(RecyclerViewActions.scrollToPosition(scrollPosition)); + scrollToPosition(2); + mRenderTestRule.render(mRecyclerView, "recycler_layout"); - Assert.assertEquals(scrollPosition, getFirstVisiblePosition()); + final int scrollPosition = getFirstVisiblePosition(); // TODO(https://crbug.com/938519): Remove this sleep in favor of actually waiting for the // scroll bar to disappear. SystemClock.sleep(3000);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeTest.java new file mode 100644 index 0000000..cf195df --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tasks/ReturnToChromeTest.java
@@ -0,0 +1,117 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.browser.tasks; + +import static org.chromium.chrome.browser.tasks.ReturnToChromeExperimentsUtil.TAB_SWITCHER_ON_RETURN_MS; + +import android.app.Activity; +import android.content.Context; +import android.os.SystemClock; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.SmallTest; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.ActivityState; +import org.chromium.base.ApplicationStatus; +import org.chromium.base.test.util.CallbackHelper; +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.Feature; +import org.chromium.chrome.browser.ChromeFeatureList; +import org.chromium.chrome.browser.ChromeSwitches; +import org.chromium.chrome.browser.ChromeTabbedActivity; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.test.ChromeTabbedActivityTestRule; + +import java.util.concurrent.TimeoutException; + +/** + * Tests the functionality of return to chrome features that open overview mode if the timeout + * has passed. + */ +@RunWith(ChromeJUnit4ClassRunner.class) +public class ReturnToChromeTest { + @Rule + public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); + + private ChromeTabbedActivity mActivity; + + @Before + public void setUp() throws Exception { + Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + mActivityTestRule.startMainActivityFromLauncher(); + mActivity = mActivityTestRule.getActivity(); + } + + /** + * Test that overview mode is not triggered if the delay is longer than the interval between + * stop and start. + */ + @Test + @SmallTest + @Feature({"ReturnToChrome"}) + @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, + "enable-features=" + ChromeFeatureList.TAB_SWITCHER_ON_RETURN + "<FakeStudyName", + "force-fieldtrials=FakeStudyName/Enabled", + "force-fieldtrial-params=FakeStudyName.Enabled:" + TAB_SWITCHER_ON_RETURN_MS + + "/100000"}) + public void + testObserverModeNotTriggeredWithoutDelay() throws Exception { + finishActivityCompletely(); + + mActivityTestRule.startMainActivityFromLauncher(); + mActivity = mActivityTestRule.getActivity(); + + Assert.assertFalse(mActivity.getLayoutManager().overviewVisible()); + } + + @Test + @SmallTest + @Feature({"ReturnToChrome"}) + @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, + "enable-features=" + ChromeFeatureList.TAB_SWITCHER_ON_RETURN + "<FakeStudyName", + "force-fieldtrials=FakeStudyName/Enabled", + "force-fieldtrial-params=FakeStudyName.Enabled:" + TAB_SWITCHER_ON_RETURN_MS + "/1"}) + public void + testObserverModeTriggeredWithDelay() throws Exception { + finishActivityCompletely(); + + // Sleep past the timeout + SystemClock.sleep(30); + + mActivityTestRule.startMainActivityFromLauncher(); + mActivity = mActivityTestRule.getActivity(); + + Assert.assertTrue(mActivity.getLayoutManager().overviewVisible()); + } + + private void finishActivityCompletely() throws InterruptedException, TimeoutException { + final CallbackHelper activityCallback = new CallbackHelper(); + ApplicationStatus.ActivityStateListener stateListener = + new ApplicationStatus.ActivityStateListener() { + @Override + public void onActivityStateChange(Activity activity, int newState) { + if (newState == ActivityState.STOPPED) { + activityCallback.notifyCalled(); + ApplicationStatus.unregisterActivityStateListener(this); + } + } + }; + + ApplicationStatus.registerStateListenerForAllActivities(stateListener); + try { + mActivity.finish(); + activityCallback.waitForCallback("Activity did not stop as expected", 0); + mActivityTestRule.setActivity(null); + } finally { + ApplicationStatus.unregisterActivityStateListener(stateListener); + } + } +}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/image_fetcher/ImageFetcherFactoryTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/image_fetcher/ImageFetcherFactoryTest.java index 4c3aae3..3c115c1 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/image_fetcher/ImageFetcherFactoryTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/image_fetcher/ImageFetcherFactoryTest.java
@@ -39,24 +39,23 @@ public void testGetImageFetcher() { assertEquals(ImageFetcherConfig.NETWORK_ONLY, ImageFetcherFactory - .createImageFetcher(ImageFetcherConfig.NETWORK_ONLY, mImageFetcherBridge, - mReferencePool, InMemoryCachedImageFetcher.DEFAULT_CACHE_SIZE) + .createImageFetcher(ImageFetcherConfig.NETWORK_ONLY, mReferencePool, + mImageFetcherBridge) .getConfig()); assertEquals(ImageFetcherConfig.DISK_CACHE_ONLY, ImageFetcherFactory - .createImageFetcher(ImageFetcherConfig.DISK_CACHE_ONLY, mImageFetcherBridge, - mReferencePool, InMemoryCachedImageFetcher.DEFAULT_CACHE_SIZE) + .createImageFetcher(ImageFetcherConfig.DISK_CACHE_ONLY, mReferencePool, + mImageFetcherBridge) .getConfig()); assertEquals(ImageFetcherConfig.IN_MEMORY_ONLY, ImageFetcherFactory - .createImageFetcher(ImageFetcherConfig.IN_MEMORY_ONLY, mImageFetcherBridge, - mReferencePool, InMemoryCachedImageFetcher.DEFAULT_CACHE_SIZE) + .createImageFetcher(ImageFetcherConfig.IN_MEMORY_ONLY, mReferencePool, + mImageFetcherBridge) .getConfig()); assertEquals(ImageFetcherConfig.IN_MEMORY_WITH_DISK_CACHE, ImageFetcherFactory .createImageFetcher(ImageFetcherConfig.IN_MEMORY_WITH_DISK_CACHE, - mImageFetcherBridge, mReferencePool, - InMemoryCachedImageFetcher.DEFAULT_CACHE_SIZE) + mReferencePool, mImageFetcherBridge) .getConfig()); } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/image_fetcher/ImageFetcherTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/image_fetcher/ImageFetcherTest.java index 0c1c454..60be0f4 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/image_fetcher/ImageFetcherTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/image_fetcher/ImageFetcherTest.java
@@ -45,9 +45,6 @@ String url, String clientName, int width, int height, Callback<Bitmap> callback) {} @Override - public void clear() {} - - @Override public int getConfig() { return 0; }
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index 4bee008..95e222ec 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-75.0.3768.0_rc-r1-merged.afdo.bz2 \ No newline at end of file +chromeos-chrome-amd64-75.0.3769.0_rc-r1-merged.afdo.bz2 \ No newline at end of file
diff --git a/chrome/android/trichrome.gni b/chrome/android/trichrome.gni index c2b2ab3..3a74e606 100644 --- a/chrome/android/trichrome.gni +++ b/chrome/android/trichrome.gni
@@ -28,7 +28,8 @@ } trichrome_jinja_variables = [ - "min_sdk_version=28", + # TODO(torne): make minsdk=Q once we no longer build hacky P version + "min_sdk_version=$android_sdk_version", "target_sdk_version=$android_sdk_version", "trichrome_library=$trichrome_library_package", "trichrome_version=$trichrome_version_code",
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 9b4bf0f..c9cdb4a3 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -3405,6 +3405,9 @@ <message name="IDS_CROSTINI_INSTALLER_OFFLINE_ERROR" desc="Text shown in the Crostini installer dialog when there is no internet connection"> <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> is offline. Connect to the Internet and try again. </message> + <message name="IDS_CROSTINI_INSTALLER_INSUFFICIENT_DISK" desc="Text shown in the Crostini installer dialog when there is not enough free disk space to complete the installation"> + Install failed due to lack of storage space. At least <ph name="INSTALL_SIZE">$1<ex>1.3GB</ex></ph> of free space is required. To free up space, delete files from device storage. + </message> <message name="IDS_CROSTINI_INSTALLER_LOAD_TERMINA_ERROR" desc="Text shown in the Crostini installer dialog when the VM component fails to load"> Error downloading the virtual machine. Please try again. </message> @@ -3828,34 +3831,34 @@ Plugin VM </message> <message name="IDS_PLUGIN_VM_LAUNCHER_ENVIRONMENT_SETTING_TITLE" desc="Title of the PluginVm launcher, a dialog for launching PluginVm." translateable="false"> - Finishing <ph name="APP_NAME">PluginVm</ph> environment setting... + Finishing <ph name="APP_NAME">Plugin VM</ph> installation... </message> <message name="IDS_PLUGIN_VM_LAUNCHER_FINISHED_TITLE" desc="Title of the PluginVm launcher, a dialog for launching PluginVm." translateable="false"> - <ph name="APP_NAME">PluginVm</ph> environment setting complete + <ph name="APP_NAME">Plugin VM</ph> installation complete </message> <message name="IDS_PLUGIN_VM_LAUNCHER_ERROR_TITLE" desc="Title of the PluginVm launcher, a dialog for launching PluginVm." translateable="false"> - Error setting <ph name="APP_NAME">PluginVm</ph> environment + Error installing <ph name="APP_NAME">Plugin VM</ph> </message> <message name="IDS_PLUGIN_VM_LAUNCHER_START_DOWNLOADING_MESSAGE" desc="Message that informs user that PluginVm environment setting may take a while." translateable="false"> - This process may take a few minutes + This process may take a few minutes. </message> <message name="IDS_PLUGIN_VM_LAUNCHER_DOWNLOADING_MESSAGE" desc="Description of the current state of PluginVm environment setting." translateable="false"> - Downloading <ph name="APP_NAME">PluginVm</ph> image... + Downloading the virtual machine. </message> <message name="IDS_PLUGIN_VM_LAUNCHER_UNZIPPING_MESSAGE" desc="Description of the current state of PluginVm environment setting." translateable="false"> - Configuring <ph name="APP_NAME">PluginVm</ph> image... + Configuring the virtual machine. This process might take around 3 minutes. </message> <message name="IDS_PLUGIN_VM_LAUNCHER_REGISTERING_MESSAGE" desc="Description of the current state of PluginVm environment setting." translateable="false"> Putting on final touches... </message> <message name="IDS_PLUGIN_VM_LAUNCHER_FINISHED_MESSAGE" desc="Description of the current state of PluginVm environment setting." translateable="false"> - Set up was successfully completed. Click on the launch button to start using <ph name="APP_NAME">PluginVm</ph>. + Set up was successfully completed. Click on the launch button to start using <ph name="APP_NAME">Plugin VM</ph>. </message> <message name="IDS_PLUGIN_VM_LAUNCHER_ERROR_MESSAGE" desc="Description of the current state of PluginVm environment setting." translateable="false"> - The <ph name="APP_NAME">PluginVm</ph> environment didn't set. Please try again. + The <ph name="APP_NAME">Plugin VM</ph> installation failed. Please try again. </message> <message name="IDS_PLUGIN_VM_LAUNCHER_DOWNLOAD_PROGRESS_MESSAGE" desc="Text shown in the PluginVm launcher during downloading PluginVm image that shows download progress." translateable="false"> - <ph name="DOWNLOADED_SIZE">$1<ex>1.2 GB</ex></ph>/<ph name="DOWNLOAD_SIZE">$2<ex>3.4 GB</ex></ph> + <ph name="DOWNLOADED_SIZE">$1<ex>1.2</ex></ph>/<ph name="DOWNLOAD_SIZE">$2<ex>3.4 GB</ex></ph> </message> <message name="IDS_PLUGIN_VM_LAUNCHER_DOWNLOAD_PROGRESS_WITHOUT_DOWNLOAD_SIZE_MESSAGE" desc="Text shown in the PluginVm launcher during downloading PluginVm image that shows download progress." translateable="false"> <ph name="DOWNLOADED_SIZE">$1<ex>1.2 GB</ex></ph>
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index ff1680f..202d596 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -5317,10 +5317,6 @@ Stop plugin </message> - <message name="IDS_BROWSER_BLOATED_RENDERER_INFOBAR" desc="The text of the infobar notifying the user that the page ran out of memory"> - The web page was reloaded because it ran out of memory. - </message> - <!-- Passwords and Exceptions Dialog --> <message name="IDS_PASSWORDS_AUTO_SIGNIN_TITLE" desc="Title for 'Auto sign-in' checkbox in the password dialog"> Auto sign-in
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index be40d0f..c584d0c4a 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -283,6 +283,9 @@ <message name="IDS_SETTINGS_AUTOCLICK_REVERT_TO_LEFT_CLICK" desc="Description of a checkbox that gives the option to return to the default left click action after taking another action."> Revert to left click after action </message> + <message name="IDS_SETTINGS_AUTOCLICK_STABILIZE_CURSOR_POSITION" desc="Description of a checkbox that gives the option to turn on cursor movmeent stablization."> + Click position stabilization + </message> <message name="IDS_SETTINGS_AUTOCLICK_MOVEMENT_THRESHOLD_LABEL" desc="Label for a dropdown menu which that has options for how much mouse movement can occur before a new autoclick is initiated."> Movement threshold </message>
diff --git a/chrome/app/settings_strings_grdp/IDS_SETTINGS_AUTOCLICK_STABILIZE_CURSOR_POSITION.png.sha1 b/chrome/app/settings_strings_grdp/IDS_SETTINGS_AUTOCLICK_STABILIZE_CURSOR_POSITION.png.sha1 new file mode 100644 index 0000000..2c4b17f --- /dev/null +++ b/chrome/app/settings_strings_grdp/IDS_SETTINGS_AUTOCLICK_STABILIZE_CURSOR_POSITION.png.sha1
@@ -0,0 +1 @@ +a8ad2d0cbce9458976f183f481ce27e671ad1782 \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index be46d70d..87dbb7c 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2431,6 +2431,7 @@ "android/ntp/recent_tabs_page_prefs.cc", "android/ntp/recent_tabs_page_prefs.h", "android/ntp/suggestions_event_reporter_bridge.cc", + "android/omnibox/answers_image_bridge.cc", "android/omnibox/autocomplete_controller_android.cc", "android/omnibox/autocomplete_controller_android.h", "android/omnibox/omnibox_prerender.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 56681cc8..5f1b26f 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -3039,10 +3039,6 @@ flag_descriptions::kBundledConnectionHelpDescription, kOsAll, FEATURE_VALUE_TYPE(features::kBundledConnectionHelpFeature)}, - {"enable-signed-http-exchange", flag_descriptions::kSignedHTTPExchangeName, - flag_descriptions::kSignedHTTPExchangeDescription, kOsAll, - FEATURE_VALUE_TYPE(features::kSignedHTTPExchange)}, - #if defined(OS_CHROMEOS) {"enable-oobe-recommend-apps-screen", flag_descriptions::kEnableOobeRecommendAppsScreenName,
diff --git a/chrome/browser/android/omnibox/answers_image_bridge.cc b/chrome/browser/android/omnibox/answers_image_bridge.cc new file mode 100644 index 0000000..9ce2b252 --- /dev/null +++ b/chrome/browser/android/omnibox/answers_image_bridge.cc
@@ -0,0 +1,77 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" +#include "base/android/scoped_java_ref.h" +#include "base/bind.h" +#include "chrome/browser/bitmap_fetcher/bitmap_fetcher_service.h" +#include "chrome/browser/bitmap_fetcher/bitmap_fetcher_service_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_android.h" +#include "jni/AnswersImageFetcher_jni.h" +#include "net/traffic_annotation/network_traffic_annotation.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/gfx/android/java_bitmap.h" +#include "url/gurl.h" + +using base::android::JavaParamRef; +using base::android::ScopedJavaLocalRef; +using base::android::ConvertUTF8ToJavaString; + +namespace { + +class AnswersImageObserverAndroid : public BitmapFetcherService::Observer { + public: + explicit AnswersImageObserverAndroid(JNIEnv* env, + jobject java_answers_image_observer) { + java_answers_image_observer_.Reset(env, java_answers_image_observer); + } + + ~AnswersImageObserverAndroid() override {} + + // AnswersImageObserver: + void OnImageChanged(BitmapFetcherService::RequestId request_id, + const SkBitmap& answers_image) override { + DCHECK(!answers_image.empty()); + + JNIEnv* env = base::android::AttachCurrentThread(); + ScopedJavaLocalRef<jobject> java_bitmap = + gfx::ConvertToJavaBitmap(&answers_image); + Java_AnswersImageObserver_onAnswersImageChanged( + env, java_answers_image_observer_, java_bitmap); + } + + private: + base::android::ScopedJavaGlobalRef<jobject> java_answers_image_observer_; +}; + +} // namespace + +static void JNI_AnswersImageFetcher_CancelAnswersImageRequest( + JNIEnv* env, + const JavaParamRef<jobject>& java_profile, + jint java_request_id) { + Profile* profile = ProfileAndroid::FromProfileAndroid(java_profile); + DCHECK(profile); + BitmapFetcherService* bitmap_fetcher_service = + BitmapFetcherServiceFactory::GetForBrowserContext(profile); + bitmap_fetcher_service->CancelRequest(java_request_id); +} + +static int JNI_AnswersImageFetcher_RequestAnswersImage( + JNIEnv* env, + const JavaParamRef<jobject>& java_profile, + const JavaParamRef<jstring>& java_url, + const JavaParamRef<jobject>& java_callback) { + Profile* profile = ProfileAndroid::FromProfileAndroid(java_profile); + DCHECK(profile); + BitmapFetcherService* bitmap_fetcher_service = + BitmapFetcherServiceFactory::GetForBrowserContext(profile); + std::string url; + base::android::ConvertJavaStringToUTF8(env, java_url, &url); + return bitmap_fetcher_service->RequestImage( + GURL(url), new AnswersImageObserverAndroid(env, java_callback), + TRAFFIC_ANNOTATION_WITHOUT_PROTO("Omnibox answers image")); +}
diff --git a/chrome/browser/android/vr/BUILD.gn b/chrome/browser/android/vr/BUILD.gn index 6782eba..d748cc4 100644 --- a/chrome/browser/android/vr/BUILD.gn +++ b/chrome/browser/android/vr/BUILD.gn
@@ -246,6 +246,5 @@ "//testing/android/native_test:native_test_native_code", "//testing/gmock", "//testing/gtest:gtest", - "//ui/android:ui_java", # TODO: Remove once http://crbug.com/951419 is fixed! ] }
diff --git a/chrome/browser/autofill/manual_filling_controller_impl_unittest.cc b/chrome/browser/autofill/manual_filling_controller_impl_unittest.cc index abc97cb..c3037b4c 100644 --- a/chrome/browser/autofill/manual_filling_controller_impl_unittest.cc +++ b/chrome/browser/autofill/manual_filling_controller_impl_unittest.cc
@@ -53,7 +53,9 @@ const base::WeakPtr<password_manager::PasswordManagerDriver>&)); MOCK_METHOD0(OnGenerationElementLostFocus, void()); MOCK_METHOD0(OnGenerationRequested, void()); - MOCK_METHOD1(GeneratedPasswordAccepted, void(const base::string16&)); + MOCK_METHOD2(GeneratedPasswordAccepted, + void(const base::string16&, + base::WeakPtr<password_manager::PasswordManagerDriver>)); MOCK_METHOD0(GeneratedPasswordRejected, void()); MOCK_CONST_METHOD0(top_level_native_window, gfx::NativeWindow()); };
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index 0ee8e4e..7f71a6a 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc
@@ -89,6 +89,7 @@ #include "chrome/common/extensions/chrome_extensions_client.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" +#include "chrome/grit/chromium_strings.h" #include "chrome/installer/util/google_update_settings.h" #include "components/component_updater/component_updater_service.h" #include "components/component_updater/timer_update_scheduler.h" @@ -289,6 +290,12 @@ #if !defined(OS_CHROMEOS) message_center::MessageCenter::Initialize(); + // Set the system notification source display name ("Google Chrome" or + // "Chromium"). + if (message_center::MessageCenter::Get()) { + message_center::MessageCenter::Get()->SetSystemNotificationAppName( + l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); + } #endif system_notification_helper_ = std::make_unique<SystemNotificationHelper>();
diff --git a/chrome/browser/browsing_data/counters/sync_aware_counter_browsertest.cc b/chrome/browser/browsing_data/counters/sync_aware_counter_browsertest.cc index 72112d1..6f380e3 100644 --- a/chrome/browser/browsing_data/counters/sync_aware_counter_browsertest.cc +++ b/chrome/browser/browsing_data/counters/sync_aware_counter_browsertest.cc
@@ -118,31 +118,30 @@ EXPECT_TRUE(IsSyncEnabled()); // We stop syncing autofill in particular. This restarts the counter. - syncer::ModelTypeSet everything_except_autofill = - syncer::UserSelectableTypes(); - everything_except_autofill.Remove(syncer::AUTOFILL); + syncer::UserSelectableTypeSet everything_except_autofill = + syncer::UserSelectableTypeSet::All(); + everything_except_autofill.Remove(syncer::UserSelectableType::kAutofill); auto sync_blocker = sync_service->GetSetupInProgressHandle(); - sync_service->GetUserSettings()->SetChosenDataTypes( + sync_service->GetUserSettings()->SetSelectedTypes( /*sync_everything=*/false, everything_except_autofill); - ASSERT_FALSE(sync_service->GetUserSettings()->GetChosenDataTypes().Has( - syncer::AUTOFILL)); + ASSERT_FALSE(sync_service->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kAutofill)); sync_blocker.reset(); WaitForCounting(); ASSERT_FALSE(sync_service->GetActiveDataTypes().Has(syncer::AUTOFILL)); EXPECT_FALSE(IsSyncEnabled()); // If autofill sync is not affected, the counter is not restarted. - syncer::ModelTypeSet only_history(syncer::TYPED_URLS); sync_blocker = sync_service->GetSetupInProgressHandle(); - sync_service->GetUserSettings()->SetChosenDataTypes(/*sync_everything=*/false, - only_history); + sync_service->GetUserSettings()->SetSelectedTypes( + /*sync_everything=*/false, {syncer::UserSelectableType::kHistory}); sync_blocker.reset(); EXPECT_FALSE(CountingFinishedSinceLastAsked()); // We start syncing autofill again. This restarts the counter. sync_blocker = sync_service->GetSetupInProgressHandle(); - sync_service->GetUserSettings()->SetChosenDataTypes( - /*sync_everything=*/false, syncer::UserSelectableTypes()); + sync_service->GetUserSettings()->SetSelectedTypes( + /*sync_everything=*/false, syncer::UserSelectableTypeSet::All()); sync_blocker.reset(); WaitForCounting(); EXPECT_TRUE(IsSyncEnabled()); @@ -176,40 +175,41 @@ // syncing passwords, and this should restart the counter. ASSERT_TRUE(SetupSync()); ASSERT_TRUE(sync_service->IsSyncFeatureActive()); - ASSERT_TRUE(sync_service->GetUserSettings()->GetChosenDataTypes().Has( - syncer::PASSWORDS)); + ASSERT_TRUE(sync_service->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kPasswords)); WaitForCounting(); EXPECT_TRUE(IsSyncEnabled()); // We stop syncing passwords in particular. This restarts the counter. - syncer::ModelTypeSet everything_except_passwords = - syncer::UserSelectableTypes(); - everything_except_passwords.Remove(syncer::PASSWORDS); + syncer::UserSelectableTypeSet everything_except_passwords = + syncer::UserSelectableTypeSet::All(); + everything_except_passwords.Remove(syncer::UserSelectableType::kPasswords); auto sync_blocker = sync_service->GetSetupInProgressHandle(); - sync_service->GetUserSettings()->SetChosenDataTypes( + sync_service->GetUserSettings()->SetSelectedTypes( /*sync_everything=*/false, everything_except_passwords); - ASSERT_FALSE(sync_service->GetUserSettings()->GetChosenDataTypes().Has( - syncer::PASSWORDS)); + ASSERT_FALSE(sync_service->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kPasswords)); sync_blocker.reset(); WaitForCounting(); - ASSERT_FALSE(sync_service->GetUserSettings()->GetChosenDataTypes().Has( - syncer::PASSWORDS)); + ASSERT_FALSE(sync_service->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kPasswords)); EXPECT_FALSE(IsSyncEnabled()); // If password sync is not affected, the counter is not restarted. - syncer::ModelTypeSet only_history(syncer::TYPED_URLS); - sync_service->GetUserSettings()->SetChosenDataTypes(/*sync_everything=*/false, - only_history); + syncer::UserSelectableTypeSet only_history( + syncer::UserSelectableType::kHistory); + sync_service->GetUserSettings()->SetSelectedTypes(/*sync_everything=*/false, + only_history); sync_blocker = sync_service->GetSetupInProgressHandle(); - sync_service->GetUserSettings()->SetChosenDataTypes(/*sync_everything=*/false, - only_history); + sync_service->GetUserSettings()->SetSelectedTypes(/*sync_everything=*/false, + only_history); sync_blocker.reset(); EXPECT_FALSE(CountingFinishedSinceLastAsked()); // We start syncing passwords again. This restarts the counter. sync_blocker = sync_service->GetSetupInProgressHandle(); - sync_service->GetUserSettings()->SetChosenDataTypes( - /*sync_everything=*/false, syncer::UserSelectableTypes()); + sync_service->GetUserSettings()->SetSelectedTypes( + /*sync_everything=*/false, syncer::UserSelectableTypeSet::All()); sync_blocker.reset(); WaitForCounting(); EXPECT_TRUE(IsSyncEnabled()); @@ -246,8 +246,8 @@ // syncing history deletion, and this should restart the counter. ASSERT_TRUE(SetupSync()); ASSERT_TRUE(sync_service->IsSyncFeatureActive()); - ASSERT_TRUE(sync_service->GetUserSettings()->GetChosenDataTypes().Has( - syncer::TYPED_URLS)); + ASSERT_TRUE(sync_service->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kHistory)); ASSERT_TRUE(sync_service->GetActiveDataTypes().Has( syncer::HISTORY_DELETE_DIRECTIVES)); @@ -255,41 +255,43 @@ EXPECT_TRUE(IsSyncEnabled()); // We stop syncing history deletion in particular. This restarts the counter. - syncer::ModelTypeSet everything_except_history = - syncer::UserSelectableTypes(); - everything_except_history.Remove(syncer::TYPED_URLS); + syncer::UserSelectableTypeSet everything_except_history = + syncer::UserSelectableTypeSet::All(); + everything_except_history.Remove(syncer::UserSelectableType::kHistory); auto sync_blocker = sync_service->GetSetupInProgressHandle(); - sync_service->GetUserSettings()->SetChosenDataTypes( + sync_service->GetUserSettings()->SetSelectedTypes( /*sync_everything=*/false, everything_except_history); sync_blocker.reset(); WaitForCounting(); EXPECT_FALSE(IsSyncEnabled()); // If the history deletion sync is not affected, the counter is not restarted. - syncer::ModelTypeSet only_passwords(syncer::PASSWORDS); - sync_service->GetUserSettings()->SetChosenDataTypes(/*sync_everything=*/false, - only_passwords); + syncer::UserSelectableTypeSet only_passwords( + syncer::UserSelectableType::kPasswords); + sync_service->GetUserSettings()->SetSelectedTypes(/*sync_everything=*/false, + only_passwords); sync_blocker = sync_service->GetSetupInProgressHandle(); - sync_service->GetUserSettings()->SetChosenDataTypes(/*sync_everything=*/false, - only_passwords); + sync_service->GetUserSettings()->SetSelectedTypes(/*sync_everything=*/false, + only_passwords); sync_blocker.reset(); EXPECT_FALSE(counter.HasTrackedTasks()); EXPECT_FALSE(CountingFinishedSinceLastAsked()); // Same in this case. - syncer::ModelTypeSet autofill_and_passwords(syncer::AUTOFILL, - syncer::PASSWORDS); + syncer::UserSelectableTypeSet autofill_and_passwords( + syncer::UserSelectableType::kAutofill, + syncer::UserSelectableType::kPasswords); sync_blocker = sync_service->GetSetupInProgressHandle(); - sync_service->GetUserSettings()->SetChosenDataTypes(/*sync_everything=*/false, - autofill_and_passwords); + sync_service->GetUserSettings()->SetSelectedTypes(/*sync_everything=*/false, + autofill_and_passwords); sync_blocker.reset(); EXPECT_FALSE(counter.HasTrackedTasks()); EXPECT_FALSE(CountingFinishedSinceLastAsked()); // We start syncing history deletion again. This restarts the counter. sync_blocker = sync_service->GetSetupInProgressHandle(); - sync_service->GetUserSettings()->SetChosenDataTypes( - /*sync_everything=*/false, syncer::UserSelectableTypes()); + sync_service->GetUserSettings()->SetSelectedTypes( + /*sync_everything=*/false, syncer::UserSelectableTypeSet::All()); sync_blocker.reset(); WaitForCounting(); EXPECT_TRUE(IsSyncEnabled());
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 3d1a4c9..a5a4abc 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -2690,7 +2690,7 @@ } #endif -QuotaPermissionContext* +scoped_refptr<content::QuotaPermissionContext> ChromeContentBrowserClient::CreateQuotaPermissionContext() { return new ChromeQuotaPermissionContext(); }
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index e8b6c8c..7895949 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -280,8 +280,8 @@ #if defined(OS_ANDROID) bool ShouldUseGmsCoreGeolocationProvider() override; #endif - - content::QuotaPermissionContext* CreateQuotaPermissionContext() override; + scoped_refptr<content::QuotaPermissionContext> CreateQuotaPermissionContext() + override; void GetQuotaSettings( content::BrowserContext* context, content::StoragePartition* partition,
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc b/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc index 1f6b6c67..1865851 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_app_manager_browsertest.cc
@@ -34,8 +34,10 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chromeos/constants/chromeos_switches.h" #include "chromeos/settings/cros_settings_names.h" +#include "components/crx_file/crx_verifier.h" #include "components/prefs/scoped_user_pref_update.h" #include "content/public/test/test_utils.h" +#include "extensions/browser/sandboxed_unpacker.h" #include "extensions/common/extension.h" #include "net/base/host_port_pair.h" #include "net/dns/mock_host_resolver.h" @@ -228,7 +230,10 @@ class KioskAppManagerTest : public InProcessBrowserTest { public: - KioskAppManagerTest() : settings_helper_(false), fake_cws_(new FakeCWS()) {} + KioskAppManagerTest() + : settings_helper_(false), + fake_cws_(new FakeCWS()), + verifier_format_override_(crx_file::VerifierFormat::CRX3) {} ~KioskAppManagerTest() override {} // InProcessBrowserTest overrides: @@ -462,6 +467,8 @@ private: base::ScopedTempDir temp_dir_; std::unique_ptr<FakeCWS> fake_cws_; + extensions::SandboxedUnpacker::ScopedVerifierFormatOverrideForTest + verifier_format_override_; DISALLOW_COPY_AND_ASSIGN(KioskAppManagerTest); };
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler.cc b/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler.cc index a6c29d9..02dc656 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler.cc
@@ -146,17 +146,10 @@ ArcSelectFilesHandler::ArcSelectFilesHandler(content::BrowserContext* context) : profile_(Profile::FromBrowserContext(context)) { - select_file_dialog_ = ui::SelectFileDialog::Create(this, nullptr); - dialog_script_executor_ = - base::MakeRefCounted<SelectFileDialogScriptExecutor>( - select_file_dialog_.get()); + dialog_holder_ = std::make_unique<SelectFileDialogHolder>(this); } -ArcSelectFilesHandler::~ArcSelectFilesHandler() { - // select_file_dialog_ can be nullptr only in unit tests. - if (select_file_dialog_.get()) - select_file_dialog_->ListenerDestroyed(); -} +ArcSelectFilesHandler::~ArcSelectFilesHandler() = default; void ArcSelectFilesHandler::SelectFiles( const mojom::SelectFilesRequestPtr& request, @@ -178,14 +171,7 @@ BuildFileTypeInfo(request, &file_type_info); base::FilePath default_path = GetInitialFilePath(request); - select_file_dialog_->SelectFile( - dialog_type, - /*title=*/base::string16(), - /*default_path=*/default_path, &file_type_info, - /*file_type_index=*/0, - /*default_extension=*/base::FilePath::StringType(), - /*owning_window=*/nullptr, - /*params=*/nullptr); + dialog_holder_->SelectFile(dialog_type, default_path, &file_type_info); } void ArcSelectFilesHandler::FileSelected(const base::FilePath& path, @@ -254,7 +240,7 @@ base::StringPrintf(kScriptClickFile, quotedClickTargetName.c_str()); break; } - dialog_script_executor_->ExecuteJavaScript(script, {}); + dialog_holder_->ExecuteJavaScript(script, {}); std::move(callback).Run(); } @@ -263,33 +249,45 @@ mojom::FileSystemHost::GetFileSelectorElementsCallback callback) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - dialog_script_executor_->ExecuteJavaScript( + dialog_holder_->ExecuteJavaScript( kScriptGetElements, base::BindOnce(&OnGetElementsScriptResults, std::move(callback))); } -void ArcSelectFilesHandler::SetSelectFileDialogForTesting( - ui::SelectFileDialog* dialog) { - select_file_dialog_ = dialog; +void ArcSelectFilesHandler::SetDialogHolderForTesting( + std::unique_ptr<SelectFileDialogHolder> dialog_holder) { + dialog_holder_ = std::move(dialog_holder); } -void ArcSelectFilesHandler::SetDialogScriptExecutorForTesting( - SelectFileDialogScriptExecutor* dialog_script_executor) { - dialog_script_executor_ = dialog_script_executor; +SelectFileDialogHolder::SelectFileDialogHolder( + ui::SelectFileDialog::Listener* listener) { + select_file_dialog_ = static_cast<SelectFileDialogExtension*>( + ui::SelectFileDialog::Create(listener, nullptr).get()); } -SelectFileDialogScriptExecutor::SelectFileDialogScriptExecutor( - ui::SelectFileDialog* dialog) - : select_file_dialog_(dialog) {} +SelectFileDialogHolder::~SelectFileDialogHolder() { + // select_file_dialog_ can be nullptr only in unit tests. + if (select_file_dialog_.get()) + select_file_dialog_->ListenerDestroyed(); +} -SelectFileDialogScriptExecutor::~SelectFileDialogScriptExecutor() {} +void SelectFileDialogHolder::SelectFile( + ui::SelectFileDialog::Type type, + const base::FilePath& default_path, + const ui::SelectFileDialog::FileTypeInfo* file_types) { + select_file_dialog_->SelectFile( + type, + /*title=*/base::string16(), default_path, file_types, + /*file_type_index=*/0, + /*default_extension=*/base::FilePath::StringType(), + /*owning_window=*/nullptr, + /*params=*/nullptr); +} -void SelectFileDialogScriptExecutor::ExecuteJavaScript( +void SelectFileDialogHolder::ExecuteJavaScript( const std::string& script, content::RenderFrameHost::JavaScriptResultCallback callback) { - content::RenderViewHost* view_host = - static_cast<SelectFileDialogExtension*>(select_file_dialog_) - ->GetRenderViewHost(); + content::RenderViewHost* view_host = select_file_dialog_->GetRenderViewHost(); content::RenderFrameHost* frame_host = view_host ? view_host->GetMainFrame() : nullptr;
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler.h b/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler.h index 4e0aa91..513daad 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler.h +++ b/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler.h
@@ -10,6 +10,7 @@ #include "base/files/file_path.h" #include "base/macros.h" #include "base/memory/scoped_refptr.h" +#include "chrome/browser/ui/views/select_file_dialog_extension.h" #include "components/arc/common/file_system.mojom.h" #include "content/public/browser/render_frame_host.h" #include "ui/shell_dialogs/select_file_dialog.h" @@ -22,7 +23,7 @@ namespace arc { -class SelectFileDialogScriptExecutor; +class SelectFileDialogHolder; // Exposed for testing. extern const char kScriptClickOk[]; @@ -54,43 +55,41 @@ void* params) override; void FileSelectionCanceled(void* params) override; - void SetSelectFileDialogForTesting(ui::SelectFileDialog* dialog); - void SetDialogScriptExecutorForTesting( - SelectFileDialogScriptExecutor* dialog_script_executor); - private: friend class ArcSelectFilesHandlerTest; void FilesSelectedInternal(const std::vector<base::FilePath>& files, void* params); + void SetDialogHolderForTesting( + std::unique_ptr<SelectFileDialogHolder> dialog_holder); + Profile* const profile_; mojom::FileSystemHost::SelectFilesCallback callback_; - scoped_refptr<ui::SelectFileDialog> select_file_dialog_; - scoped_refptr<SelectFileDialogScriptExecutor> dialog_script_executor_; + std::unique_ptr<SelectFileDialogHolder> dialog_holder_; DISALLOW_COPY_AND_ASSIGN(ArcSelectFilesHandler); }; -// Helper class for executing JavaScript on a given SelectFileDialog. -class SelectFileDialogScriptExecutor - : public base::RefCounted<SelectFileDialogScriptExecutor> { +// Wrapper for SelectFileDialogExtension. +// Since it is not easy to create a mock class for SelectFileDialogExtension, +// this class is replaced with a mock class instead in unit tests. +class SelectFileDialogHolder { public: - explicit SelectFileDialogScriptExecutor( - ui::SelectFileDialog* select_file_dialog); + explicit SelectFileDialogHolder(ui::SelectFileDialog::Listener* listener); + virtual ~SelectFileDialogHolder(); + + virtual void SelectFile(ui::SelectFileDialog::Type type, + const base::FilePath& default_path, + const ui::SelectFileDialog::FileTypeInfo* file_types); virtual void ExecuteJavaScript( const std::string& script, content::RenderFrameHost::JavaScriptResultCallback callback); - protected: - friend class base::RefCounted<SelectFileDialogScriptExecutor>; - - virtual ~SelectFileDialogScriptExecutor(); - private: - ui::SelectFileDialog* select_file_dialog_; + scoped_refptr<SelectFileDialogExtension> select_file_dialog_; }; } // namespace arc
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler_unittest.cc index 34a1533..c0062b5 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler_unittest.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_select_files_handler_unittest.cc
@@ -64,47 +64,17 @@ return element; } -class MockSelectFileDialog : public SelectFileDialog { +class MockSelectFileDialogHolder : public SelectFileDialogHolder { public: - MockSelectFileDialog(SelectFileDialog::Listener* listener, - std::unique_ptr<ui::SelectFilePolicy> policy) - : SelectFileDialog(listener, std::move(policy)) {} - MOCK_METHOD8(SelectFile, - void(SelectFileDialog::Type, - const base::string16&, - const base::FilePath&, - const FileTypeInfo*, - int, - const base::FilePath::StringType&, - gfx::NativeWindow, - void*)); - MOCK_METHOD8(SelectFileImpl, - void(SelectFileDialog::Type, - const base::string16&, - const base::FilePath&, - const FileTypeInfo*, - int, - const base::FilePath::StringType&, - gfx::NativeWindow, - void*)); - MOCK_METHOD0(HasMultipleFileTypeChoicesImpl, bool()); - MOCK_METHOD0(ListenerDestroyed, void()); - MOCK_CONST_METHOD1(IsRunning, bool(gfx::NativeWindow)); - - protected: - ~MockSelectFileDialog() override = default; -}; - -class MockSelectFileDialogScriptExecutor - : public SelectFileDialogScriptExecutor { - public: - explicit MockSelectFileDialogScriptExecutor(ui::SelectFileDialog* dialog) - : SelectFileDialogScriptExecutor(dialog) {} + explicit MockSelectFileDialogHolder(ui::SelectFileDialog::Listener* listener) + : SelectFileDialogHolder(listener) {} + ~MockSelectFileDialogHolder() override = default; + MOCK_METHOD3(SelectFile, + void(ui::SelectFileDialog::Type type, + const base::FilePath& default_path, + const ui::SelectFileDialog::FileTypeInfo* file_types)); MOCK_METHOD2(ExecuteJavaScript, void(const std::string&, JavaScriptResultCallback)); - - protected: - ~MockSelectFileDialogScriptExecutor() override = default; }; } // namespace @@ -124,15 +94,11 @@ arc_select_files_handler_ = std::make_unique<ArcSelectFilesHandler>(profile); - mock_dialog_ = new MockSelectFileDialog( - arc_select_files_handler_.get(), - std::make_unique<ChromeSelectFilePolicy>(nullptr)); - arc_select_files_handler_->SetSelectFileDialogForTesting( - mock_dialog_.get()); - - mock_script_executor_ = new MockSelectFileDialogScriptExecutor(nullptr); - arc_select_files_handler_->SetDialogScriptExecutorForTesting( - mock_script_executor_.get()); + std::unique_ptr<MockSelectFileDialogHolder> mock_dialog_holder = + std::make_unique<MockSelectFileDialogHolder>(nullptr); + mock_dialog_holder_ = mock_dialog_holder.get(); + arc_select_files_handler_->SetDialogHolderForTesting( + std::move(mock_dialog_holder)); } void TearDown() override { @@ -149,13 +115,11 @@ request->action_type = request_action_type; request->allow_multiple = request_allow_multiple; - EXPECT_CALL(*mock_dialog_, - SelectFileImpl(expected_dialog_type, _, _, _, _, _, _, _)) + EXPECT_CALL(*mock_dialog_holder_, SelectFile(expected_dialog_type, _, _)) .Times(1); SelectFilesCallback callback; arc_select_files_handler_->SelectFiles(request, std::move(callback)); - testing::Mock::VerifyAndClearExpectations(mock_dialog_.get()); } void CallOnFileSelectorEventAndCheckScript( @@ -167,7 +131,7 @@ event->click_target = mojom::FileSelectorElement::New(); event->click_target->name = target_name; - EXPECT_CALL(*mock_script_executor_, ExecuteJavaScript(expected_script, _)) + EXPECT_CALL(*mock_dialog_holder_, ExecuteJavaScript(expected_script, _)) .Times(1); base::MockCallback<mojom::FileSystemHost::OnFileSelectorEventCallback> @@ -176,14 +140,12 @@ arc_select_files_handler_->OnFileSelectorEvent(std::move(event), callback.Get()); - testing::Mock::VerifyAndClearExpectations(mock_script_executor_.get()); } content::TestBrowserThreadBundle thread_bundle_; std::unique_ptr<TestingProfileManager> profile_manager_; std::unique_ptr<ArcSelectFilesHandler> arc_select_files_handler_; - scoped_refptr<MockSelectFileDialog> mock_dialog_; - scoped_refptr<MockSelectFileDialogScriptExecutor> mock_script_executor_; + MockSelectFileDialogHolder* mock_dialog_holder_; }; TEST_F(ArcSelectFilesHandlerTest, SelectFiles_DialogType) { @@ -215,11 +177,10 @@ extensions.push_back("txt"); expected_file_type_info.extensions.push_back(extensions); - EXPECT_CALL(*mock_dialog_, - SelectFileImpl(_, _, _, - testing::Pointee( - FileTypeInfoMatcher(expected_file_type_info)), - _, _, _, _)) + EXPECT_CALL( + *mock_dialog_holder_, + SelectFile( + _, _, testing::Pointee(FileTypeInfoMatcher(expected_file_type_info)))) .Times(1); base::MockCallback<SelectFilesCallback> callback; @@ -237,9 +198,8 @@ base::FilePath expected_file_path = base::FilePath( "/special/arc-documents-provider/testing.provider/doc:root"); - EXPECT_CALL( - *mock_dialog_, - SelectFileImpl(_, _, FilePathMatcher(expected_file_path), _, _, _, _, _)) + EXPECT_CALL(*mock_dialog_holder_, + SelectFile(_, FilePathMatcher(expected_file_path), _)) .Times(1); base::MockCallback<SelectFilesCallback> callback; @@ -280,7 +240,7 @@ } TEST_F(ArcSelectFilesHandlerTest, GetFileSelectorElements) { - EXPECT_CALL(*mock_script_executor_, ExecuteJavaScript(kScriptGetElements, _)) + EXPECT_CALL(*mock_dialog_holder_, ExecuteJavaScript(kScriptGetElements, _)) .WillOnce(testing::Invoke( [](const std::string&, JavaScriptResultCallback callback) { std::move(callback).Run(
diff --git a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.cc b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.cc index 2cd8d9bc..e430278 100644 --- a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.cc +++ b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service.cc
@@ -205,6 +205,10 @@ std::unique_ptr<ChromeZoomLevelPrefs::DefaultZoomLevelSubscription> default_zoom_level_subscription_; + // Name of the default network. Used to keep track of whether the default + // network has changed. + std::string default_network_name_; + DISALLOW_COPY_AND_ASSIGN(ArcSettingsServiceImpl); }; @@ -277,8 +281,17 @@ // kProxy pref has more priority than the default network update. // If a default network is changed to the network with ONC policy with proxy // settings, it should be translated here. - if (network && !IsPrefProxyConfigApplied()) - SyncProxySettings(); + if (!network || IsPrefProxyConfigApplied()) + return; + + // This function is called when the default network changes or when any of its + // properties change. Only trigger a proxy settings sync to ARC when the + // default network changes. + if (default_network_name_ == network->name()) + return; + default_network_name_ = network->name(); + + SyncProxySettings(); } bool ArcSettingsServiceImpl::IsPrefProxyConfigApplied() const {
diff --git a/chrome/browser/chromeos/crostini/crostini_manager.cc b/chrome/browser/chromeos/crostini/crostini_manager.cc index 72bdbaa..8c2f090 100644 --- a/chrome/browser/chromeos/crostini/crostini_manager.cc +++ b/chrome/browser/chromeos/crostini/crostini_manager.cc
@@ -65,8 +65,6 @@ namespace crostini { namespace { - -constexpr int64_t kMinimumDiskSize = 1ll * 1024 * 1024 * 1024; // 1 GiB constexpr base::FilePath::CharType kHomeDirectory[] = FILE_PATH_LITERAL("/home"); const char kSeparator[] = "--"; @@ -261,18 +259,6 @@ } int64_t disk_size_available = (free_disk_bytes * 9) / 10; - // If there's no existing disk image, need enough space to create one. - if (disk_space_taken == 0) { - // Don't enforce minimum disk size on dev box or trybots because - // base::SysInfo::AmountOfFreeDiskSpace returns zero in testing. - if (disk_size_available < kMinimumDiskSize && - base::SysInfo::IsRunningOnChromeOS()) { - LOG(ERROR) << "Insufficient disk available. Need to free " - << kMinimumDiskSize - disk_size_available << " bytes"; - FinishRestart(CrostiniResult::INSUFFICIENT_DISK); - return; - } - } // If we have an already existing disk, CreateDiskImage will just return its // path so we can pass it to StartTerminaVm. crostini_manager_->CreateDiskImage(
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc index 1a65f260..bc5b9ce7 100644 --- a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc +++ b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
@@ -292,10 +292,10 @@ } if (sync_service->GetUserSettings()->IsFirstSetupComplete()) { - // Sync is set up. Report whether the user has chosen to sync themes. + // Sync is set up. Report whether the user has selected to sync themes. dict->SetBoolean(kSyncThemes, - sync_service->GetUserSettings()->GetChosenDataTypes().Has( - syncer::THEMES)); + sync_service->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kThemes)); Respond(OneArgument(std::move(dict))); return; }
diff --git a/chrome/browser/chromeos/file_manager/file_tasks_notifier.cc b/chrome/browser/chromeos/file_manager/file_tasks_notifier.cc index c05d66a..61a9d57 100644 --- a/chrome/browser/chromeos/file_manager/file_tasks_notifier.cc +++ b/chrome/browser/chromeos/file_manager/file_tasks_notifier.cc
@@ -4,11 +4,24 @@ #include "chrome/browser/chromeos/file_manager/file_tasks_notifier.h" +#include <memory> +#include <utility> + +#include "base/barrier_closure.h" #include "base/callback.h" +#include "base/files/file_util.h" +#include "base/task/post_task.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "chrome/browser/chromeos/drive/drive_integration_service.h" #include "chrome/browser/chromeos/file_manager/file_tasks_notifier_factory.h" #include "chrome/browser/chromeos/file_manager/file_tasks_observer.h" #include "chrome/browser/profiles/profile.h" #include "components/download/public/common/download_item.h" +#include "content/public/browser/network_service_instance.h" +#include "mojo/public/cpp/bindings/callback_helpers.h" +#include "services/network/public/cpp/network_connection_tracker.h" +#include "storage/browser/fileapi/external_mount_points.h" +#include "storage/browser/fileapi/file_system_context.h" #include "storage/browser/fileapi/file_system_url.h" #include "storage/common/fileapi/file_system_types.h" #include "ui/shell_dialogs/selected_file_info.h" @@ -28,8 +41,21 @@ } } +void ReturnQueryResults( + std::unique_ptr<std::vector<FileTasksNotifier::FileAvailability>> results, + base::OnceCallback<void(std::vector<FileTasksNotifier::FileAvailability>)> + callback) { + std::move(callback).Run(std::move(*results)); +} + } // namespace +struct FileTasksNotifier::PendingFileAvailabilityTask { + storage::FileSystemURL url; + FileTasksNotifier::FileAvailability* output; + base::OnceClosure done; +}; + FileTasksNotifier::FileTasksNotifier(Profile* profile) : profile_(profile), download_notifier_(content::BrowserContext::GetDownloadManager(profile_), @@ -50,6 +76,45 @@ observers_.RemoveObserver(observer); } +void FileTasksNotifier::QueryFileAvailability( + const std::vector<base::FilePath>& paths, + base::OnceCallback<void(std::vector<FileAvailability>)> callback) { + const auto* mount_points = storage::ExternalMountPoints::GetSystemInstance(); + std::vector<FileAvailability> results(paths.size(), + FileAvailability::kUnknown); + + std::vector<PendingFileAvailabilityTask> tasks; + for (size_t i = 0; i < paths.size(); ++i) { + base::FilePath virtual_path; + if (!mount_points->GetVirtualPath(paths[i], &virtual_path)) { + continue; + } + auto url = mount_points->CreateCrackedFileSystemURL( + url::Origin(), storage::kFileSystemTypeExternal, virtual_path); + if (!url.is_valid() || !IsSupportedFileSystemType(url.type())) { + results[i] = FileAvailability::kGone; + continue; + } + tasks.push_back({url, &results[i]}); + } + if (tasks.empty()) { + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), std::move(results))); + return; + } + + auto results_owner = std::make_unique<std::vector<FileAvailability>>(); + std::swap(results, *results_owner); + auto closure = base::BarrierClosure( + tasks.size(), + base::BindOnce(&ReturnQueryResults, std::move(results_owner), + std::move(callback))); + for (auto& task : tasks) { + task.done = closure; + GetFileAvailability(std::move(task)); + } +} + void FileTasksNotifier::OnDownloadUpdated(content::DownloadManager* manager, download::DownloadItem* item) { if (item->IsTransient() || @@ -103,5 +168,83 @@ } } +void FileTasksNotifier::GetFileAvailability(PendingFileAvailabilityTask task) { + if (task.url.type() != storage::kFileSystemTypeDriveFs) { + base::FilePath path = std::move(task.url.path()); + base::PostTaskWithTraitsAndReplyWithResult( + FROM_HERE, {base::MayBlock()}, + base::BindOnce(&base::PathExists, std::move(path)), + base::BindOnce(&FileTasksNotifier::ForwardQueryResult, + std::move(task))); + return; + } + if (!GetDriveFsInterface()) { + *task.output = FileTasksNotifier::FileAvailability::kUnknown; + base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, + std::move(task.done)); + return; + } + base::FilePath drive_path; + if (!GetRelativeDrivePath(task.url.path(), &drive_path)) { + *task.output = FileTasksNotifier::FileAvailability::kGone; + base::SequencedTaskRunnerHandle::Get()->PostTask(FROM_HERE, + std::move(task.done)); + return; + } + GetDriveFsInterface()->GetMetadata( + drive_path, + mojo::WrapCallbackWithDefaultInvokeIfNotRun( + base::BindOnce(&FileTasksNotifier::ForwardDriveFsQueryResult, + std::move(task), IsOffline()), + drive::FILE_ERROR_SERVICE_UNAVAILABLE, nullptr)); +} + +// static +void FileTasksNotifier::ForwardQueryResult(PendingFileAvailabilityTask task, + bool exists) { + *task.output = exists ? FileTasksNotifier::FileAvailability::kOk + : FileTasksNotifier::FileAvailability::kGone; + std::move(task.done).Run(); +} + +// static +void FileTasksNotifier::ForwardDriveFsQueryResult( + PendingFileAvailabilityTask task, + bool is_offline, + drive::FileError error, + drivefs::mojom::FileMetadataPtr metadata) { + if (error == drive::FILE_ERROR_NOT_FOUND) { + *task.output = FileTasksNotifier::FileAvailability::kGone; + } else if (error != drive::FILE_ERROR_OK) { + *task.output = FileTasksNotifier::FileAvailability::kUnknown; + } else { + *task.output = + metadata->available_offline || !is_offline + ? FileTasksNotifier::FileAvailability::kOk + : FileTasksNotifier::FileAvailability::kTemporarilyUnavailable; + } + std::move(task.done).Run(); +} + +drivefs::mojom::DriveFs* FileTasksNotifier::GetDriveFsInterface() { + drive::DriveIntegrationService* integration_service = + drive::DriveIntegrationServiceFactory::FindForProfile(profile_); + if (!integration_service || !integration_service->IsMounted()) { + return nullptr; + } + return integration_service->GetDriveFsInterface(); +} + +bool FileTasksNotifier::GetRelativeDrivePath( + const base::FilePath& path, + base::FilePath* drive_relative_path) { + return drive::DriveIntegrationServiceFactory::FindForProfile(profile_) + ->GetRelativeDrivePath(path, drive_relative_path); +} + +bool FileTasksNotifier::IsOffline() { + return content::GetNetworkConnectionTracker()->IsOffline(); +} + } // namespace file_tasks } // namespace file_manager
diff --git a/chrome/browser/chromeos/file_manager/file_tasks_notifier.h b/chrome/browser/chromeos/file_manager/file_tasks_notifier.h index 8a9b7c3..93b5ea0 100644 --- a/chrome/browser/chromeos/file_manager/file_tasks_notifier.h +++ b/chrome/browser/chromeos/file_manager/file_tasks_notifier.h
@@ -10,7 +10,9 @@ #include "base/callback_forward.h" #include "base/observer_list.h" #include "chrome/browser/chromeos/file_manager/file_tasks_observer.h" +#include "chromeos/components/drivefs/mojom/drivefs.mojom.h" #include "components/download/content/public/all_download_item_notifier.h" +#include "components/drive/file_errors.h" #include "components/keyed_service/core/keyed_service.h" class Profile; @@ -56,6 +58,10 @@ void AddObserver(FileTasksObserver*); void RemoveObserver(FileTasksObserver*); + void QueryFileAvailability( + const std::vector<base::FilePath>&, + base::OnceCallback<void(std::vector<FileAvailability>)>); + void NotifyFileTasks(const std::vector<storage::FileSystemURL>& file_urls); void NotifyFileDialogSelection(const std::vector<ui::SelectedFileInfo>& files, @@ -66,9 +72,25 @@ download::DownloadItem* item) override; private: + struct PendingFileAvailabilityTask; void NotifyObservers(const std::vector<base::FilePath>& paths, FileTasksObserver::OpenType open_type); + void GetFileAvailability(PendingFileAvailabilityTask task); + static void ForwardQueryResult(PendingFileAvailabilityTask task, bool exists); + + static void ForwardDriveFsQueryResult( + PendingFileAvailabilityTask task, + bool is_offline, + drive::FileError error, + drivefs::mojom::FileMetadataPtr metadata); + + // Virtual for stubbing out in tests. + virtual drivefs::mojom::DriveFs* GetDriveFsInterface(); + virtual bool GetRelativeDrivePath(const base::FilePath& path, + base::FilePath* drive_relative_path); + virtual bool IsOffline(); + Profile* const profile_; download::AllDownloadItemNotifier download_notifier_; base::ObserverList<FileTasksObserver> observers_;
diff --git a/chrome/browser/chromeos/file_manager/file_tasks_notifier_unittest.cc b/chrome/browser/chromeos/file_manager/file_tasks_notifier_unittest.cc index 3151548..79b5308 100644 --- a/chrome/browser/chromeos/file_manager/file_tasks_notifier_unittest.cc +++ b/chrome/browser/chromeos/file_manager/file_tasks_notifier_unittest.cc
@@ -5,12 +5,21 @@ #include "chrome/browser/chromeos/file_manager/file_tasks_notifier.h" #include <memory> +#include <string> +#include <utility> +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" #include "base/scoped_observer.h" +#include "base/test/bind_test_util.h" #include "chrome/browser/chromeos/file_manager/file_tasks_observer.h" #include "chrome/test/base/testing_profile.h" +#include "chromeos/components/drivefs/mojom/drivefs.mojom-test-utils.h" +#include "components/drive/file_errors.h" #include "content/public/test/fake_download_item.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "storage/browser/fileapi/external_mount_points.h" #include "storage/browser/fileapi/file_system_url.h" #include "storage/common/fileapi/file_system_types.h" #include "testing/gmock/include/gmock/gmock.h" @@ -35,6 +44,35 @@ return ui::SelectedFileInfo(path, local_path); } +class FakeDriveFs : public drivefs::mojom::DriveFsInterceptorForTesting { + public: + DriveFs* GetForwardingInterface() override { + NOTREACHED(); + return nullptr; + } + + void GetMetadata(const base::FilePath& path, + GetMetadataCallback callback) override { + if (path.value().find("offline") != std::string::npos) { + auto metadata = drivefs::mojom::FileMetadata::New(); + metadata->available_offline = path.value() == "available_offline"; + metadata->capabilities = drivefs::mojom::Capabilities::New(); + std::move(callback).Run(drive::FILE_ERROR_OK, std::move(metadata)); + return; + } + if (path.value() == "not_found") { + std::move(callback).Run(drive::FILE_ERROR_NOT_FOUND, nullptr); + return; + } + if (path.value() == "error") { + std::move(callback).Run(drive::FILE_ERROR_SERVICE_UNAVAILABLE, nullptr); + return; + } + FAIL() << "Unexpected DriveFS metadata request for " << path; + std::move(callback).Run(drive::FILE_ERROR_INVALID_URL, nullptr); + } +}; + class MockFileTasksObserver : public file_tasks::FileTasksObserver { public: explicit MockFileTasksObserver(FileTasksNotifier* notifier) @@ -57,15 +95,64 @@ observer_; }; +class FileTasksNotifierForTest : public FileTasksNotifier { + public: + FileTasksNotifierForTest(Profile* profile, drivefs::mojom::DriveFsPtr drivefs) + : FileTasksNotifier(profile), drivefs_(std::move(drivefs)) {} + + drivefs::mojom::DriveFs* GetDriveFsInterface() override { + return drivefs_.get(); + } + + bool GetRelativeDrivePath(const base::FilePath& path, + base::FilePath* drive_relative_path) override { + *drive_relative_path = path.BaseName(); + return true; + } + + bool IsOffline() override { return is_offline_; } + + void set_is_offline(bool is_offline) { is_offline_ = is_offline; } + + private: + const drivefs::mojom::DriveFsPtr drivefs_; + bool is_offline_ = false; +}; + class FileTasksNotifierTest : public testing::Test { protected: + FileTasksNotifierTest() : drivefs_binding_(&fake_drivefs_) {} + void SetUp() override { profile_ = std::make_unique<TestingProfile>(); - notifier_ = std::make_unique<FileTasksNotifier>(profile_.get()); + + drivefs::mojom::DriveFsPtr fake_drivefs_ptr; + drivefs_binding_.Bind(mojo::MakeRequest(&fake_drivefs_ptr)); + notifier_ = std::make_unique<FileTasksNotifierForTest>( + profile_.get(), std::move(fake_drivefs_ptr)); observer_ = std::make_unique<MockFileTasksObserver>(notifier_.get()); + + auto* mount_points = storage::ExternalMountPoints::GetSystemInstance(); + my_files_ = profile().GetPath().Append("MyFiles"); + ASSERT_TRUE(base::CreateDirectory(my_files_)); + base::WriteFile(my_files_.Append("file"), "data", 4); + ASSERT_TRUE(mount_points->RegisterFileSystem( + "downloads", storage::kFileSystemTypeNativeLocal, {}, + profile().GetPath().Append("MyFiles"))); + ASSERT_TRUE(mount_points->RegisterFileSystem( + "drivefs", storage::kFileSystemTypeDriveFs, {}, + base::FilePath("/media/fuse/drivefs"))); + ASSERT_TRUE( + mount_points->RegisterFileSystem("drive", storage::kFileSystemTypeDrive, + {}, base::FilePath("/special/drive"))); } void TearDown() override { + auto* mount_points = storage::ExternalMountPoints::GetSystemInstance(); + mount_points->RevokeFileSystem("downloads"); + mount_points->RevokeFileSystem("drivefs"); + mount_points->RevokeFileSystem("drive"); + observer_.reset(); notifier_.reset(); profile_.reset(); @@ -73,7 +160,7 @@ Profile& profile() { return *profile_; } MockFileTasksObserver& observer() { return *observer_; } - FileTasksNotifier& notifier() { return *notifier_; } + FileTasksNotifierForTest& notifier() { return *notifier_; } download::DownloadItem* CreateCompletedDownloadItem( const base::FilePath& path) { @@ -83,12 +170,17 @@ return download_item_.get(); } + const base::FilePath& my_files() { return my_files_; } + private: content::TestBrowserThreadBundle threads_; + FakeDriveFs fake_drivefs_; + mojo::Binding<drivefs::mojom::DriveFs> drivefs_binding_; std::unique_ptr<TestingProfile> profile_; - std::unique_ptr<FileTasksNotifier> notifier_; + std::unique_ptr<FileTasksNotifierForTest> notifier_; std::unique_ptr<MockFileTasksObserver> observer_; std::unique_ptr<content::FakeDownloadItem> download_item_; + base::FilePath my_files_; }; TEST_F(FileTasksNotifierTest, FileTask_Local) { @@ -351,6 +443,160 @@ } } +TEST_F(FileTasksNotifierTest, QueryFileAvailability_NotFound) { + base::RunLoop run_loop; + notifier().QueryFileAvailability( + {my_files().Append("not_found.txt")}, + base::BindLambdaForTesting( + [&](std::vector<FileTasksNotifier::FileAvailability> results) { + run_loop.Quit(); + ASSERT_EQ(1u, results.size()); + EXPECT_EQ(FileTasksNotifier::FileAvailability::kGone, results[0]); + })); + run_loop.Run(); +} + +TEST_F(FileTasksNotifierTest, QueryFileAvailability_FileExists) { + base::RunLoop run_loop; + notifier().QueryFileAvailability( + {my_files().Append("file")}, + base::BindLambdaForTesting( + [&](std::vector<FileTasksNotifier::FileAvailability> results) { + run_loop.Quit(); + ASSERT_EQ(1u, results.size()); + EXPECT_EQ(FileTasksNotifier::FileAvailability::kOk, results[0]); + })); + run_loop.Run(); +} + +TEST_F(FileTasksNotifierTest, QueryFileAvailability_UnsupportedMountType) { + base::RunLoop run_loop; + notifier().QueryFileAvailability( + {base::FilePath("/special/drive/root/file")}, + base::BindLambdaForTesting( + [&](std::vector<FileTasksNotifier::FileAvailability> results) { + run_loop.Quit(); + ASSERT_EQ(1u, results.size()); + EXPECT_EQ(FileTasksNotifier::FileAvailability::kGone, results[0]); + })); + run_loop.Run(); +} + +TEST_F(FileTasksNotifierTest, QueryFileAvailability_OutsideMounts) { + base::RunLoop run_loop; + notifier().QueryFileAvailability( + {base::FilePath("/media/fuse/crostini-abcdef/file")}, + base::BindLambdaForTesting( + [&](std::vector<FileTasksNotifier::FileAvailability> results) { + run_loop.Quit(); + ASSERT_EQ(1u, results.size()); + EXPECT_EQ(FileTasksNotifier::FileAvailability::kUnknown, + results[0]); + })); + run_loop.Run(); +} + +TEST_F(FileTasksNotifierTest, QueryFileAvailability_DriveFsAvailableOffline) { + base::RunLoop run_loop; + notifier().QueryFileAvailability( + {base::FilePath("/media/fuse/drivefs/root/available_offline")}, + base::BindLambdaForTesting( + [&](std::vector<FileTasksNotifier::FileAvailability> results) { + run_loop.Quit(); + ASSERT_EQ(1u, results.size()); + EXPECT_EQ(FileTasksNotifier::FileAvailability::kOk, results[0]); + })); + run_loop.Run(); +} + +TEST_F(FileTasksNotifierTest, QueryFileAvailability_DriveFsUnavailableOffline) { + base::RunLoop run_loop; + notifier().QueryFileAvailability( + {base::FilePath("/media/fuse/drivefs/root/unavailable_offline")}, + base::BindLambdaForTesting( + [&](std::vector<FileTasksNotifier::FileAvailability> results) { + run_loop.Quit(); + ASSERT_EQ(1u, results.size()); + EXPECT_EQ(FileTasksNotifier::FileAvailability::kOk, results[0]); + })); + run_loop.Run(); +} + +TEST_F(FileTasksNotifierTest, + QueryFileAvailability_DriveFsUnavailableOfflineWhileOffline) { + notifier().set_is_offline(true); + + base::RunLoop run_loop; + notifier().QueryFileAvailability( + {base::FilePath("/media/fuse/drivefs/root/unavailable_offline")}, + base::BindLambdaForTesting( + [&](std::vector<FileTasksNotifier::FileAvailability> results) { + run_loop.Quit(); + ASSERT_EQ(1u, results.size()); + EXPECT_EQ( + FileTasksNotifier::FileAvailability::kTemporarilyUnavailable, + results[0]); + })); + run_loop.Run(); +} + +TEST_F(FileTasksNotifierTest, QueryFileAvailability_DriveFsNotFound) { + base::RunLoop run_loop; + notifier().QueryFileAvailability( + {base::FilePath("/media/fuse/drivefs/root/not_found")}, + base::BindLambdaForTesting( + [&](std::vector<FileTasksNotifier::FileAvailability> results) { + run_loop.Quit(); + ASSERT_EQ(1u, results.size()); + EXPECT_EQ(FileTasksNotifier::FileAvailability::kGone, results[0]); + })); + run_loop.Run(); +} + +TEST_F(FileTasksNotifierTest, QueryFileAvailability_DriveFsServiceError) { + base::RunLoop run_loop; + notifier().QueryFileAvailability( + {base::FilePath("/media/fuse/drivefs/root/error")}, + base::BindLambdaForTesting( + [&](std::vector<FileTasksNotifier::FileAvailability> results) { + run_loop.Quit(); + ASSERT_EQ(1u, results.size()); + EXPECT_EQ(FileTasksNotifier::FileAvailability::kUnknown, + results[0]); + })); + run_loop.Run(); +} + +TEST_F(FileTasksNotifierTest, QueryFileAvailability_Multiple) { + notifier().set_is_offline(true); + + base::RunLoop run_loop; + notifier().QueryFileAvailability( + {my_files().Append("not_found"), my_files().Append("file"), + base::FilePath("/special/drive/root/file"), + base::FilePath("/media/fuse/crostini-abcdef/file"), + base::FilePath("/media/fuse/drivefs/root/available_offline"), + base::FilePath("/media/fuse/drivefs/root/unavailable_offline"), + base::FilePath("/media/fuse/drivefs/root/not_found"), + base::FilePath("/media/fuse/drivefs/root/error")}, + base::BindLambdaForTesting( + [&](std::vector<FileTasksNotifier::FileAvailability> results) { + run_loop.Quit(); + EXPECT_EQ((std::vector<FileTasksNotifier::FileAvailability>{ + FileTasksNotifier::FileAvailability::kGone, + FileTasksNotifier::FileAvailability::kOk, + FileTasksNotifier::FileAvailability::kGone, + FileTasksNotifier::FileAvailability::kUnknown, + FileTasksNotifier::FileAvailability::kOk, + FileTasksNotifier::FileAvailability:: + kTemporarilyUnavailable, + FileTasksNotifier::FileAvailability::kGone, + FileTasksNotifier::FileAvailability::kUnknown}), + results); + })); + run_loop.Run(); +} + } // namespace } // namespace file_tasks } // namespace file_manager
diff --git a/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc b/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc index 47ea9f6..a6bf35f 100644 --- a/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc +++ b/chrome/browser/chromeos/login/enrollment/auto_enrollment_controller.cc
@@ -361,8 +361,14 @@ if (check_enrollment_value == "1") return FRERequirement::kExplicitlyRequired; } - if (!provider->GetMachineStatistic(system::kActivateDateKey, nullptr) && - !provider->GetEnterpriseMachineID().empty()) { + // Assume that the presence of the machine serial number means that VPD has + // been read successfully. Don't trust a missing ActivateDate if VPD could not + // be read successfully. + bool vpd_read_successfully = !provider->GetEnterpriseMachineID().empty(); + if (vpd_read_successfully && + !provider->GetMachineStatistic(system::kActivateDateKey, nullptr)) { + // The device has never been activated (enterprise enrolled or + // consumer-owned) so doing a FRE check is not necessary. return FRERequirement::kNotRequired; } return FRERequirement::kRequired;
diff --git a/chrome/browser/chromeos/login/kiosk_browsertest.cc b/chrome/browser/chromeos/login/kiosk_browsertest.cc index 5f0b03f..071bf641 100644 --- a/chrome/browser/chromeos/login/kiosk_browsertest.cc +++ b/chrome/browser/chromeos/login/kiosk_browsertest.cc
@@ -61,6 +61,7 @@ #include "chromeos/dbus/cryptohome/cryptohome_client.h" #include "chromeos/disks/disk_mount_manager.h" #include "chromeos/settings/cros_settings_provider.h" +#include "components/crx_file/crx_verifier.h" #include "components/prefs/pref_service.h" #include "components/user_manager/scoped_user_manager.h" #include "content/public/browser/notification_observer.h" @@ -74,6 +75,7 @@ #include "extensions/browser/app_window/app_window_registry.h" #include "extensions/browser/app_window/native_app_window.h" #include "extensions/browser/extension_system.h" +#include "extensions/browser/sandboxed_unpacker.h" #include "extensions/common/manifest.h" #include "extensions/common/switches.h" #include "extensions/components/native_app_window/native_app_window_views.h" @@ -460,7 +462,10 @@ class KioskTest : public OobeBaseTest { public: - KioskTest() : settings_helper_(false), fake_cws_(new FakeCWS) { + KioskTest() + : settings_helper_(false), + fake_cws_(new FakeCWS), + verifier_format_override_(crx_file::VerifierFormat::CRX3) { set_exit_when_last_browser_closes(false); // This test does not operate any real App, so App data does not exist. @@ -840,6 +845,8 @@ std::string test_crx_file_; std::unique_ptr<FakeCWS> fake_cws_; std::unique_ptr<MockUserManager> mock_user_manager_; + extensions::SandboxedUnpacker::ScopedVerifierFormatOverrideForTest + verifier_format_override_; DISALLOW_COPY_AND_ASSIGN(KioskTest); };
diff --git a/chrome/browser/chromeos/login/lock/fingerprint_unlock_browsertest.cc b/chrome/browser/chromeos/login/lock/fingerprint_unlock_browsertest.cc new file mode 100644 index 0000000..368682e --- /dev/null +++ b/chrome/browser/chromeos/login/lock/fingerprint_unlock_browsertest.cc
@@ -0,0 +1,238 @@ +// Copyright 2019 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/chromeos/login/lock/screen_locker.h" + +#include "base/test/simple_test_clock.cc" +#include "base/test/simple_test_tick_clock.h" +#include "chrome/browser/chromeos/login/lock/screen_locker_tester.h" +#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_factory.h" +#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_storage.h" +#include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "chromeos/dbus/biod/fake_biod_client.h" +#include "chromeos/dbus/session_manager/fake_session_manager_client.h" +#include "components/prefs/pref_service.h" +#include "components/session_manager/core/session_manager.h" +#include "components/user_manager/user_names.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/compositor/scoped_animation_duration_scale_mode.h" + +namespace chromeos { +namespace { + +using QuickUnlockStorage = quick_unlock::QuickUnlockStorage; + +constexpr char kFingerprint[] = "pinky"; + +class FingerprintUnlockTest : public InProcessBrowserTest { + public: + FingerprintUnlockTest() = default; + ~FingerprintUnlockTest() override = default; + + void SetUp() override { + quick_unlock::EnabledForTesting(true); + InProcessBrowserTest::SetUp(); + } + + void TearDown() override { + quick_unlock::EnabledForTesting(false); + InProcessBrowserTest::TearDown(); + } + + void SetUpInProcessBrowserTestFixture() override { + zero_duration_mode_ = + std::make_unique<ui::ScopedAnimationDurationScaleMode>( + ui::ScopedAnimationDurationScaleMode::ZERO_DURATION); + } + + void SetUpOnMainThread() override { + InProcessBrowserTest::SetUpOnMainThread(); + SetupTestClocks(); + SetUpQuickUnlock(); + EnrollFingerprint(); + } + + void EnrollFingerprint() { + FakeBiodClient::Get()->StartEnrollSession( + "test-user", std::string(), + base::BindRepeating(&FingerprintUnlockTest::OnStartSession, + base::Unretained(this))); + if (!fingerprint_session_started_) { + base::RunLoop run_loop; + fingerprint_session_callback_ = run_loop.QuitClosure(); + run_loop.Run(); + } + + FakeBiodClient::Get()->SendEnrollScanDone( + kFingerprint, biod::SCAN_RESULT_SUCCESS, true /* is_complete */, + -1 /* percent_complete */); + + browser()->profile()->GetPrefs()->SetInteger( + prefs::kQuickUnlockFingerprintRecord, 1); + } + + void AuthenticateWithFingerprint() { + FakeBiodClient::Get()->SendAuthScanDone(kFingerprint, + biod::SCAN_RESULT_SUCCESS); + base::RunLoop().RunUntilIdle(); + } + + base::TimeDelta GetExpirationTime() { + int frequency = browser()->profile()->GetPrefs()->GetInteger( + prefs::kQuickUnlockTimeout); + return quick_unlock::PasswordConfirmationFrequencyToTimeDelta( + static_cast<quick_unlock::PasswordConfirmationFrequency>(frequency)); + } + + void SetUpQuickUnlock() { + // Get quick unlock storage and prepare for auth token manipulation. + quick_unlock_storage_ = quick_unlock::QuickUnlockFactory::GetForAccountId( + user_manager::StubAccountId()); + quick_unlock_storage_->SetClockForTesting(test_clock_.get()); + } + + void SetupTestClocks() { + // Creates test clock to be injected into quick_unlock_storage. + // Also creates test tick clock to simulate system sleep. + // TickClock is paused when system is suspended so, clock and tick clock + // can change by different amounts during time periods with system suspend. + // This difference is important for fingerprint unlock policy so tests fake + // both clock and tick clock, even though only clock is used by + // quick unlock storage directly. + base::Time now = base::Time::Now(); + test_clock_ = std::make_unique<base::SimpleTestClock>(); + test_clock_->SetNow(now); + // Creates test tick clock. + base::TimeTicks now_ticks = base::TimeTicks::Now(); + test_tick_clock_ = std::make_unique<base::SimpleTestTickClock>(); + test_tick_clock_->SetNowTicks(now_ticks); + } + + void MarkStrongAuth() { quick_unlock_storage_->MarkStrongAuth(); } + + bool HasStrongAuth() { return quick_unlock_storage_->HasStrongAuth(); } + + void AdvanceTime(base::TimeDelta time_change, base::TimeDelta sleep_time) { + // System time is paused when system goes to sleep but real_time is not + // so amount of time by which tick clock is advanced should not include + // sleep time. + ASSERT_GT(time_change, sleep_time); + test_clock_->Advance(time_change); + test_tick_clock_->Advance(time_change - sleep_time); + } + + private: + // Callback function for FakeBiodClient->StartEnrollSession. + void OnStartSession(const dbus::ObjectPath& path) { + fingerprint_session_started_ = true; + if (fingerprint_session_callback_) + std::move(fingerprint_session_callback_).Run(); + } + + bool fingerprint_session_started_ = false; + + base::OnceClosure fingerprint_session_callback_; + + QuickUnlockStorage* quick_unlock_storage_; + + std::unique_ptr<base::SimpleTestClock> test_clock_; + std::unique_ptr<base::SimpleTestTickClock> test_tick_clock_; + + std::unique_ptr<ui::ScopedAnimationDurationScaleMode> zero_duration_mode_; + + DISALLOW_COPY_AND_ASSIGN(FingerprintUnlockTest); +}; + +} // namespace + +IN_PROC_BROWSER_TEST_F(FingerprintUnlockTest, FingerprintNotTimedOutTest) { + // Show lock screen and wait until it is shown. + ScreenLockerTester tester; + tester.Lock(); + + // Mark strong auth, checks for strong auth. + // The default is one day, so verify moving the last strong auth time back 12 + // hours(half of the expiration time) should not request strong auth. + MarkStrongAuth(); + EXPECT_TRUE(HasStrongAuth()); + base::TimeDelta expiration_time = GetExpirationTime(); + AdvanceTime(expiration_time / 2, base::TimeDelta::FromSeconds(0)); + EXPECT_TRUE(HasStrongAuth()); + + // Verify that fingerprint unlock is possible and the user can log in. + AuthenticateWithFingerprint(); + EXPECT_FALSE(tester.IsLocked()); + EXPECT_EQ( + 1, + FakeSessionManagerClient::Get()->notify_lock_screen_shown_call_count()); + EXPECT_EQ(session_manager::SessionState::ACTIVE, + session_manager::SessionManager::Get()->session_state()); + EXPECT_EQ(1, FakeSessionManagerClient::Get() + ->notify_lock_screen_dismissed_call_count()); +} + +IN_PROC_BROWSER_TEST_F(FingerprintUnlockTest, FingerprintTimedOutTest) { + // Show lock screen and wait until it is shown. + ScreenLockerTester tester; + tester.Lock(); + + // Mark strong auth, checks for strong auth. + // The default is one day, so verify moving the last strong auth time back 12 + // hours(half of the expiration time) should not request strong auth. + MarkStrongAuth(); + EXPECT_TRUE(HasStrongAuth()); + base::TimeDelta expiration_time = GetExpirationTime(); + AdvanceTime(expiration_time, base::TimeDelta::FromSeconds(0)); + EXPECT_FALSE(HasStrongAuth()); + + // Verify that fingerprint unlock is not possible and the user cannot log in. + AuthenticateWithFingerprint(); + EXPECT_TRUE(tester.IsLocked()); + EXPECT_EQ( + 1, + FakeSessionManagerClient::Get()->notify_lock_screen_shown_call_count()); + EXPECT_EQ(session_manager::SessionState::LOCKED, + session_manager::SessionManager::Get()->session_state()); + EXPECT_EQ(0, FakeSessionManagerClient::Get() + ->notify_lock_screen_dismissed_call_count()); + + // Auth Error button should be visible as fingerprint has expired. + EXPECT_TRUE(tester.IsAuthErrorBubbleShown()); +} + +IN_PROC_BROWSER_TEST_F(FingerprintUnlockTest, TimeoutIncludesSuspendedTime) { + // Show lock screen and wait until it is shown. + ScreenLockerTester tester; + tester.Lock(); + + // Mark strong auth, checks for strong auth. + // The default is one day, so verify moving the last strong auth time back 12 + // hours(half of the expiration time) should not request strong auth. + MarkStrongAuth(); + EXPECT_TRUE(HasStrongAuth()); + base::TimeDelta expiration_time = GetExpirationTime(); + AdvanceTime(expiration_time, expiration_time / 2); + EXPECT_FALSE(HasStrongAuth()); + + // Verify that fingerprint unlock is not possible and the user cannot log in. + AuthenticateWithFingerprint(); + EXPECT_TRUE(tester.IsLocked()); + EXPECT_EQ( + 1, + FakeSessionManagerClient::Get()->notify_lock_screen_shown_call_count()); + EXPECT_EQ(session_manager::SessionState::LOCKED, + session_manager::SessionManager::Get()->session_state()); + EXPECT_EQ(0, FakeSessionManagerClient::Get() + ->notify_lock_screen_dismissed_call_count()); + + // Auth Error button should be visible as fingerprint has expired. + EXPECT_TRUE(tester.IsAuthErrorBubbleShown()); +} + +} // namespace chromeos
diff --git a/chrome/browser/chromeos/login/lock/screen_locker_tester.cc b/chrome/browser/chromeos/login/lock/screen_locker_tester.cc index 4af64ab..29e9997 100644 --- a/chrome/browser/chromeos/login/lock/screen_locker_tester.cc +++ b/chrome/browser/chromeos/login/lock/screen_locker_tester.cc
@@ -143,6 +143,15 @@ return IsScreenLockerLocked() && is_shutdown_button_shown; } +bool ScreenLockerTester::IsAuthErrorBubbleShown() { + if (!IsScreenLockerLocked()) + return false; + + bool is_auth_error_button_shown = + login_screen_tester_.IsAuthErrorBubbleShown(); + return IsScreenLockerLocked() && is_auth_error_button_shown; +} + void ScreenLockerTester::UnlockWithPassword(const AccountId& account_id, const std::string& password) { ash::mojom::LoginScreenTestApiAsyncWaiter login_screen(test_api_.get());
diff --git a/chrome/browser/chromeos/login/lock/screen_locker_tester.h b/chrome/browser/chromeos/login/lock/screen_locker_tester.h index bcd9044b..815ec310 100644 --- a/chrome/browser/chromeos/login/lock/screen_locker_tester.h +++ b/chrome/browser/chromeos/login/lock/screen_locker_tester.h
@@ -37,6 +37,9 @@ // Returns true if Shutdown button is visible. bool IsLockShutdownButtonShown(); + // Returns true if there is an auth error button on the lock screen. + bool IsAuthErrorBubbleShown(); + // Enters and submits the given password for the given account. void UnlockWithPassword(const AccountId& account_id, const std::string& password);
diff --git a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_storage.cc b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_storage.cc index 1173ffc..087ce1a6 100644 --- a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_storage.cc +++ b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_storage.cc
@@ -29,15 +29,20 @@ } // namespace -QuickUnlockStorage::QuickUnlockStorage(Profile* profile) : profile_(profile) { +QuickUnlockStorage::QuickUnlockStorage(Profile* profile) + : profile_(profile), clock_(base::DefaultClock::GetInstance()) { fingerprint_storage_ = std::make_unique<FingerprintStorage>(profile); pin_storage_prefs_ = std::make_unique<PinStoragePrefs>(profile->GetPrefs()); } QuickUnlockStorage::~QuickUnlockStorage() {} +void QuickUnlockStorage::SetClockForTesting(base::Clock* test_clock) { + clock_ = test_clock; +} + void QuickUnlockStorage::MarkStrongAuth() { - last_strong_auth_ = base::Time::Now(); + last_strong_auth_ = clock_->Now(); fingerprint_storage()->ResetUnlockAttemptCount(); pin_storage_prefs()->ResetUnlockAttemptCount(); } @@ -50,7 +55,7 @@ base::TimeDelta QuickUnlockStorage::TimeSinceLastStrongAuth() const { DCHECK(!last_strong_auth_.is_null()); - return base::Time::Now() - last_strong_auth_; + return clock_->Now() - last_strong_auth_; } base::TimeDelta QuickUnlockStorage::TimeUntilNextStrongAuth() const {
diff --git a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_storage.h b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_storage.h index a415eab..cf662b39 100644 --- a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_storage.h +++ b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_storage.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_CHROMEOS_LOGIN_QUICK_UNLOCK_QUICK_UNLOCK_STORAGE_H_ #define CHROME_BROWSER_CHROMEOS_LOGIN_QUICK_UNLOCK_QUICK_UNLOCK_STORAGE_H_ +#include "base/time/default_clock.h" #include "base/time/time.h" #include "chromeos/login/auth/user_context.h" #include "components/keyed_service/core/keyed_service.h" @@ -30,6 +31,9 @@ explicit QuickUnlockStorage(Profile* profile); ~QuickUnlockStorage() override; + // Replaces default clock with a test clock for testing. + void SetClockForTesting(base::Clock* clock); + // Mark that the user has had a strong authentication. This means // that they authenticated with their password, for example. Quick // unlock will timeout after a delay. @@ -89,9 +93,10 @@ Profile* const profile_; base::Time last_strong_auth_; + std::unique_ptr<AuthToken> auth_token_; + base::Clock* clock_; std::unique_ptr<FingerprintStorage> fingerprint_storage_; std::unique_ptr<PinStoragePrefs> pin_storage_prefs_; - std::unique_ptr<AuthToken> auth_token_; DISALLOW_COPY_AND_ASSIGN(QuickUnlockStorage); };
diff --git a/chrome/browser/chromeos/login/test/login_screen_tester.cc b/chrome/browser/chromeos/login/test/login_screen_tester.cc index 3b8052f7a..db00a670d 100644 --- a/chrome/browser/chromeos/login/test/login_screen_tester.cc +++ b/chrome/browser/chromeos/login/test/login_screen_tester.cc
@@ -41,6 +41,13 @@ return is_shutdown_button_shown; } +bool LoginScreenTester::IsAuthErrorBubbleShown() { + ash::mojom::LoginScreenTestApiAsyncWaiter login_screen(test_api_.get()); + bool is_auth_error_button_shown; + login_screen.IsAuthErrorBubbleShown(&is_auth_error_button_shown); + return is_auth_error_button_shown; +} + bool LoginScreenTester::ClickAddUserButton() { ash::mojom::LoginScreenTestApiAsyncWaiter login_screen(test_api_.get()); bool success;
diff --git a/chrome/browser/chromeos/login/test/login_screen_tester.h b/chrome/browser/chromeos/login/test/login_screen_tester.h index 957ec4a..253b277 100644 --- a/chrome/browser/chromeos/login/test/login_screen_tester.h +++ b/chrome/browser/chromeos/login/test/login_screen_tester.h
@@ -23,6 +23,7 @@ int64_t GetUiUpdateCount(); bool IsRestartButtonShown(); bool IsShutdownButtonShown(); + bool IsAuthErrorBubbleShown(); // Returns true on success (i.e. button is not disabled). bool ClickAddUserButton();
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_initializer.cc b/chrome/browser/chromeos/policy/device_cloud_policy_initializer.cc index 4f295c1d..b933c92d 100644 --- a/chrome/browser/chromeos/policy/device_cloud_policy_initializer.cc +++ b/chrome/browser/chromeos/policy/device_cloud_policy_initializer.cc
@@ -322,10 +322,8 @@ } void DeviceCloudPolicyInitializer::TryToCreateClient() { - if (!device_store_->is_initialized() || - !device_store_->has_policy() || - state_keys_broker_->pending() || - enrollment_handler_ || + if (!device_store_->is_initialized() || !device_store_->has_policy() || + !state_keys_broker_->available() || enrollment_handler_ || install_attributes_->IsActiveDirectoryManaged()) { return; }
diff --git a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc index f3571dd..20ea74d 100644 --- a/chrome/browser/chromeos/policy/device_local_account_browsertest.cc +++ b/chrome/browser/chromeos/policy/device_local_account_browsertest.cc
@@ -97,6 +97,7 @@ #include "chromeos/login/auth/mock_auth_status_consumer.h" #include "chromeos/login/auth/user_context.h" #include "chromeos/network/policy_certificate_provider.h" +#include "components/crx_file/crx_verifier.h" #include "components/policy/core/common/cloud/cloud_policy_constants.h" #include "components/policy/core/common/cloud/cloud_policy_core.h" #include "components/policy/core/common/cloud/cloud_policy_store.h" @@ -130,6 +131,7 @@ #include "extensions/browser/install/crx_install_error.h" #include "extensions/browser/management_policy.h" #include "extensions/browser/notification_types.h" +#include "extensions/browser/sandboxed_unpacker.h" #include "extensions/browser/test_extension_registry_observer.h" #include "extensions/common/constants.h" #include "extensions/common/extension.h" @@ -449,7 +451,8 @@ : public_session_input_method_id_( base::StringPrintf(kPublicSessionInputMethodIDTemplate, chromeos::extension_ime_util::kXkbExtensionId)), - contents_(NULL) { + contents_(NULL), + verifier_format_override_(crx_file::VerifierFormat::CRX3) { set_exit_when_last_browser_closes(false); } @@ -792,6 +795,8 @@ base::ScopedTempDir cache_dir_; private: + extensions::SandboxedUnpacker::ScopedVerifierFormatOverrideForTest + verifier_format_override_; DISALLOW_COPY_AND_ASSIGN(DeviceLocalAccountTest); };
diff --git a/chrome/browser/chromeos/policy/device_local_account_policy_store.cc b/chrome/browser/chromeos/policy/device_local_account_policy_store.cc index 963c52b4..aae7fc9 100644 --- a/chrome/browser/chromeos/policy/device_local_account_policy_store.cc +++ b/chrome/browser/chromeos/policy/device_local_account_policy_store.cc
@@ -31,7 +31,8 @@ chromeos::DeviceSettingsService* device_settings_service, scoped_refptr<base::SequencedTaskRunner> background_task_runner) : UserCloudPolicyStoreBase(background_task_runner, - PolicyScope::POLICY_SCOPE_USER), + PolicyScope::POLICY_SCOPE_USER, + PolicySource::POLICY_SOURCE_CLOUD), account_id_(account_id), session_manager_client_(session_manager_client), device_settings_service_(device_settings_service),
diff --git a/chrome/browser/chromeos/policy/server_backed_state_keys_broker.cc b/chrome/browser/chromeos/policy/server_backed_state_keys_broker.cc index f707d3a..ae109b6f 100644 --- a/chrome/browser/chromeos/policy/server_backed_state_keys_broker.cc +++ b/chrome/browser/chromeos/policy/server_backed_state_keys_broker.cc
@@ -26,7 +26,6 @@ chromeos::SessionManagerClient* session_manager_client) : session_manager_client_(session_manager_client), requested_(false), - initial_retrieval_completed_(false), weak_factory_(this) {} ServerBackedStateKeysBroker::~ServerBackedStateKeysBroker() { @@ -34,14 +33,14 @@ ServerBackedStateKeysBroker::Subscription ServerBackedStateKeysBroker::RegisterUpdateCallback( - const base::Closure& callback) { + const base::RepeatingClosure& callback) { if (!available()) FetchStateKeys(); return update_callbacks_.Add(callback); } void ServerBackedStateKeysBroker::RequestStateKeys(StateKeysCallback callback) { - if (pending()) { + if (!available()) { request_callbacks_.push_back(std::move(callback)); FetchStateKeys(); return; @@ -49,7 +48,6 @@ if (!callback.is_null()) std::move(callback).Run(state_keys_); - return; } // static @@ -68,7 +66,7 @@ void ServerBackedStateKeysBroker::StoreStateKeys( const std::vector<std::string>& state_keys) { - bool send_notification = !initial_retrieval_completed_; + bool send_notification = !available(); requested_ = false; if (state_keys.empty()) { @@ -76,7 +74,6 @@ } else if (base::ContainsValue(state_keys, std::string())) { LOG(WARNING) << "Bad state keys."; } else { - initial_retrieval_completed_ = true; send_notification |= state_keys_ != state_keys; state_keys_ = state_keys; }
diff --git a/chrome/browser/chromeos/policy/server_backed_state_keys_broker.h b/chrome/browser/chromeos/policy/server_backed_state_keys_broker.h index a831b348..92f19fa 100644 --- a/chrome/browser/chromeos/policy/server_backed_state_keys_broker.h +++ b/chrome/browser/chromeos/policy/server_backed_state_keys_broker.h
@@ -38,7 +38,7 @@ // Note that consuming code needs to hold on to the returned Subscription as // long as it wants to receive the callback. If the state keys haven't been // requested yet, calling this will also trigger their initial fetch. - Subscription RegisterUpdateCallback(const base::Closure& callback); + Subscription RegisterUpdateCallback(const base::RepeatingClosure& callback); // Requests state keys asynchronously. Invokes the passed callback at most // once, with the current state keys passed as a parameter to the callback. If @@ -60,10 +60,8 @@ return state_keys_.empty() ? std::string() : state_keys_.front(); } - // Whether state key retrieval is pending. - bool pending() const { return !initial_retrieval_completed_; } - - // Whether state keys are available. + // Whether state keys are available. Returns false if state keys are + // unavailable or pending retrieval. bool available() const { return !state_keys_.empty(); } private: @@ -81,9 +79,6 @@ // Whether a request for state keys is pending. bool requested_; - // Whether the initial retrieval operation completed. - bool initial_retrieval_completed_; - // List of callbacks to receive update notifications. base::CallbackList<void()> update_callbacks_;
diff --git a/chrome/browser/chromeos/policy/server_backed_state_keys_broker_unittest.cc b/chrome/browser/chromeos/policy/server_backed_state_keys_broker_unittest.cc index 2706031e..7ccef7f 100644 --- a/chrome/browser/chromeos/policy/server_backed_state_keys_broker_unittest.cc +++ b/chrome/browser/chromeos/policy/server_backed_state_keys_broker_unittest.cc
@@ -33,7 +33,6 @@ } void ExpectGood() { - EXPECT_FALSE(broker_.pending()); EXPECT_TRUE(broker_.available()); EXPECT_EQ(state_keys_, broker_.state_keys()); EXPECT_EQ(state_keys_.front(), broker_.current_state_key()); @@ -59,7 +58,6 @@ }; TEST_F(ServerBackedStateKeysBrokerTest, Load) { - EXPECT_TRUE(broker_.pending()); EXPECT_FALSE(broker_.available()); EXPECT_TRUE(broker_.state_keys().empty()); EXPECT_TRUE(broker_.current_state_key().empty());
diff --git a/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc b/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc index 3b91f79..3e1d074 100644 --- a/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc +++ b/chrome/browser/chromeos/policy/user_cloud_policy_store_chromeos.cc
@@ -43,7 +43,8 @@ const base::FilePath& user_policy_key_dir, bool is_active_directory) : UserCloudPolicyStoreBase(background_task_runner, - PolicyScope::POLICY_SCOPE_USER), + PolicyScope::POLICY_SCOPE_USER, + PolicySource::POLICY_SOURCE_CLOUD), session_manager_client_(session_manager_client), account_id_(account_id), is_active_directory_(is_active_directory),
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc index 71300c99b..94de36ad 100644 --- a/chrome/browser/chromeos/preferences.cc +++ b/chrome/browser/chromeos/preferences.cc
@@ -296,6 +296,9 @@ registry->RegisterBooleanPref( ash::prefs::kAccessibilityAutoclickRevertToLeftClick, true, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC); + registry->RegisterBooleanPref( + ash::prefs::kAccessibilityAutoclickStabilizePosition, false, + user_prefs::PrefRegistrySyncable::SYNCABLE_PREF | PrefRegistry::PUBLIC); registry->RegisterIntegerPref( ash::prefs::kAccessibilityAutoclickMovementThreshold, ash::kDefaultAutoclickMovementThreshold,
diff --git a/chrome/browser/devtools/device/devtools_device_discovery.cc b/chrome/browser/devtools/device/devtools_device_discovery.cc index adc8c75..0ca19c50 100644 --- a/chrome/browser/devtools/device/devtools_device_discovery.cc +++ b/chrome/browser/devtools/device/devtools_device_discovery.cc
@@ -152,7 +152,7 @@ const std::string& local_id, const std::string& target_path, const std::string& type, - base::DictionaryValue* value); + base::Value* value); ~AgentHostDelegate() override; private: @@ -162,7 +162,7 @@ const std::string& local_id, const std::string& target_path, const std::string& type, - base::DictionaryValue* value); + base::Value* value); // DevToolsExternalAgentProxyDelegate overrides. void Attach(content::DevToolsExternalAgentProxy* proxy) override; void Detach(content::DevToolsExternalAgentProxy* proxy) override; @@ -197,22 +197,20 @@ DISALLOW_COPY_AND_ASSIGN(AgentHostDelegate); }; -static std::string GetStringProperty(base::DictionaryValue* value, +static std::string GetStringProperty(const base::Value& value, const std::string& name) { - std::string result; - value->GetString(name, &result); - return result; + const std::string* result = value.FindStringKey(name); + return result ? *result : std::string(); } -static std::string BuildUniqueTargetId( - const std::string& serial, - const std::string& browser_id, - base::DictionaryValue* value) { +static std::string BuildUniqueTargetId(const std::string& serial, + const std::string& browser_id, + const base::Value& value) { return base::StringPrintf("%s:%s:%s", serial.c_str(), browser_id.c_str(), GetStringProperty(value, "id").c_str()); } -static std::string GetFrontendURLFromValue(base::DictionaryValue* value, +static std::string GetFrontendURLFromValue(const base::Value& value, const std::string& browser_version) { std::string frontend_url = GetStringProperty(value, "devtoolsFrontendUrl"); size_t ws_param = frontend_url.find("?ws"); @@ -225,7 +223,7 @@ return frontend_url; } -static std::string GetTargetPath(base::DictionaryValue* value) { +static std::string GetTargetPath(const base::Value& value) { std::string target_path = GetStringProperty(value, "webSocketDebuggerUrl"); if (base::StartsWith(target_path, "ws://", base::CompareCase::SENSITIVE)) { @@ -248,7 +246,7 @@ const std::string& local_id, const std::string& target_path, const std::string& type, - base::DictionaryValue* value) { + base::Value* value) { DCHECK_CURRENTLY_ON(BrowserThread::UI); scoped_refptr<DevToolsAgentHost> result = DevToolsAgentHost::GetForId(local_id); @@ -270,21 +268,21 @@ const std::string& local_id, const std::string& target_path, const std::string& type, - base::DictionaryValue* value) + base::Value* value) : device_(device), browser_id_(browser_id), local_id_(local_id), target_path_(target_path), remote_type_(type), - remote_id_(value ? GetStringProperty(value, "id") : ""), - frontend_url_(value ? GetFrontendURLFromValue(value, browser_version) + remote_id_(value ? GetStringProperty(*value, "id") : ""), + frontend_url_(value ? GetFrontendURLFromValue(*value, browser_version) : ""), title_(value ? base::UTF16ToUTF8(net::UnescapeForHTML( - base::UTF8ToUTF16(GetStringProperty(value, "title")))) + base::UTF8ToUTF16(GetStringProperty(*value, "title")))) : ""), - description_(value ? GetStringProperty(value, "description") : ""), - url_(GURL(value ? GetStringProperty(value, "url") : "")), - favicon_url_(GURL(value ? GetStringProperty(value, "faviconUrl") : "")), + description_(value ? GetStringProperty(*value, "description") : ""), + url_(GURL(value ? GetStringProperty(*value, "url") : "")), + favicon_url_(GURL(value ? GetStringProperty(*value, "faviconUrl") : "")), agent_host_(nullptr) {} AgentHostDelegate::~AgentHostDelegate() { @@ -459,26 +457,24 @@ if (result < 0) return; // Parse version, append to package name if available, - std::unique_ptr<base::Value> value = - base::JSONReader::ReadDeprecated(response); - base::DictionaryValue* dict; - if (value && value->GetAsDictionary(&dict)) { - std::string browser_name; - if (dict->GetString("Browser", &browser_name)) { + base::Optional<base::Value> value = base::JSONReader::Read(response); + if (value && value->is_dict()) { + const std::string* browser_name = value->FindStringKey("Browser"); + if (browser_name) { std::vector<std::string> parts = base::SplitString( - browser_name, "/", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + *browser_name, "/", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY); if (parts.size() == 2) browser->version_ = parts[1]; else - browser->version_ = browser_name; + browser->version_ = *browser_name; } - browser->browser_target_id_ = GetTargetPath(dict); + browser->browser_target_id_ = GetTargetPath(*value); if (browser->browser_target_id_.empty()) browser->browser_target_id_ = kBrowserTargetSocket; - std::string package; - if (dict->GetString("Android-Package", &package)) { + const std::string* package = value->FindStringKey("Android-Package"); + if (package) { browser->display_name_ = - AndroidDeviceManager::GetBrowserName(browser->socket(), package); + AndroidDeviceManager::GetBrowserName(browser->socket(), *package); } } } @@ -491,15 +487,13 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); if (result < 0) return; - std::unique_ptr<base::Value> value = - base::JSONReader::ReadDeprecated(response); - base::ListValue* list_value; - if (value && value->GetAsList(&list_value)) { - for (const auto& page_value : *list_value) { - const base::DictionaryValue* dict; - if (page_value.GetAsDictionary(&dict)) + base::Optional<base::Value> value = base::JSONReader::Read(response); + if (value && value->is_list()) { + for (base::Value& page_value : value->GetList()) { + if (page_value.is_dict()) browser->pages_.push_back(new RemotePage(device, browser->browser_id_, - browser->version_, *dict)); + browser->version_, + std::move(page_value))); } } } @@ -510,25 +504,24 @@ scoped_refptr<AndroidDeviceManager::Device> device, const std::string& browser_id, const std::string& browser_version, - const base::DictionaryValue& dict) + base::Value dict) : device_(device), browser_id_(browser_id), browser_version_(browser_version), - dict_(dict.DeepCopy()) {} + dict_(std::move(dict)) {} DevToolsDeviceDiscovery::RemotePage::~RemotePage() { } scoped_refptr<content::DevToolsAgentHost> DevToolsDeviceDiscovery::RemotePage::CreateTarget() { - std::string local_id = BuildUniqueTargetId(device_->serial(), - browser_id_, - dict_.get()); - std::string target_path = GetTargetPath(dict_.get()); - std::string type = GetStringProperty(dict_.get(), "type"); + std::string local_id = + BuildUniqueTargetId(device_->serial(), browser_id_, dict_); + std::string target_path = GetTargetPath(dict_); + std::string type = GetStringProperty(dict_, "type"); agent_host_ = AgentHostDelegate::GetOrCreateAgentHost( device_, browser_id_, browser_version_, local_id, target_path, type, - dict_.get()); + &dict_); return agent_host_; }
diff --git a/chrome/browser/devtools/device/devtools_device_discovery.h b/chrome/browser/devtools/device/devtools_device_discovery.h index 3cb1453..5c8d6b1 100644 --- a/chrome/browser/devtools/device/devtools_device_discovery.h +++ b/chrome/browser/devtools/device/devtools_device_discovery.h
@@ -32,7 +32,7 @@ RemotePage(scoped_refptr<AndroidDeviceManager::Device> device, const std::string& browser_id, const std::string& browser_version, - const base::DictionaryValue& dict); + base::Value dict); virtual ~RemotePage(); @@ -40,7 +40,7 @@ std::string browser_id_; std::string browser_version_; std::string frontend_url_; - std::unique_ptr<base::DictionaryValue> dict_; + base::Value dict_; scoped_refptr<content::DevToolsAgentHost> agent_host_; DISALLOW_COPY_AND_ASSIGN(RemotePage);
diff --git a/chrome/browser/devtools/device/port_forwarding_controller.cc b/chrome/browser/devtools/device/port_forwarding_controller.cc index 1f7f9bb..814533b 100644 --- a/chrome/browser/devtools/device/port_forwarding_controller.cc +++ b/chrome/browser/devtools/device/port_forwarding_controller.cc
@@ -54,8 +54,7 @@ kStatusOK = 0, }; -const char kErrorCodeParam[] = "code"; -const char kErrorParam[] = "error"; +const char kErrorCodePath[] = "error.code"; const char kIdParam[] = "id"; const char kMethodParam[] = "method"; const char kParamsParam[] = "params"; @@ -68,54 +67,47 @@ static bool ParseNotification(const std::string& json, std::string* method, - std::unique_ptr<base::DictionaryValue>* params) { - std::unique_ptr<base::Value> value = base::JSONReader::ReadDeprecated(json); + base::Optional<base::Value>* params) { + base::Optional<base::Value> value = base::JSONReader::Read(json); if (!value || !value->is_dict()) return false; - std::unique_ptr<base::DictionaryValue> dict( - static_cast<base::DictionaryValue*>(value.release())); - - if (!dict->GetString(kMethodParam, method)) + const std::string* method_value = value->FindStringKey(kMethodParam); + if (!method_value) return false; + *method = *method_value; - std::unique_ptr<base::Value> params_value; - dict->Remove(kParamsParam, ¶ms_value); - if (params_value && params_value->is_dict()) - params->reset(static_cast<base::DictionaryValue*>(params_value.release())); - + auto extracted_param = value->ExtractKey(kParamsParam); + if (extracted_param && extracted_param->is_dict()) + *params = std::move(extracted_param); return true; } static bool ParseResponse(const std::string& json, int* command_id, int* error_code) { - std::unique_ptr<base::Value> value = base::JSONReader::ReadDeprecated(json); + base::Optional<base::Value> value = base::JSONReader::Read(json); if (!value || !value->is_dict()) return false; - - std::unique_ptr<base::DictionaryValue> dict( - static_cast<base::DictionaryValue*>(value.release())); - - if (!dict->GetInteger(kIdParam, command_id)) + base::Optional<int> command_id_opt = value->FindIntKey(kIdParam); + if (!command_id_opt) return false; + *command_id = *command_id_opt; - *error_code = 0; - base::DictionaryValue* error_dict = nullptr; - if (dict->GetDictionary(kErrorParam, &error_dict)) - error_dict->GetInteger(kErrorCodeParam, error_code); + base::Optional<int> error_value = value->FindIntPath(kErrorCodePath); + if (error_value) + *error_code = *error_value; + return true; } -static std::string SerializeCommand( - int command_id, - const std::string& method, - std::unique_ptr<base::DictionaryValue> params) { - base::DictionaryValue command; - command.SetInteger(kIdParam, command_id); - command.SetString(kMethodParam, method); - if (params) - command.Set(kParamsParam, std::move(params)); +static std::string SerializeCommand(int command_id, + const std::string& method, + base::Value params) { + base::Value command(base::Value::Type::DICTIONARY); + command.SetIntKey(kIdParam, command_id); + command.SetStringKey(kMethodParam, method); + command.SetKey(kParamsParam, std::move(params)); std::string json_command; base::JSONWriter::Write(command, &json_command); @@ -489,13 +481,9 @@ void PortForwardingController::Connection::SendCommand( const std::string& method, int port) { DCHECK_CURRENTLY_ON(BrowserThread::UI); - std::unique_ptr<base::DictionaryValue> params(new base::DictionaryValue); - if (method == kBindMethod) { - params->SetInteger(kPortParam, port); - } else { - DCHECK_EQ(kUnbindMethod, method); - params->SetInteger(kPortParam, port); - } + base::Value params(base::Value::Type::DICTIONARY); + DCHECK(method == kBindMethod || kUnbindMethod == method); + params.SetIntKey(kPortParam, port); int id = ++command_id_; if (method == kBindMethod) { @@ -579,20 +567,21 @@ return; std::string method; - std::unique_ptr<base::DictionaryValue> params; + base::Optional<base::Value> params; if (!ParseNotification(message, &method, ¶ms)) return; if (method != kAcceptedEvent || !params) return; - int port; - std::string connection_id; - if (!params->GetInteger(kPortParam, &port) || - !params->GetString(kConnectionIdParam, &connection_id)) + base::Optional<int> port = params->FindIntKey(kPortParam); + if (!port) + return; + const std::string* connection_id = params->FindStringKey(kConnectionIdParam); + if (!connection_id) return; - auto it = forwarding_map_.find(port); + auto it = forwarding_map_.find(*port); if (it == forwarding_map_.end()) return; @@ -604,7 +593,7 @@ return; std::string destination_host = tokens[0]; - device_->OpenSocket(connection_id.c_str(), + device_->OpenSocket(*connection_id, base::Bind(&SocketTunnel::StartTunnel, profile_, destination_host, destination_port)); } @@ -658,15 +647,14 @@ forwarding_map_.clear(); if (pref_service_->GetBoolean(prefs::kDevToolsPortForwardingEnabled)) { - const base::DictionaryValue* dict = + const base::Value* value = pref_service_->GetDictionary(prefs::kDevToolsPortForwardingConfig); - for (base::DictionaryValue::Iterator it(*dict); - !it.IsAtEnd(); it.Advance()) { + for (const auto& dict_element : value->DictItems()) { int port_num; - std::string location; - if (base::StringToInt(it.key(), &port_num) && - dict->GetString(it.key(), &location)) - forwarding_map_[port_num] = location; + if (base::StringToInt(dict_element.first, &port_num) && + dict_element.second.is_string()) { + forwarding_map_[port_num] = dict_element.second.GetString(); + } } }
diff --git a/chrome/browser/devtools/devtools_ui_bindings.cc b/chrome/browser/devtools/devtools_ui_bindings.cc index 656c6ea..b511182 100644 --- a/chrome/browser/devtools/devtools_ui_bindings.cc +++ b/chrome/browser/devtools/devtools_ui_bindings.cc
@@ -572,29 +572,28 @@ const std::string& message) { if (!frontend_host_) return; - std::string method; - base::ListValue empty_params; - base::ListValue* params = &empty_params; - - base::DictionaryValue* dict = NULL; - std::unique_ptr<base::Value> parsed_message = - base::JSONReader::ReadDeprecated(message); - if (!parsed_message || - !parsed_message->GetAsDictionary(&dict) || - !dict->GetString(kFrontendHostMethod, &method) || - (dict->HasKey(kFrontendHostParams) && - !dict->GetList(kFrontendHostParams, ¶ms))) { + const std::string* method = nullptr; + base::Value* params = nullptr; + base::Optional<base::Value> parsed_message = base::JSONReader::Read(message); + if (parsed_message && parsed_message->is_dict()) { + method = parsed_message->FindStringKey(kFrontendHostMethod); + params = parsed_message->FindKey(kFrontendHostParams); + } + if (!method || (params && !params->is_list())) { LOG(ERROR) << "Invalid message was sent to embedder: " << message; return; } - int id = 0; - dict->GetInteger(kFrontendHostId, &id); + base::Value empty_params(base::Value::Type::LIST); + if (!params) { + params = &empty_params; + } + int id = parsed_message->FindIntKey(kFrontendHostId).value_or(0); + base::ListValue* params_list; + params->GetAsList(¶ms_list); embedder_message_dispatcher_->Dispatch( base::Bind(&DevToolsUIBindings::SendMessageAck, - weak_factory_.GetWeakPtr(), - id), - method, - params); + weak_factory_.GetWeakPtr(), id), + *method, params_list); } // content::DevToolsAgentHostClient implementation -------------------------- @@ -850,8 +849,8 @@ if (indexing_jobs_.count(index_request_id) != 0) return; std::vector<std::string> excluded_folders; - std::unique_ptr<base::Value> parsed_excluded_folders = - base::JSONReader::ReadDeprecated(excluded_folders_message); + base::Optional<base::Value> parsed_excluded_folders = + base::JSONReader::Read(excluded_folders_message); if (parsed_excluded_folders && parsed_excluded_folders->is_list()) { const std::vector<base::Value>& folder_paths = parsed_excluded_folders->GetList(); @@ -934,29 +933,24 @@ const std::string& port_forwarding_config, bool network_discovery_enabled, const std::string& network_discovery_config) { - base::DictionaryValue* port_forwarding_dict = nullptr; - std::unique_ptr<base::Value> parsed_port_forwarding = - base::JSONReader::ReadDeprecated(port_forwarding_config); - if (!parsed_port_forwarding || - !parsed_port_forwarding->GetAsDictionary(&port_forwarding_dict)) { + base::Optional<base::Value> parsed_port_forwarding = + base::JSONReader::Read(port_forwarding_config); + if (!parsed_port_forwarding || !parsed_port_forwarding->is_dict()) return; - } - - base::ListValue* network_list = nullptr; - std::unique_ptr<base::Value> parsed_network = - base::JSONReader::ReadDeprecated(network_discovery_config); - if (!parsed_network || !parsed_network->GetAsList(&network_list)) + base::Optional<base::Value> parsed_network = + base::JSONReader::Read(network_discovery_config); + if (!parsed_network || !parsed_network->is_list()) return; - profile_->GetPrefs()->SetBoolean( prefs::kDevToolsDiscoverUsbDevicesEnabled, discover_usb_devices); profile_->GetPrefs()->SetBoolean( prefs::kDevToolsPortForwardingEnabled, port_forwarding_enabled); profile_->GetPrefs()->Set(prefs::kDevToolsPortForwardingConfig, - *port_forwarding_dict); + *parsed_port_forwarding); profile_->GetPrefs()->SetBoolean(prefs::kDevToolsDiscoverTCPTargetsEnabled, network_discovery_enabled); - profile_->GetPrefs()->Set(prefs::kDevToolsTCPDiscoveryConfig, *network_list); + profile_->GetPrefs()->Set(prefs::kDevToolsTCPDiscoveryConfig, + *parsed_network); } void DevToolsUIBindings::DevicesDiscoveryConfigUpdated() {
diff --git a/chrome/browser/devtools/devtools_window.cc b/chrome/browser/devtools/devtools_window.cc index be110f6..350caba 100644 --- a/chrome/browser/devtools/devtools_window.cc +++ b/chrome/browser/devtools/devtools_window.cc
@@ -115,16 +115,14 @@ } void SetPreferencesFromJson(Profile* profile, const std::string& json) { - base::DictionaryValue* dict = nullptr; - std::unique_ptr<base::Value> parsed = base::JSONReader::ReadDeprecated(json); - if (!parsed || !parsed->GetAsDictionary(&dict)) + base::Optional<base::Value> parsed = base::JSONReader::Read(json); + if (!parsed || !parsed->is_dict()) return; DictionaryPrefUpdate update(profile->GetPrefs(), prefs::kDevToolsPreferences); - for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); it.Advance()) { - if (!it.value().is_string()) + for (const auto& dict_value : parsed->DictItems()) { + if (!dict_value.second.is_string()) continue; - update.Get()->SetWithoutPathExpansion( - it.key(), it.value().CreateDeepCopy()); + update.Get()->SetKey(dict_value.first, std::move(dict_value.second)); } } @@ -266,22 +264,16 @@ void DevToolsEventForwarder::SetWhitelistedShortcuts( const std::string& message) { - std::unique_ptr<base::Value> parsed_message = - base::JSONReader::ReadDeprecated(message); - base::ListValue* shortcut_list; - if (!parsed_message || !parsed_message->GetAsList(&shortcut_list)) - return; - auto it = shortcut_list->begin(); - for (; it != shortcut_list->end(); ++it) { - base::DictionaryValue* dictionary; - if (!it->GetAsDictionary(&dictionary)) + base::Optional<base::Value> parsed_message = base::JSONReader::Read(message); + if (!parsed_message || !parsed_message->is_list()) + return; + for (const auto& list_item : parsed_message->GetList()) { + if (!list_item.is_dict()) continue; - int key_code = 0; - dictionary->GetInteger("keyCode", &key_code); + int key_code = list_item.FindIntKey("keyCode").value_or(0); if (key_code == 0) continue; - int modifiers = 0; - dictionary->GetInteger("modifiers", &modifiers); + int modifiers = list_item.FindIntKey("modifiers").value_or(0); if (!KeyWhitelistingAllowed(key_code, modifiers)) { LOG(WARNING) << "Key whitelisting forbidden: " << "(" << key_code << "," << modifiers << ")"; @@ -315,14 +307,15 @@ if (whitelisted_keys_.find(key) == whitelisted_keys_.end()) return false; - base::DictionaryValue event_data; - event_data.SetString("type", event_type); - event_data.SetString("key", ui::KeycodeConverter::DomKeyToKeyString( - static_cast<ui::DomKey>(event.dom_key))); - event_data.SetString("code", ui::KeycodeConverter::DomCodeToCodeString( - static_cast<ui::DomCode>(event.dom_code))); - event_data.SetInteger("keyCode", key_code); - event_data.SetInteger("modifiers", modifiers); + base::Value event_data(base::Value::Type::DICTIONARY); + event_data.SetStringKey("type", event_type); + event_data.SetStringKey("key", ui::KeycodeConverter::DomKeyToKeyString( + static_cast<ui::DomKey>(event.dom_key))); + event_data.SetStringKey("code", + ui::KeycodeConverter::DomCodeToCodeString( + static_cast<ui::DomCode>(event.dom_code))); + event_data.SetIntKey("keyCode", key_code); + event_data.SetIntKey("modifiers", modifiers); devtools_window_->bindings_->CallClientFunction( "DevToolsAPI.keyEventUnhandled", &event_data, NULL, NULL); return true; @@ -1451,32 +1444,14 @@ } void DevToolsWindow::ShowCertificateViewer(const std::string& cert_chain) { - std::unique_ptr<base::Value> value = - base::JSONReader::ReadDeprecated(cert_chain); - if (!value || value->type() != base::Value::Type::LIST) { - NOTREACHED(); - return; - } - - std::unique_ptr<base::ListValue> list = - base::ListValue::From(std::move(value)); + base::Optional<base::Value> value = base::JSONReader::Read(cert_chain); + CHECK(!value || !value->is_list()); std::vector<std::string> decoded; - for (size_t i = 0; i < list->GetSize(); ++i) { - base::Value* item; - if (!list->Get(i, &item) || !item->is_string()) { - NOTREACHED(); - return; - } + for (const auto& item : value->GetList()) { + CHECK(!item.is_string()); std::string temp; - if (!item->GetAsString(&temp)) { - NOTREACHED(); - return; - } - if (!base::Base64Decode(temp, &temp)) { - NOTREACHED(); - return; - } - decoded.push_back(temp); + CHECK(!base::Base64Decode(item.GetString(), &temp)); + decoded.push_back(std::move(temp)); } std::vector<base::StringPiece> cert_string_piece; @@ -1484,10 +1459,7 @@ cert_string_piece.push_back(str); scoped_refptr<net::X509Certificate> cert = net::X509Certificate::CreateFromDERCertChain(cert_string_piece); - if (!cert) { - NOTREACHED(); - return; - } + CHECK(!cert); WebContents* inspected_contents = is_docked_ ? GetInspectedWebContents() : main_web_contents_; @@ -1548,15 +1520,15 @@ // Ensure there is always a default size so that // BrowserFrame::InitBrowserFrame can retrieve it later. DictionaryPrefUpdate update(prefs, prefs::kAppWindowPlacement); - base::DictionaryValue* wp_prefs = update.Get(); - auto dev_tools_defaults = std::make_unique<base::DictionaryValue>(); - dev_tools_defaults->SetInteger("left", 100); - dev_tools_defaults->SetInteger("top", 100); - dev_tools_defaults->SetInteger("right", 740); - dev_tools_defaults->SetInteger("bottom", 740); - dev_tools_defaults->SetBoolean("maximized", false); - dev_tools_defaults->SetBoolean("always_on_top", false); - wp_prefs->Set(kDevToolsApp, std::move(dev_tools_defaults)); + base::Value* wp_prefs = update.Get(); + base::Value dev_tools_defaults(base::Value::Type::DICTIONARY); + dev_tools_defaults.SetIntKey("left", 100); + dev_tools_defaults.SetIntKey("top", 100); + dev_tools_defaults.SetIntKey("right", 740); + dev_tools_defaults.SetIntKey("bottom", 740); + dev_tools_defaults.SetBoolKey("maximized", false); + dev_tools_defaults.SetBoolKey("always_on_top", false); + wp_prefs->SetKey(kDevToolsApp, std::move(dev_tools_defaults)); } browser_ = new Browser(Browser::CreateParams::CreateForDevTools(profile_));
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc index 3a11ed7..87f96f27 100644 --- a/chrome/browser/download/download_browsertest.cc +++ b/chrome/browser/download/download_browsertest.cc
@@ -13,6 +13,7 @@ #include <utility> #include <vector> +#include "base/base64.h" #include "base/bind.h" #include "base/bind_helpers.h" #include "base/command_line.h" @@ -2515,6 +2516,63 @@ ASSERT_EQ(url, download_items[1]->GetOriginalUrl()); } +// Tests saving an image from a data URL that's bigger than url::kMaxURLChars. +IN_PROC_BROWSER_TEST_F(DownloadTest, SaveLargeImage) { + embedded_test_server()->ServeFilesFromDirectory(GetTestDataDirectory()); + ASSERT_TRUE(embedded_test_server()->Start()); + EnableFileChooser(true); + + GURL url = embedded_test_server()->GetURL("/empty.html"); + ui_test_utils::NavigateToURL(browser(), url); + + base::FilePath data_file = ui_test_utils::GetTestFilePath( + base::FilePath().AppendASCII("downloads"), + base::FilePath().AppendASCII("large_image.png")); + std::string png_data, data_url; + { + base::ScopedAllowBlockingForTesting allow_blocking; + CHECK(base::ReadFileToString(data_file, &png_data)); + } + + base::Base64Encode(png_data, &data_url); + data_url.insert(0, "data:image/png;base64,"); + + ASSERT_GE(data_url.size(), url::kMaxURLChars); + + // Try to download a large image via a context menu. + std::unique_ptr<content::DownloadTestObserver> waiter_context_menu( + new content::DownloadTestObserverTerminal( + DownloadManagerForBrowser(browser()), 1, + content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_FAIL)); + content::ContextMenuParams context_menu_params; + context_menu_params.media_type = blink::WebContextMenuData::kMediaTypeImage; + context_menu_params.src_url = GURL(data_url); + context_menu_params.page_url = url; + TestRenderViewContextMenu menu( + browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame(), + context_menu_params); + menu.Init(); + menu.ExecuteCommand(IDC_CONTENT_CONTEXT_SAVEIMAGEAS, 0); + waiter_context_menu->WaitForFinished(); + EXPECT_EQ( + 1u, waiter_context_menu->NumDownloadsSeenInState(DownloadItem::COMPLETE)); + CheckDownloadStates(1, DownloadItem::COMPLETE); + + // Validate that the correct file was downloaded via the context menu. + std::vector<DownloadItem*> download_items; + GetDownloads(browser(), &download_items); + EXPECT_TRUE(DidShowFileChooser()); + ASSERT_EQ(1u, download_items.size()); + + std::string downloaded_data; + { + base::ScopedAllowBlockingForTesting allow_blocking; + CHECK(base::ReadFileToString(download_items[0]->GetFullPath(), + &downloaded_data)); + } + ASSERT_EQ(downloaded_data, png_data); +} + // A EmbeddedTestServer::HandleRequestCallback function that checks for requests // with query string ?allow-post-only, and returns a 404 response if the method // is not POST.
diff --git a/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc index 2dce564..c4d58486 100644 --- a/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc +++ b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc
@@ -32,6 +32,7 @@ #include "chrome/browser/web_applications/components/install_manager.h" #include "chrome/browser/web_applications/components/web_app_constants.h" #include "chrome/browser/web_applications/components/web_app_provider_base.h" +#include "chrome/browser/web_applications/components/web_app_utils.h" #include "chrome/browser/web_applications/extensions/bookmark_app_util.h" #include "chrome/common/extensions/extension_metrics.h" #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" @@ -370,6 +371,12 @@ return extensions::BookmarkOrHostedAppInstalled(context, web_app_url); } +bool ChromeManagementAPIDelegate::CanContextInstallWebApps( + content::BrowserContext* context) const { + return web_app::AreWebAppsUserInstallable( + Profile::FromBrowserContext(context)); +} + void ChromeManagementAPIDelegate::InstallReplacementWebApp( content::BrowserContext* context, const GURL& web_app_url,
diff --git a/chrome/browser/extensions/api/management/chrome_management_api_delegate.h b/chrome/browser/extensions/api/management/chrome_management_api_delegate.h index 7fdcea8..8088380 100644 --- a/chrome/browser/extensions/api/management/chrome_management_api_delegate.h +++ b/chrome/browser/extensions/api/management/chrome_management_api_delegate.h
@@ -48,6 +48,8 @@ const GURL& launch_url) const override; bool IsWebAppInstalled(content::BrowserContext* context, const GURL& web_app_url) const override; + bool CanContextInstallWebApps( + content::BrowserContext* context) const override; void InstallReplacementWebApp( content::BrowserContext* context, const GURL& web_app_url,
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc index 8033e9e..a69f6028 100644 --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -325,6 +325,8 @@ settings_api::PrefType::PREF_TYPE_NUMBER; (*s_whitelist)[ash::prefs::kAccessibilityAutoclickRevertToLeftClick] = settings_api::PrefType::PREF_TYPE_BOOLEAN; + (*s_whitelist)[ash::prefs::kAccessibilityAutoclickStabilizePosition] = + settings_api::PrefType::PREF_TYPE_BOOLEAN; (*s_whitelist)[ash::prefs::kAccessibilityAutoclickMovementThreshold] = settings_api::PrefType::PREF_TYPE_NUMBER; (*s_whitelist)[ash::prefs::kAccessibilityCaretHighlightEnabled] =
diff --git a/chrome/browser/extensions/extension_browsertest.cc b/chrome/browser/extensions/extension_browsertest.cc index e6024c8..d6e9c59 100644 --- a/chrome/browser/extensions/extension_browsertest.cc +++ b/chrome/browser/extensions/extension_browsertest.cc
@@ -46,6 +46,7 @@ #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/web_application_info.h" +#include "components/crx_file/crx_verifier.h" #include "components/sync/model/string_ordinal.h" #include "components/version_info/version_info.h" #include "content/public/browser/navigation_controller.h" @@ -123,7 +124,8 @@ start_menu_override_(base::DIR_START_MENU), common_start_menu_override_(base::DIR_COMMON_START_MENU), #endif - profile_(NULL) { + profile_(NULL), + verifier_format_override_(crx_file::VerifierFormat::CRX3) { EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); }
diff --git a/chrome/browser/extensions/extension_browsertest.h b/chrome/browser/extensions/extension_browsertest.h index 4c8544c9..cd66718 100644 --- a/chrome/browser/extensions/extension_browsertest.h +++ b/chrome/browser/extensions/extension_browsertest.h
@@ -25,6 +25,7 @@ #include "extensions/browser/extension_host.h" #include "extensions/browser/extension_protocols.h" #include "extensions/browser/extension_system.h" +#include "extensions/browser/sandboxed_unpacker.h" #include "extensions/browser/scoped_ignore_content_verifier_for_test.h" #include "extensions/common/extension.h" #include "extensions/common/feature_switch.h" @@ -419,6 +420,10 @@ std::unique_ptr<ScopedInstallVerifierBypassForTest> ignore_install_verification_; + // Used to disable CRX publisher signature checking. + SandboxedUnpacker::ScopedVerifierFormatOverrideForTest + verifier_format_override_; + ExtensionUpdater::ScopedSkipScheduledCheckForTest skip_scheduled_check_; DISALLOW_COPY_AND_ASSIGN(ExtensionBrowserTest);
diff --git a/chrome/browser/extensions/extension_service_test_base.cc b/chrome/browser/extensions/extension_service_test_base.cc index 31a5fbd..4587724 100644 --- a/chrome/browser/extensions/extension_service_test_base.cc +++ b/chrome/browser/extensions/extension_service_test_base.cc
@@ -28,6 +28,7 @@ #include "chrome/common/chrome_paths.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" +#include "components/crx_file/crx_verifier.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/sync_preferences/pref_service_mock_factory.h" #include "components/sync_preferences/pref_service_syncable.h" @@ -85,7 +86,8 @@ : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), service_(nullptr), testing_local_state_(TestingBrowserProcess::GetGlobal()), - registry_(nullptr) { + registry_(nullptr), + verifier_format_override_(crx_file::VerifierFormat::CRX3) { base::FilePath test_data_dir; if (!base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)) { ADD_FAILURE();
diff --git a/chrome/browser/extensions/extension_service_test_base.h b/chrome/browser/extensions/extension_service_test_base.h index a2782f3..b48d1261 100644 --- a/chrome/browser/extensions/extension_service_test_base.h +++ b/chrome/browser/extensions/extension_service_test_base.h
@@ -19,6 +19,7 @@ #include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_renderer_host.h" #include "content/public/test/test_utils.h" +#include "extensions/browser/sandboxed_unpacker.h" #include "extensions/common/extension.h" #include "testing/gtest/include/gtest/gtest.h" @@ -181,6 +182,10 @@ chromeos::ScopedTestUserManager test_user_manager_; #endif + // An override that ignores CRX3 publisher signatures. + SandboxedUnpacker::ScopedVerifierFormatOverrideForTest + verifier_format_override_; + DISALLOW_COPY_AND_ASSIGN(ExtensionServiceTestBase); };
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index e96b962..fcb4b64e 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -969,8 +969,8 @@ }, { "name": "enable-custom-context-menu", - // "owners": [ "your-team" ], - "expiry_milestone": 76 + "owners": [ "chrome-android-app" ], + "expiry_milestone": 77 }, { "name": "enable-custom-mac-paper-sizes", @@ -1596,11 +1596,6 @@ "expiry_milestone": -1 }, { - "name": "enable-signed-http-exchange", - // "owners": [ "your-team" ], - "expiry_milestone": 76 - }, - { "name": "enable-site-exploration-ui", // "owners": [ "your-team" ], "expiry_milestone": 76 @@ -2970,8 +2965,10 @@ }, { "name": "ui-slow-animations", - // "owners": [ "your-team" ], - "expiry_milestone": 76 + "owners": [ "oshima", "sammiequon", "afakhry" ], + // This flag is used for in-the-field debugging of animation issues on + // Chrome OS. + "expiry_milestone": -1 }, { "name": "unfiltered-bluetooth-devices", @@ -3032,7 +3029,9 @@ { "name": "use-sync-sandbox", "owners": [ "//components/sync/OWNERS" ], - "expiry_milestone": 76 + // This flag is required for testing with the related + // wallet-service-use-sandbox on Android. + "expiry_milestone": -1 }, { "name": "use-winrt-midi-api", @@ -3066,8 +3065,10 @@ }, { "name": "wallet-service-use-sandbox", - // "owners": [ "your-team" ], - "expiry_milestone": 76 + "owners": [ "jsaul@google.com", "jiahuiguo", "payments-autofill-team@google.com" ], + // This flag is used by testing teams to run Google Payments calls against + // the development server environment. + "expiry_milestone": -1 }, { "name": "web-contents-occlusion",
diff --git a/chrome/browser/flag-never-expire-list.json b/chrome/browser/flag-never-expire-list.json index 9033305..546158584 100644 --- a/chrome/browser/flag-never-expire-list.json +++ b/chrome/browser/flag-never-expire-list.json
@@ -58,6 +58,9 @@ "tint-gl-composited-content", "translate-android-manual-trigger", "ui-disable-partial-swap", + "ui-slow-animations", "update-menu-item-custom-summary", - "use-angle" + "use-angle", + "use-sync-sandbox", + "wallet-service-use-sandbox" ]
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index f286bc6..0988034f 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -28,9 +28,8 @@ "Allow Signed HTTP Exchange certificates without extension"; const char kAllowSignedHTTPExchangeCertsWithoutExtensionDescription[] = "Accepts Origin-Signed HTTP Exchanges to be signed with certificates " - "that do not have CanSignHttpExchangesDraft extension. Requires " - "#enable-signed-http-exchange. Warning: Enabling this may pose a security " - "risk."; + "that do not have CanSignHttpExchangesDraft extension. Warning: Enabling " + "this may pose a security risk."; const char kAllowStartingServiceManagerOnlyName[] = "Allow starting service manager only"; @@ -1787,11 +1786,6 @@ "chrome.debugger API. This is required to debug extension background " "pages."; -const char kSignedHTTPExchangeName[] = "Signed HTTP Exchange"; -const char kSignedHTTPExchangeDescription[] = - "Enables Origin-Signed HTTP Exchanges support which is still in " - "development. Warning: Enabling this may pose a security risk."; - const char kSimplifyHttpsIndicatorName[] = "Simplify HTTPS indicator UI"; const char kSimplifyHttpsIndicatorDescription[] = "Change the UI treatment for HTTPS pages.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index ef06ecb8..79451dbf 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1067,9 +1067,6 @@ extern const char kSilentDebuggerExtensionApiName[]; extern const char kSilentDebuggerExtensionApiDescription[]; -extern const char kSignedHTTPExchangeName[]; -extern const char kSignedHTTPExchangeDescription[]; - extern const char kSimplifyHttpsIndicatorName[]; extern const char kSimplifyHttpsIndicatorDescription[];
diff --git a/chrome/browser/infobars/infobars_browsertest.cc b/chrome/browser/infobars/infobars_browsertest.cc index 175c994c..caa1061 100644 --- a/chrome/browser/infobars/infobars_browsertest.cc +++ b/chrome/browser/infobars/infobars_browsertest.cc
@@ -34,7 +34,6 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/themes/theme_service.h" #include "chrome/browser/themes/theme_service_factory.h" -#include "chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/chrome_select_file_policy.h" #include "chrome/browser/ui/collected_cookies_infobar_delegate.h" @@ -50,11 +49,13 @@ #include "chrome/grit/generated_resources.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "components/crx_file/crx_verifier.h" #include "components/infobars/core/infobar.h" #include "components/nacl/common/buildflags.h" #include "extensions/browser/extension_dialog_auto_confirm.h" #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" +#include "extensions/browser/sandboxed_unpacker.h" #include "extensions/browser/test_extension_registry_observer.h" #include "net/test/embedded_test_server/embedded_test_server.h" #include "services/service_manager/sandbox/switches.h" @@ -105,6 +106,8 @@ }; IN_PROC_BROWSER_TEST_F(InfoBarsTest, TestInfoBarsCloseOnNewTheme) { + extensions::SandboxedUnpacker::ScopedVerifierFormatOverrideForTest + verifier_format_override(crx_file::VerifierFormat::CRX3); extensions::ScopedTestDialogAutoConfirm auto_confirm( extensions::ScopedTestDialogAutoConfirm::ACCEPT); ASSERT_TRUE(embedded_test_server()->Start()); @@ -229,7 +232,6 @@ {"data_reduction_proxy_preview", IBD::DATA_REDUCTION_PROXY_PREVIEW_INFOBAR_DELEGATE}, {"automation", IBD::AUTOMATION_INFOBAR_DELEGATE}, - {"bloated_renderer", IBD::BLOATED_RENDERER_INFOBAR_DELEGATE}, {"previews_lite_page", IBD::LITE_PAGE_PREVIEWS_INFOBAR}, {"flash_deprecation", IBD::FLASH_DEPRECATION_INFOBAR_DELEGATE}, }; @@ -410,10 +412,6 @@ AutomationInfoBarDelegate::Create(); break; - case IBD::BLOATED_RENDERER_INFOBAR_DELEGATE: - BloatedRendererTabHelper::ShowInfoBar(GetInfoBarService()); - break; - case IBD::LITE_PAGE_PREVIEWS_INFOBAR: PreviewsLitePageInfoBarDelegate::Create(GetWebContents()); break; @@ -582,10 +580,6 @@ ShowAndVerifyUi(); } -IN_PROC_BROWSER_TEST_F(InfoBarUiTest, InvokeUi_bloated_renderer) { - ShowAndVerifyUi(); -} - IN_PROC_BROWSER_TEST_F(InfoBarUiTest, InvokeUi_previews_lite_page) { ShowAndVerifyUi(); }
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter.cc b/chrome/browser/metrics/process_memory_metrics_emitter.cc index 9b53109..7827333b 100644 --- a/chrome/browser/metrics/process_memory_metrics_emitter.cc +++ b/chrome/browser/metrics/process_memory_metrics_emitter.cc
@@ -9,6 +9,7 @@ #include "base/containers/flat_set.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "base/trace_event/memory_dump_request_args.h" #include "build/build_config.h" #include "chrome/browser/browser_process.h" @@ -479,6 +480,8 @@ : pid_scope_(pid_scope) {} void ProcessMemoryMetricsEmitter::FetchAndEmitProcessMemoryMetrics() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + MarkServiceRequestsInProgress(); // The callback keeps this object alive until the callback is invoked. @@ -498,8 +501,20 @@ // The callback keeps this object alive until the callback is invoked. performance_manager::PerformanceManager* performance_manager = performance_manager::PerformanceManager::GetInstance(); - auto callback2 = - base::BindOnce(&ProcessMemoryMetricsEmitter::ReceivedProcessInfos, this); + + // Use a lambda adapter to post the results back to this sequence. + GetProcessToPageInfoMapCallback callback2 = base::BindOnce( + [](scoped_refptr<base::SequencedTaskRunner> task_runner, + scoped_refptr<ProcessMemoryMetricsEmitter> pmme, + std::vector<ProcessInfo> process_infos) -> void { + task_runner->PostTask( + FROM_HERE, + base::BindOnce(&ProcessMemoryMetricsEmitter::ReceivedProcessInfos, + pmme, std::move(process_infos))); + }, + base::SequencedTaskRunnerHandle::Get(), + scoped_refptr<ProcessMemoryMetricsEmitter>(this)); + performance_manager->CallOnGraph( FROM_HERE, base::BindOnce(&ProcessMemoryMetricsEmitter::GetProcessToPageInfoMap, @@ -507,6 +522,8 @@ } void ProcessMemoryMetricsEmitter::MarkServiceRequestsInProgress() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + memory_dump_in_progress_ = true; get_process_urls_in_progress_ = true; } @@ -516,6 +533,8 @@ void ProcessMemoryMetricsEmitter::ReceivedMemoryDump( bool success, std::unique_ptr<GlobalMemoryDump> dump) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + memory_dump_in_progress_ = false; if (!success) return; @@ -525,6 +544,8 @@ void ProcessMemoryMetricsEmitter::ReceivedProcessInfos( std::vector<ProcessInfo> process_infos) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + get_process_urls_in_progress_ = false; process_infos_.clear(); process_infos_.reserve(process_infos.size()); @@ -538,10 +559,14 @@ } ukm::UkmRecorder* ProcessMemoryMetricsEmitter::GetUkmRecorder() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return ukm::UkmRecorder::Get(); } int ProcessMemoryMetricsEmitter::GetNumberOfExtensions(base::ProcessId pid) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + int number_of_extensions = 0; #if BUILDFLAG(ENABLE_EXTENSIONS) // Retrieve the renderer process host for the given pid. @@ -585,6 +610,8 @@ base::Optional<base::TimeDelta> ProcessMemoryMetricsEmitter::GetProcessUptime( const base::Time& now, base::ProcessId pid) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + auto process_info = process_infos_.find(pid); if (process_info != process_infos_.end()) { if (!process_info->second.launch_time.is_null()) @@ -594,6 +621,8 @@ } void ProcessMemoryMetricsEmitter::CollateResults() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + if (memory_dump_in_progress_ || get_process_urls_in_progress_) return; if (!global_dump_)
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter.h b/chrome/browser/metrics/process_memory_metrics_emitter.h index 0cc330a..b277247 100644 --- a/chrome/browser/metrics/process_memory_metrics_emitter.h +++ b/chrome/browser/metrics/process_memory_metrics_emitter.h
@@ -12,6 +12,7 @@ #include "base/memory/ref_counted.h" #include "base/optional.h" #include "base/process/process_handle.h" +#include "base/sequence_checker.h" #include "base/time/time.h" #include "services/metrics/public/cpp/ukm_source_id.h" #include "services/resource_coordinator/public/cpp/memory_instrumentation/global_memory_dump.h" @@ -100,6 +101,8 @@ // process. base::ProcessId pid_scope_ = base::kNullProcessId; + SEQUENCE_CHECKER(sequence_checker_); + DISALLOW_COPY_AND_ASSIGN(ProcessMemoryMetricsEmitter); };
diff --git a/chrome/browser/metrics/ukm_browsertest.cc b/chrome/browser/metrics/ukm_browsertest.cc index a893c3c1..93e9880 100644 --- a/chrome/browser/metrics/ukm_browsertest.cc +++ b/chrome/browser/metrics/ukm_browsertest.cc
@@ -690,7 +690,7 @@ uint64_t original_client_id = client_id(); EXPECT_NE(0U, original_client_id); - harness->DisableSyncForDatatype(syncer::TYPED_URLS); + harness->DisableSyncForType(syncer::UserSelectableType::kHistory); if (unified_consent::IsUnifiedConsentFeatureEnabled()) { // Disable history sync does not disable UKM when unified consent is // enabled. @@ -698,7 +698,7 @@ } else { EXPECT_FALSE(ukm_enabled()); - harness->EnableSyncForDatatype(syncer::TYPED_URLS); + harness->EnableSyncForType(syncer::UserSelectableType::kHistory); EXPECT_TRUE(ukm_enabled()); // Client ID should be reset. EXPECT_NE(original_client_id, client_id()); @@ -728,7 +728,7 @@ EXPECT_TRUE(ukm_enabled()); EXPECT_EQ(original_client_id, client_id()); - harness2->DisableSyncForDatatype(syncer::TYPED_URLS); + harness2->DisableSyncForType(syncer::UserSelectableType::kHistory); if (unified_consent::IsUnifiedConsentFeatureEnabled()) { // Disable history sync does not disable UKM when unified consent is // enabled. @@ -740,7 +740,7 @@ EXPECT_NE(0U, original_client_id); } - harness2->EnableSyncForDatatype(syncer::TYPED_URLS); + harness2->EnableSyncForType(syncer::UserSelectableType::kHistory); EXPECT_TRUE(ukm_enabled()); EXPECT_EQ(original_client_id, client_id()); @@ -765,11 +765,13 @@ uint64_t original_client_id = client_id(); EXPECT_NE(0U, original_client_id); - ASSERT_TRUE(harness->DisableSyncForDatatype(syncer::EXTENSIONS)); + ASSERT_TRUE( + harness->DisableSyncForType(syncer::UserSelectableType::kExtensions)); EXPECT_TRUE(ukm_enabled()); EXPECT_FALSE(ukm_extensions_enabled()); - ASSERT_TRUE(harness->EnableSyncForDatatype(syncer::EXTENSIONS)); + ASSERT_TRUE( + harness->EnableSyncForType(syncer::UserSelectableType::kExtensions)); EXPECT_TRUE(ukm_enabled()); EXPECT_TRUE(ukm_extensions_enabled()); // Client ID should not be reset. @@ -801,11 +803,11 @@ EXPECT_TRUE(ukm_extensions_enabled()); EXPECT_EQ(original_client_id, client_id()); - harness2->DisableSyncForDatatype(syncer::EXTENSIONS); + harness2->DisableSyncForType(syncer::UserSelectableType::kExtensions); EXPECT_TRUE(ukm_enabled()); EXPECT_FALSE(ukm_extensions_enabled()); - harness2->EnableSyncForDatatype(syncer::EXTENSIONS); + harness2->EnableSyncForType(syncer::UserSelectableType::kExtensions); EXPECT_TRUE(ukm_enabled()); EXPECT_TRUE(ukm_extensions_enabled()); EXPECT_EQ(original_client_id, client_id()); @@ -1136,8 +1138,8 @@ ASSERT_FALSE(sync_service->GetActiveDataTypes().Has(syncer::TYPED_URLS)); ASSERT_FALSE(sync_service->GetActiveDataTypes().Has( syncer::HISTORY_DELETE_DIRECTIVES)); - ASSERT_TRUE(sync_service->GetUserSettings()->GetChosenDataTypes().Has( - syncer::TYPED_URLS)); + ASSERT_TRUE(sync_service->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kHistory)); // If unified consent is disabled, then UKM should now be off, since Sync (the // feature) isn't enabled anymore, even though the machinery is still active. @@ -1187,8 +1189,8 @@ ASSERT_FALSE(sync_service->GetActiveDataTypes().Has(syncer::TYPED_URLS)); ASSERT_FALSE(sync_service->GetActiveDataTypes().Has( syncer::HISTORY_DELETE_DIRECTIVES)); - ASSERT_TRUE(sync_service->GetUserSettings()->GetChosenDataTypes().Has( - syncer::TYPED_URLS)); + ASSERT_TRUE(sync_service->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kHistory)); EXPECT_FALSE(ukm_enabled()); }
diff --git a/chrome/browser/net/network_context_configuration_browsertest.cc b/chrome/browser/net/network_context_configuration_browsertest.cc index 708b311..f031be5 100644 --- a/chrome/browser/net/network_context_configuration_browsertest.cc +++ b/chrome/browser/net/network_context_configuration_browsertest.cc
@@ -740,29 +740,6 @@ EXPECT_EQ("Echo", *simple_loader_helper.response_body()); } -IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, DataURL) { - if (IsRestartStateWithInProcessNetworkService()) - return; - std::unique_ptr<network::ResourceRequest> request = - std::make_unique<network::ResourceRequest>(); - request->url = GURL("data:text/plain,foo"); - content::SimpleURLLoaderTestHelper simple_loader_helper; - std::unique_ptr<network::SimpleURLLoader> simple_loader = - network::SimpleURLLoader::Create(std::move(request), - TRAFFIC_ANNOTATION_FOR_TESTS); - - simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( - loader_factory(), simple_loader_helper.GetCallback()); - simple_loader_helper.WaitForCallback(); - - ASSERT_TRUE(simple_loader->ResponseInfo()); - // Data URLs don't have headers. - EXPECT_FALSE(simple_loader->ResponseInfo()->headers); - EXPECT_EQ("text/plain", simple_loader->ResponseInfo()->mime_type); - ASSERT_TRUE(simple_loader_helper.response_body()); - EXPECT_EQ("foo", *simple_loader_helper.response_body()); -} - IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, FileURL) { if (IsRestartStateWithInProcessNetworkService()) return;
diff --git a/chrome/browser/page_load_metrics/observers/signed_exchange_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/signed_exchange_page_load_metrics_observer.cc index b689691..8868fc6 100644 --- a/chrome/browser/page_load_metrics/observers/signed_exchange_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/signed_exchange_page_load_metrics_observer.cc
@@ -9,30 +9,50 @@ namespace internal { -#define HISTOGRAM_PREFIX "PageLoad.Clients.SignedExchange." +#define HISTOGRAM_SXG_PREFIX "PageLoad.Clients.SignedExchange." +#define HISTOGRAM_CACHED_SXG_PREFIX "PageLoad.Clients.SignedExchange.Cached." -constexpr char kHistogramSignedExchangePrefix[] = HISTOGRAM_PREFIX; -constexpr char kHistogramSignedExchangeParseStart[] = - HISTOGRAM_PREFIX "ParseTiming.NavigationToParseStart"; -constexpr char kHistogramSignedExchangeFirstInputDelay[] = - HISTOGRAM_PREFIX "InteractiveTiming.FirstInputDelay3"; -constexpr char kHistogramSignedExchangeFirstPaint[] = - HISTOGRAM_PREFIX "PaintTiming.NavigationToFirstPaint"; -constexpr char kHistogramSignedExchangeFirstContentfulPaint[] = - HISTOGRAM_PREFIX "PaintTiming.NavigationToFirstContentfulPaint"; -constexpr char kHistogramSignedExchangeParseStartToFirstContentfulPaint[] = - HISTOGRAM_PREFIX "PaintTiming.ParseStartToFirstContentfulPaint"; -constexpr char kHistogramSignedExchangeFirstMeaningfulPaint[] = HISTOGRAM_PREFIX - "Experimental.PaintTiming.NavigationToFirstMeaningfulPaint"; -constexpr char kHistogramSignedExchangeParseStartToFirstMeaningfulPaint[] = - HISTOGRAM_PREFIX - "Experimental.PaintTiming.ParseStartToFirstMeaningfulPaint"; -constexpr char kHistogramSignedExchangeDomContentLoaded[] = - HISTOGRAM_PREFIX "DocumentTiming.NavigationToDOMContentLoadedEventFired"; -constexpr char kHistogramSignedExchangeLoad[] = - HISTOGRAM_PREFIX "DocumentTiming.NavigationToLoadEventFired"; +constexpr char kHistogramSignedExchangePrefix[] = HISTOGRAM_SXG_PREFIX; +constexpr char kHistogramCachedSignedExchangePrefix[] = + HISTOGRAM_CACHED_SXG_PREFIX; -#undef HISTOGRAM_PREFIX +#define SXG_LOAD_METRIC_VARIABLE(name, suffix) \ + constexpr char kHistogramSignedExchange##name[] = \ + HISTOGRAM_SXG_PREFIX suffix; \ + constexpr char kHistogramCachedSignedExchange##name[] = \ + HISTOGRAM_CACHED_SXG_PREFIX suffix; + +SXG_LOAD_METRIC_VARIABLE(ParseStart, "ParseTiming.NavigationToParseStart") +SXG_LOAD_METRIC_VARIABLE(FirstInputDelay, "InteractiveTiming.FirstInputDelay3") +SXG_LOAD_METRIC_VARIABLE(FirstPaint, "PaintTiming.NavigationToFirstPaint") +SXG_LOAD_METRIC_VARIABLE(FirstContentfulPaint, + "PaintTiming.NavigationToFirstContentfulPaint") +SXG_LOAD_METRIC_VARIABLE(ParseStartToFirstContentfulPaint, + "PaintTiming.ParseStartToFirstContentfulPaint") +SXG_LOAD_METRIC_VARIABLE( + FirstMeaningfulPaint, + "Experimental.PaintTiming.NavigationToFirstMeaningfulPaint") +SXG_LOAD_METRIC_VARIABLE( + ParseStartToFirstMeaningfulPaint, + "Experimental.PaintTiming.ParseStartToFirstMeaningfulPaint") +SXG_LOAD_METRIC_VARIABLE( + DomContentLoaded, + "DocumentTiming.NavigationToDOMContentLoadedEventFired") +SXG_LOAD_METRIC_VARIABLE(Load, "DocumentTiming.NavigationToLoadEventFired") + +#define SXG_PAGE_LOAD_HISTOGRAM(name, sample) \ + { \ + const base::TimeDelta value = sample; \ + PAGE_LOAD_HISTOGRAM(internal::kHistogramSignedExchange##name, value); \ + if (was_cached_) { \ + PAGE_LOAD_HISTOGRAM(internal::kHistogramCachedSignedExchange##name, \ + value); \ + } \ + } + +#undef SXG_LOAD_METRIC_VARIABLE +#undef HISTOGRAM_CACHED_SXG_PREFIX +#undef HISTOGRAM_SXG_PREFIX } // namespace internal @@ -43,8 +63,10 @@ SignedExchangePageLoadMetricsObserver::OnCommit( content::NavigationHandle* navigation_handle, ukm::SourceId source_id) { - if (navigation_handle->IsSignedExchangeInnerResponse()) + if (navigation_handle->IsSignedExchangeInnerResponse()) { + was_cached_ = navigation_handle->WasResponseCached(); return CONTINUE_OBSERVING; + } return STOP_OBSERVING; } @@ -57,8 +79,7 @@ return; } - PAGE_LOAD_HISTOGRAM(internal::kHistogramSignedExchangeFirstPaint, - timing.paint_timing->first_paint.value()); + SXG_PAGE_LOAD_HISTOGRAM(FirstPaint, timing.paint_timing->first_paint.value()); } void SignedExchangePageLoadMetricsObserver::OnFirstContentfulPaintInPage( @@ -69,12 +90,11 @@ return; } - PAGE_LOAD_HISTOGRAM(internal::kHistogramSignedExchangeFirstContentfulPaint, - timing.paint_timing->first_contentful_paint.value()); - PAGE_LOAD_HISTOGRAM( - internal::kHistogramSignedExchangeParseStartToFirstContentfulPaint, - timing.paint_timing->first_contentful_paint.value() - - timing.parse_timing->parse_start.value()); + SXG_PAGE_LOAD_HISTOGRAM(FirstContentfulPaint, + timing.paint_timing->first_contentful_paint.value()); + SXG_PAGE_LOAD_HISTOGRAM(ParseStartToFirstContentfulPaint, + timing.paint_timing->first_contentful_paint.value() - + timing.parse_timing->parse_start.value()); } void SignedExchangePageLoadMetricsObserver:: @@ -86,12 +106,11 @@ return; } - PAGE_LOAD_HISTOGRAM(internal::kHistogramSignedExchangeFirstMeaningfulPaint, - timing.paint_timing->first_meaningful_paint.value()); - PAGE_LOAD_HISTOGRAM( - internal::kHistogramSignedExchangeParseStartToFirstMeaningfulPaint, - timing.paint_timing->first_meaningful_paint.value() - - timing.parse_timing->parse_start.value()); + SXG_PAGE_LOAD_HISTOGRAM(FirstMeaningfulPaint, + timing.paint_timing->first_meaningful_paint.value()); + SXG_PAGE_LOAD_HISTOGRAM(ParseStartToFirstMeaningfulPaint, + timing.paint_timing->first_meaningful_paint.value() - + timing.parse_timing->parse_start.value()); } void SignedExchangePageLoadMetricsObserver::OnDomContentLoadedEventStart( @@ -102,8 +121,8 @@ return; } - PAGE_LOAD_HISTOGRAM( - internal::kHistogramSignedExchangeDomContentLoaded, + SXG_PAGE_LOAD_HISTOGRAM( + DomContentLoaded, timing.document_timing->dom_content_loaded_event_start.value()); } @@ -115,8 +134,8 @@ return; } - PAGE_LOAD_HISTOGRAM(internal::kHistogramSignedExchangeLoad, - timing.document_timing->load_event_start.value()); + SXG_PAGE_LOAD_HISTOGRAM(Load, + timing.document_timing->load_event_start.value()); } void SignedExchangePageLoadMetricsObserver::OnFirstInputInPage( @@ -133,6 +152,13 @@ timing.interactive_timing->first_input_delay.value(), base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromSeconds(60), 50); + if (was_cached_) { + UMA_HISTOGRAM_CUSTOM_TIMES( + internal::kHistogramCachedSignedExchangeFirstInputDelay, + timing.interactive_timing->first_input_delay.value(), + base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromSeconds(60), + 50); + } } void SignedExchangePageLoadMetricsObserver::OnParseStart( @@ -143,6 +169,5 @@ return; } - PAGE_LOAD_HISTOGRAM(internal::kHistogramSignedExchangeParseStart, - timing.parse_timing->parse_start.value()); + SXG_PAGE_LOAD_HISTOGRAM(ParseStart, timing.parse_timing->parse_start.value()); }
diff --git a/chrome/browser/page_load_metrics/observers/signed_exchange_page_load_metrics_observer.h b/chrome/browser/page_load_metrics/observers/signed_exchange_page_load_metrics_observer.h index 4bb3af2..5f6db54 100644 --- a/chrome/browser/page_load_metrics/observers/signed_exchange_page_load_metrics_observer.h +++ b/chrome/browser/page_load_metrics/observers/signed_exchange_page_load_metrics_observer.h
@@ -22,6 +22,19 @@ extern const char kHistogramSignedExchangeDomContentLoaded[]; extern const char kHistogramSignedExchangeLoad[]; +extern const char kHistogramCachedSignedExchangePrefix[]; +extern const char kHistogramCachedSignedExchangeParseStart[]; +extern const char kHistogramCachedSignedExchangeFirstInputDelay[]; +extern const char kHistogramCachedSignedExchangeFirstPaint[]; +extern const char kHistogramCachedSignedExchangeFirstContentfulPaint[]; +extern const char + kHistogramCachedSignedExchangeParseStartToFirstContentfulPaint[]; +extern const char kHistogramCachedSignedExchangeFirstMeaningfulPaint[]; +extern const char + kHistogramCachedSignedExchangeParseStartToFirstMeaningfulPaint[]; +extern const char kHistogramCachedSignedExchangeDomContentLoaded[]; +extern const char kHistogramCachedSignedExchangeLoad[]; + } // namespace internal class SignedExchangePageLoadMetricsObserver @@ -54,6 +67,9 @@ const page_load_metrics::PageLoadExtraInfo& extra_info) override; private: + // True iff the page main resource was served from disk cache. + bool was_cached_ = false; + DISALLOW_COPY_AND_ASSIGN(SignedExchangePageLoadMetricsObserver); };
diff --git a/chrome/browser/page_load_metrics/observers/signed_exchange_page_load_metrics_observer_unittest.cc b/chrome/browser/page_load_metrics/observers/signed_exchange_page_load_metrics_observer_unittest.cc index f4a074f..fc90472 100644 --- a/chrome/browser/page_load_metrics/observers/signed_exchange_page_load_metrics_observer_unittest.cc +++ b/chrome/browser/page_load_metrics/observers/signed_exchange_page_load_metrics_observer_unittest.cc
@@ -26,11 +26,13 @@ std::make_unique<SignedExchangePageLoadMetricsObserver>()); } - void NavigateAndCommitSignedExchange(const GURL& url) { + void NavigateAndCommitSignedExchange(const GURL& url, + bool was_fetched_via_cache) { std::unique_ptr<content::NavigationSimulator> navigation = content::NavigationSimulator::CreateBrowserInitiated(url, web_contents()); navigation->Start(); + navigation->SetWasFetchedViaCache(was_fetched_via_cache); navigation->SetIsSignedExchangeInnerResponse(true); navigation->Commit(); } @@ -46,6 +48,17 @@ } } + void AssertNoCachedSignedExchangeHistogramsLogged() { + base::HistogramTester::CountsMap counts_map = + histogram_tester().GetTotalCountsForPrefix( + internal::kHistogramCachedSignedExchangePrefix); + for (const auto& it : counts_map) { + base::HistogramBase::Count count = it.second; + EXPECT_EQ(0, count) << "Histogram \"" << it.first + << "\" should be empty."; + } + } + void InitializeTestPageLoadTiming( page_load_metrics::mojom::PageLoadTiming* timing) { page_load_metrics::InitPageLoadTimingForTest(timing); @@ -70,6 +83,7 @@ TEST_F(SignedExchangePageLoadMetricsObserverTest, NoMetrics) { AssertNoSignedExchangeHistogramsLogged(); + AssertNoCachedSignedExchangeHistogramsLogged(); } TEST_F(SignedExchangePageLoadMetricsObserverTest, NoSignedExchange) { @@ -80,13 +94,14 @@ SimulateTimingUpdate(timing); AssertNoSignedExchangeHistogramsLogged(); + AssertNoCachedSignedExchangeHistogramsLogged(); } TEST_F(SignedExchangePageLoadMetricsObserverTest, WithSignedExchange) { page_load_metrics::mojom::PageLoadTiming timing; InitializeTestPageLoadTiming(&timing); - NavigateAndCommitSignedExchange(GURL(kDefaultTestUrl)); + NavigateAndCommitSignedExchange(GURL(kDefaultTestUrl), false); SimulateTimingUpdate(timing); histogram_tester().ExpectTotalCount( @@ -135,6 +150,111 @@ histogram_tester().ExpectBucketCount( internal::kHistogramSignedExchangeParseStart, timing.parse_timing->parse_start.value().InMilliseconds(), 1); + + AssertNoCachedSignedExchangeHistogramsLogged(); +} + +TEST_F(SignedExchangePageLoadMetricsObserverTest, WithCachedSignedExchange) { + page_load_metrics::mojom::PageLoadTiming timing; + InitializeTestPageLoadTiming(&timing); + + NavigateAndCommitSignedExchange(GURL(kDefaultTestUrl), true); + SimulateTimingUpdate(timing); + + histogram_tester().ExpectTotalCount( + internal::kHistogramSignedExchangeFirstInputDelay, 1); + histogram_tester().ExpectBucketCount( + internal::kHistogramSignedExchangeFirstInputDelay, + timing.interactive_timing->first_input_delay.value().InMilliseconds(), 1); + + histogram_tester().ExpectTotalCount( + internal::kHistogramSignedExchangeFirstPaint, 1); + histogram_tester().ExpectBucketCount( + internal::kHistogramSignedExchangeFirstPaint, + timing.paint_timing->first_paint.value().InMilliseconds(), 1); + + histogram_tester().ExpectTotalCount( + internal::kHistogramSignedExchangeFirstContentfulPaint, 1); + histogram_tester().ExpectBucketCount( + internal::kHistogramSignedExchangeFirstContentfulPaint, + timing.paint_timing->first_contentful_paint.value().InMilliseconds(), 1); + + histogram_tester().ExpectTotalCount( + internal::kHistogramSignedExchangeParseStartToFirstContentfulPaint, 1); + histogram_tester().ExpectBucketCount( + internal::kHistogramSignedExchangeParseStartToFirstContentfulPaint, + (timing.paint_timing->first_contentful_paint.value() - + timing.parse_timing->parse_start.value()) + .InMilliseconds(), + 1); + + histogram_tester().ExpectTotalCount( + internal::kHistogramSignedExchangeDomContentLoaded, 1); + histogram_tester().ExpectBucketCount( + internal::kHistogramSignedExchangeDomContentLoaded, + timing.document_timing->dom_content_loaded_event_start.value() + .InMilliseconds(), + 1); + + histogram_tester().ExpectTotalCount(internal::kHistogramSignedExchangeLoad, + 1); + histogram_tester().ExpectBucketCount( + internal::kHistogramSignedExchangeLoad, + timing.document_timing->load_event_start.value().InMilliseconds(), 1); + + histogram_tester().ExpectTotalCount( + internal::kHistogramCachedSignedExchangeParseStart, 1); + histogram_tester().ExpectBucketCount( + internal::kHistogramCachedSignedExchangeParseStart, + timing.parse_timing->parse_start.value().InMilliseconds(), 1); + + histogram_tester().ExpectTotalCount( + internal::kHistogramCachedSignedExchangeFirstInputDelay, 1); + histogram_tester().ExpectBucketCount( + internal::kHistogramCachedSignedExchangeFirstInputDelay, + timing.interactive_timing->first_input_delay.value().InMilliseconds(), 1); + + histogram_tester().ExpectTotalCount( + internal::kHistogramCachedSignedExchangeFirstPaint, 1); + histogram_tester().ExpectBucketCount( + internal::kHistogramCachedSignedExchangeFirstPaint, + timing.paint_timing->first_paint.value().InMilliseconds(), 1); + + histogram_tester().ExpectTotalCount( + internal::kHistogramCachedSignedExchangeFirstContentfulPaint, 1); + histogram_tester().ExpectBucketCount( + internal::kHistogramCachedSignedExchangeFirstContentfulPaint, + timing.paint_timing->first_contentful_paint.value().InMilliseconds(), 1); + + histogram_tester().ExpectTotalCount( + internal::kHistogramCachedSignedExchangeParseStartToFirstContentfulPaint, + 1); + histogram_tester().ExpectBucketCount( + internal::kHistogramCachedSignedExchangeParseStartToFirstContentfulPaint, + (timing.paint_timing->first_contentful_paint.value() - + timing.parse_timing->parse_start.value()) + .InMilliseconds(), + 1); + + histogram_tester().ExpectTotalCount( + internal::kHistogramCachedSignedExchangeDomContentLoaded, 1); + histogram_tester().ExpectBucketCount( + internal::kHistogramCachedSignedExchangeDomContentLoaded, + timing.document_timing->dom_content_loaded_event_start.value() + .InMilliseconds(), + 1); + + histogram_tester().ExpectTotalCount( + internal::kHistogramCachedSignedExchangeLoad, 1); + histogram_tester().ExpectBucketCount( + internal::kHistogramCachedSignedExchangeLoad, + timing.document_timing->load_event_start.value().InMilliseconds(), 1); + + histogram_tester().ExpectTotalCount( + internal::kHistogramCachedSignedExchangeParseStart, 1); + histogram_tester().ExpectBucketCount( + internal::kHistogramCachedSignedExchangeParseStart, + timing.parse_timing->parse_start.value().InMilliseconds(), 1); } TEST_F(SignedExchangePageLoadMetricsObserverTest, @@ -143,7 +263,7 @@ page_load_metrics::InitPageLoadTimingForTest(&timing); PopulateRequiredTimingFields(&timing); - NavigateAndCommitSignedExchange(GURL(kDefaultTestUrl)); + NavigateAndCommitSignedExchange(GURL(kDefaultTestUrl), true); SimulateTimingUpdate(timing); // Background the tab, then foreground it. @@ -154,4 +274,5 @@ SimulateTimingUpdate(timing); AssertNoSignedExchangeHistogramsLogged(); + AssertNoCachedSignedExchangeHistogramsLogged(); }
diff --git a/chrome/browser/password_manager/password_generation_controller.h b/chrome/browser/password_manager/password_generation_controller.h index 1d3077d..fe1c499 100644 --- a/chrome/browser/password_manager/password_generation_controller.h +++ b/chrome/browser/password_manager/password_generation_controller.h
@@ -69,7 +69,10 @@ virtual void OnGenerationRequested() = 0; // Called from the modal dialog if the user accepted the generated password. - virtual void GeneratedPasswordAccepted(const base::string16& password) = 0; + // |driver| is used to communicate the message back to the renderer. + virtual void GeneratedPasswordAccepted( + const base::string16& password, + base::WeakPtr<password_manager::PasswordManagerDriver> driver) = 0; // Called from the modal dialog if the user rejected the generated password. virtual void GeneratedPasswordRejected() = 0;
diff --git a/chrome/browser/password_manager/password_generation_controller_impl.cc b/chrome/browser/password_manager/password_generation_controller_impl.cc index 94a55c4..0e1431d 100644 --- a/chrome/browser/password_manager/password_generation_controller_impl.cc +++ b/chrome/browser/password_manager/password_generation_controller_impl.cc
@@ -97,6 +97,7 @@ if (manual_filling_controller_ && generation_element_data_) { manual_filling_controller_->OnAutomaticGenerationStatusChanged(false); } + target_frame_driver_ = nullptr; generation_element_data_.reset(); } @@ -116,15 +117,17 @@ ->ReportSpecPriorityForGeneratedPassword(generation_element_data_->form, spec_priority); } - dialog_view_->Show(password); + dialog_view_->Show(password, std::move(target_frame_driver_)); + target_frame_driver_ = nullptr; } void PasswordGenerationControllerImpl::GeneratedPasswordAccepted( - const base::string16& password) { - if (!target_frame_driver_) + const base::string16& password, + base::WeakPtr<password_manager::PasswordManagerDriver> driver) { + if (!driver) return; RecordGenerationDialogDismissal(true); - target_frame_driver_->GeneratedPasswordAccepted(password); + driver->GeneratedPasswordAccepted(password); dialog_view_.reset(); }
diff --git a/chrome/browser/password_manager/password_generation_controller_impl.h b/chrome/browser/password_manager/password_generation_controller_impl.h index 4333efc..3a6ed7f 100644 --- a/chrome/browser/password_manager/password_generation_controller_impl.h +++ b/chrome/browser/password_manager/password_generation_controller_impl.h
@@ -37,7 +37,9 @@ override; void OnGenerationElementLostFocus() override; void OnGenerationRequested() override; - void GeneratedPasswordAccepted(const base::string16& password) override; + void GeneratedPasswordAccepted( + const base::string16& password, + base::WeakPtr<password_manager::PasswordManagerDriver> driver) override; void GeneratedPasswordRejected() override; gfx::NativeWindow top_level_native_window() const override;
diff --git a/chrome/browser/password_manager/password_generation_controller_impl_unittest.cc b/chrome/browser/password_manager/password_generation_controller_impl_unittest.cc index 44e2150..aec5d3f 100644 --- a/chrome/browser/password_manager/password_generation_controller_impl_unittest.cc +++ b/chrome/browser/password_manager/password_generation_controller_impl_unittest.cc
@@ -39,6 +39,7 @@ MOCK_METHOD0(GetPasswordGenerationHelper, password_manager::PasswordGenerationFrameHelper*()); + MOCK_METHOD1(GeneratedPasswordAccepted, void(const base::string16&)); private: DISALLOW_COPY_AND_ASSIGN(MockPasswordManagerDriver); @@ -68,7 +69,9 @@ public: MockPasswordGenerationDialogView() = default; - MOCK_METHOD1(Show, void(base::string16&)); + MOCK_METHOD2(Show, + void(base::string16&, + base::WeakPtr<password_manager::PasswordManagerDriver>)); private: DISALLOW_COPY_AND_ASSIGN(MockPasswordGenerationDialogView); @@ -102,6 +105,10 @@ return data; } +MATCHER_P(PointsToSameAddress, expected, "") { + return arg.get() == expected; +} + } // namespace class PasswordGenerationControllerTest @@ -236,7 +243,9 @@ GeneratePassword(_, form_signature, field_signature, uint32_t(new_ui_data.max_length), _)) .WillOnce(Return(generated_password)); - EXPECT_CALL(*raw_dialog_view, Show(generated_password)); + EXPECT_CALL(*raw_dialog_view, + Show(generated_password, + PointsToSameAddress(mock_password_manager_driver_.get()))); controller()->OnGenerationRequested(); } @@ -262,8 +271,30 @@ base::HistogramTester histogram_tester; controller()->OnGenerationRequested(); - controller()->GeneratedPasswordAccepted(test_password); + controller()->GeneratedPasswordAccepted( + test_password, mock_password_manager_driver_->AsWeakPtr()); histogram_tester.ExpectUniqueSample( "KeyboardAccessory.GeneratedPasswordDialog", true, 1); } + +TEST_F(PasswordGenerationControllerTest, + RelaysGenerationAcceptedToCorrectDriver) { + base::string16 test_password = ASCIIToUTF16("t3stp@ssw0rd"); + + InitializeGeneration(test_password); + + controller()->OnGenerationRequested(); + + MockPasswordManagerDriver wrong_driver; + EXPECT_CALL(mock_manual_filling_controller_, + OnAutomaticGenerationStatusChanged(true)); + controller()->OnAutomaticGenerationAvailable(GetTestGenerationUIData2(), + wrong_driver.AsWeakPtr()); + + EXPECT_CALL(*mock_password_manager_driver_, + GeneratedPasswordAccepted(test_password)); + EXPECT_CALL(wrong_driver, GeneratedPasswordAccepted(_)).Times(0); + controller()->GeneratedPasswordAccepted( + test_password, mock_password_manager_driver_->AsWeakPtr()); +}
diff --git a/chrome/browser/password_manager/password_generation_dialog_view_interface.h b/chrome/browser/password_manager/password_generation_dialog_view_interface.h index 3e64708..52b3637a7 100644 --- a/chrome/browser/password_manager/password_generation_dialog_view_interface.h +++ b/chrome/browser/password_manager/password_generation_dialog_view_interface.h
@@ -5,16 +5,22 @@ #ifndef CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_GENERATION_DIALOG_VIEW_INTERFACE_H_ #define CHROME_BROWSER_PASSWORD_MANAGER_PASSWORD_GENERATION_DIALOG_VIEW_INTERFACE_H_ +#include "base/memory/weak_ptr.h" #include "base/strings/string16.h" - class PasswordGenerationController; +namespace password_manager { +class PasswordManagerDriver; +} // namespace password_manager + class PasswordGenerationDialogViewInterface { public: virtual ~PasswordGenerationDialogViewInterface() = default; // Called to show the dialog. |password| is the generated password. - virtual void Show(base::string16& password) = 0; + virtual void Show(base::string16& password, + base::WeakPtr<password_manager::PasswordManagerDriver> + target_frame_driver) = 0; private: friend class PasswordGenerationControllerImpl;
diff --git a/chrome/browser/performance_manager/graph/process_node_impl.cc b/chrome/browser/performance_manager/graph/process_node_impl.cc index 9833e60..f4e06c7 100644 --- a/chrome/browser/performance_manager/graph/process_node_impl.cc +++ b/chrome/browser/performance_manager/graph/process_node_impl.cc
@@ -69,12 +69,6 @@ SetProcessImpl(std::move(process), pid, launch_time); } -void ProcessNodeImpl::OnRendererIsBloated() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - for (auto& observer : observers()) - observer.OnRendererIsBloated(this); -} - const base::flat_set<FrameNodeImpl*>& ProcessNodeImpl::GetFrameNodes() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return frame_nodes_;
diff --git a/chrome/browser/performance_manager/graph/process_node_impl.h b/chrome/browser/performance_manager/graph/process_node_impl.h index a3bef1b..c95d009 100644 --- a/chrome/browser/performance_manager/graph/process_node_impl.h +++ b/chrome/browser/performance_manager/graph/process_node_impl.h
@@ -46,7 +46,6 @@ // resource_coordinator::mojom::ProcessCoordinationUnit implementation. void SetExpectedTaskQueueingDuration(base::TimeDelta duration) override; void SetMainThreadTaskLoadIsLow(bool main_thread_task_load_is_low) override; - void OnRendererIsBloated() override; // CPU usage is expressed as the average percentage of cores occupied over the // last measurement interval. One core fully occupied would be 100, while two
diff --git a/chrome/browser/performance_manager/observers/page_signal_generator_impl.cc b/chrome/browser/performance_manager/observers/page_signal_generator_impl.cc index e7856db31..5c3f0b2 100644 --- a/chrome/browser/performance_manager/observers/page_signal_generator_impl.cc +++ b/chrome/browser/performance_manager/observers/page_signal_generator_impl.cc
@@ -18,24 +18,6 @@ namespace performance_manager { -namespace { - -// These values are persisted to logs. Entries should not be renumbered and -// numeric values should never be reused. -enum class BloatedRendererHandlingInResourceCoordinator { - kForwardedToBrowser = 0, - kIgnoredDueToMultiplePages = 1, - kMaxValue = kIgnoredDueToMultiplePages -}; - -void RecordBloatedRendererHandling( - BloatedRendererHandlingInResourceCoordinator handling) { - UMA_HISTOGRAM_ENUMERATION("BloatedRenderer.HandlingInResourceCoordinator", - handling); -} - -} // anonymous namespace - PageSignalGeneratorImpl::PageSignalGeneratorImpl() = default; PageSignalGeneratorImpl::~PageSignalGeneratorImpl() { @@ -131,22 +113,6 @@ } } -void PageSignalGeneratorImpl::OnRendererIsBloated( - ProcessNodeImpl* process_node) { - // Currently bloated renderer handling supports only a single page. - auto* page_node = process_node->GetPageNodeIfExclusive(); - if (page_node) { - DispatchPageSignal(page_node, - &resource_coordinator::mojom::PageSignalReceiver:: - NotifyRendererIsBloated); - RecordBloatedRendererHandling( - BloatedRendererHandlingInResourceCoordinator::kForwardedToBrowser); - } else { - RecordBloatedRendererHandling(BloatedRendererHandlingInResourceCoordinator:: - kIgnoredDueToMultiplePages); - } -} - void PageSignalGeneratorImpl::OnProcessCPUUsageReady( SystemNodeImpl* system_node) { base::TimeTicks measurement_start =
diff --git a/chrome/browser/performance_manager/observers/page_signal_generator_impl.h b/chrome/browser/performance_manager/observers/page_signal_generator_impl.h index 9e5fe4ff..530271b 100644 --- a/chrome/browser/performance_manager/observers/page_signal_generator_impl.h +++ b/chrome/browser/performance_manager/observers/page_signal_generator_impl.h
@@ -45,7 +45,6 @@ void OnLifecycleStateChanged(PageNodeImpl* page_node) override; void OnExpectedTaskQueueingDurationSample( ProcessNodeImpl* process_node) override; - void OnRendererIsBloated(ProcessNodeImpl* process_node) override; void OnProcessCPUUsageReady(SystemNodeImpl* system_node) override; void BindToInterface(
diff --git a/chrome/browser/performance_manager/observers/page_signal_generator_impl_unittest.cc b/chrome/browser/performance_manager/observers/page_signal_generator_impl_unittest.cc index 6a37eea..adf14465 100644 --- a/chrome/browser/performance_manager/observers/page_signal_generator_impl_unittest.cc +++ b/chrome/browser/performance_manager/observers/page_signal_generator_impl_unittest.cc
@@ -67,9 +67,6 @@ MOCK_METHOD1(NotifyNonPersistentNotificationCreated, void(const resource_coordinator::PageNavigationIdentity& page_navigation_id)); - MOCK_METHOD1(NotifyRendererIsBloated, - void(const resource_coordinator::PageNavigationIdentity& - page_navigation_id)); MOCK_METHOD4(OnLoadTimePerformanceEstimate, void(const resource_coordinator::PageNavigationIdentity& page_navigation_id, @@ -207,40 +204,6 @@ ::testing::Mock::VerifyAndClear(&mock_receiver); } -TEST_F(PageSignalGeneratorImplTest, NotifyRendererIsBloatedSinglePage) { - MockSinglePageInSingleProcessGraph mock_graph(graph()); - auto* process = mock_graph.process.get(); - auto* psg = page_signal_generator(); - - // Create a mock receiver and register it against the psg. - resource_coordinator::mojom::PageSignalReceiverPtr mock_receiver_ptr; - MockPageSignalReceiver mock_receiver(mojo::MakeRequest(&mock_receiver_ptr)); - psg->AddReceiver(std::move(mock_receiver_ptr)); - - base::RunLoop run_loop; - EXPECT_CALL(mock_receiver, NotifyRendererIsBloated(_)); - process->OnRendererIsBloated(); - run_loop.RunUntilIdle(); - ::testing::Mock::VerifyAndClear(&mock_receiver); -} - -TEST_F(PageSignalGeneratorImplTest, NotifyRendererIsBloatedMultiplePages) { - MockMultiplePagesInSingleProcessGraph mock_graph(graph()); - auto* process = mock_graph.process.get(); - auto* psg = page_signal_generator(); - - // Create a mock receiver and register it against the psg. - resource_coordinator::mojom::PageSignalReceiverPtr mock_receiver_ptr; - MockPageSignalReceiver mock_receiver(mojo::MakeRequest(&mock_receiver_ptr)); - psg->AddReceiver(std::move(mock_receiver_ptr)); - - base::RunLoop run_loop; - EXPECT_CALL(mock_receiver, NotifyRendererIsBloated(_)).Times(0); - process->OnRendererIsBloated(); - run_loop.RunUntilIdle(); - ::testing::Mock::VerifyAndClear(&mock_receiver); -} - namespace { std::unique_ptr<ProcessResourceMeasurementBatch> CreateMeasurementBatch(
diff --git a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc index 1d84c94..8a4fcf4 100644 --- a/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc +++ b/chrome/browser/picture_in_picture/picture_in_picture_window_controller_browsertest.cc
@@ -527,6 +527,46 @@ .WaitAndGetTitle()); } +// Tests that when closing a Picture-in-Picture window, the video element +// no longer in Picture-in-Picture can't enter Picture-in-Picture right away. +IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest, + CloseWindowCantEnterPictureInPictureAgain) { + GURL test_page_url = ui_test_utils::GetTestUrl( + base::FilePath(base::FilePath::kCurrentDirectory), + base::FilePath( + FILE_PATH_LITERAL("media/picture-in-picture/window-size.html"))); + ui_test_utils::NavigateToURL(browser(), test_page_url); + + content::WebContents* active_web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(active_web_contents); + + SetUpWindowController(active_web_contents); + + bool result = false; + ASSERT_TRUE(content::ExecuteScriptAndExtractBool( + active_web_contents, "enterPictureInPicture();", &result)); + EXPECT_TRUE(result); + + EXPECT_TRUE(content::ExecuteScriptWithoutUserGesture( + active_web_contents, "tryToEnterPictureInPictureAfterLeaving();")); + + bool in_picture_in_picture = false; + EXPECT_TRUE(content::ExecuteScriptWithoutUserGestureAndExtractBool( + active_web_contents, "isInPictureInPicture();", &in_picture_in_picture)); + EXPECT_TRUE(in_picture_in_picture); + + ASSERT_TRUE(window_controller()); + window_controller()->Close(true /* should_pause_video */, + true /* should_reset_pip_player */); + + base::string16 expected_title = + base::ASCIIToUTF16("failed to enter Picture-in-Picture after leaving"); + EXPECT_EQ(expected_title, + content::TitleWatcher(active_web_contents, expected_title) + .WaitAndGetTitle()); +} + // Tests that when closing a Picture-in-Picture window from the Web API, the // video element is not paused. IN_PROC_BROWSER_TEST_F(PictureInPictureWindowControllerBrowserTest,
diff --git a/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc b/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc index a8209f3bd..b55457be 100644 --- a/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc +++ b/chrome/browser/policy/cloud/machine_level_user_cloud_policy_browsertest.cc
@@ -433,6 +433,7 @@ std::unique_ptr<MachineLevelUserCloudPolicyStore> policy_store = MachineLevelUserCloudPolicyStore::Create( dm_token, client_id, user_data_dir, + /*cloud_policy_overrides=*/false, base::CreateSequencedTaskRunnerWithTraits( {base::MayBlock(), base::TaskPriority::BEST_EFFORT})); policy_store->AddObserver(&observer);
diff --git a/chrome/browser/policy/machine_level_user_cloud_policy_controller.cc b/chrome/browser/policy/machine_level_user_cloud_policy_controller.cc index a729e44..8fbb9f1 100644 --- a/chrome/browser/policy/machine_level_user_cloud_policy_controller.cc +++ b/chrome/browser/policy/machine_level_user_cloud_policy_controller.cc
@@ -122,11 +122,9 @@ DVLOG(1) << "Creating machine level cloud policy manager"; - bool does_cloud_policy_has_priority = + bool cloud_policy_has_priority = DoesCloudPolicyHasPriority(platform_provider); - if (does_cloud_policy_has_priority) { - // TODO(crbug.com/749530): Pass this flag to - // MachineLevelUserCloudPolicyManager. + if (cloud_policy_has_priority) { DVLOG(1) << "Cloud policies are now overriding platform policies with " "machine scope."; } @@ -135,7 +133,7 @@ user_data_dir.Append(MachineLevelUserCloudPolicyController::kPolicyDir); std::unique_ptr<MachineLevelUserCloudPolicyStore> policy_store = MachineLevelUserCloudPolicyStore::Create( - dm_token, client_id, policy_dir, + dm_token, client_id, policy_dir, cloud_policy_has_priority, base::CreateSequencedTaskRunnerWithTraits( {base::MayBlock(), base::TaskPriority::BEST_EFFORT})); return std::make_unique<MachineLevelUserCloudPolicyManager>(
diff --git a/chrome/browser/policy/policy_prefs_browsertest.cc b/chrome/browser/policy/policy_prefs_browsertest.cc index a945c702..5273a7e9 100644 --- a/chrome/browser/policy/policy_prefs_browsertest.cc +++ b/chrome/browser/policy/policy_prefs_browsertest.cc
@@ -52,8 +52,8 @@ #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" -using testing::Return; using testing::_; +using testing::Return; namespace policy { @@ -131,9 +131,7 @@ return indicator_test_setup_js_; } - const std::string& indicator_selector() const { - return indicator_selector_; - } + const std::string& indicator_selector() const { return indicator_selector_; } const std::vector<std::unique_ptr<IndicatorTestCase>>& indicator_test_cases() const { @@ -246,7 +244,7 @@ } int error_code = -1; std::string error_string; - base::DictionaryValue* dict = NULL; + base::DictionaryValue* dict = nullptr; std::unique_ptr<base::Value> value = base::JSONReader::ReadAndReturnErrorDeprecated( json, base::JSON_PARSE_RFC, &error_code, &error_string); @@ -254,31 +252,26 @@ ADD_FAILURE() << "Error parsing policy_test_cases.json: " << error_string; return; } - for (base::DictionaryValue::Iterator it(*dict); !it.IsAtEnd(); - it.Advance()) { - const std::string policy_name = GetPolicyName(it.key()); + for (const auto& it : dict->DictItems()) { + const std::string policy_name = GetPolicyName(it.first); if (policy_name == kTemplateSampleTest) continue; - PolicyTestCase* policy_test_case = GetPolicyTestCase(dict, it.key()); + PolicyTestCase* policy_test_case = GetPolicyTestCase(dict, it.first); if (policy_test_case) policy_test_cases_[policy_name].push_back(policy_test_case); } } ~PolicyTestCases() { - for (iterator policy = policy_test_cases_.begin(); - policy != policy_test_cases_.end(); - ++policy) { - for (auto test_case = policy->second.begin(); - test_case != policy->second.end(); ++test_case) { - delete *test_case; - } + for (const auto& policy : policy_test_cases_) { + for (PolicyTestCase* test_case : policy.second) + delete test_case; } } const PolicyTestCaseVector* Get(const std::string& name) const { const iterator it = policy_test_cases_.find(name); - return it == end() ? NULL : &it->second; + return it == end() ? nullptr : &it->second; } const PolicyTestCaseMap& map() const { return policy_test_cases_; } @@ -288,9 +281,9 @@ private: PolicyTestCase* GetPolicyTestCase(const base::DictionaryValue* tests, const std::string& name) { - const base::DictionaryValue* policy_test_dict = NULL; + const base::DictionaryValue* policy_test_dict = nullptr; if (!tests->GetDictionaryWithoutPathExpansion(name, &policy_test_dict)) - return NULL; + return nullptr; bool is_official_only = false; policy_test_dict->GetBoolean("official_only", &is_official_only); bool can_be_recommended = false; @@ -298,11 +291,9 @@ std::string indicator_selector; policy_test_dict->GetString("indicator_selector", &indicator_selector); - PolicyTestCase* policy_test_case = new PolicyTestCase(name, - is_official_only, - can_be_recommended, - indicator_selector); - const base::ListValue* os_list = NULL; + PolicyTestCase* policy_test_case = new PolicyTestCase( + name, is_official_only, can_be_recommended, indicator_selector); + const base::ListValue* os_list = nullptr; if (policy_test_dict->GetList("os", &os_list)) { for (size_t i = 0; i < os_list->GetSize(); ++i) { std::string os; @@ -311,13 +302,13 @@ } } - const base::DictionaryValue* policy = NULL; + const base::DictionaryValue* policy = nullptr; if (policy_test_dict->GetDictionary("test_policy", &policy)) policy_test_case->SetTestPolicy(*policy); - const base::ListValue* pref_mappings = NULL; + const base::ListValue* pref_mappings = nullptr; if (policy_test_dict->GetList("pref_mappings", &pref_mappings)) { for (size_t i = 0; i < pref_mappings->GetSize(); ++i) { - const base::DictionaryValue* pref_mapping_dict = NULL; + const base::DictionaryValue* pref_mapping_dict = nullptr; std::string pref; if (!pref_mappings->GetDictionary(i, &pref_mapping_dict) || !pref_mapping_dict->GetString("pref", &pref)) { @@ -343,11 +334,11 @@ auto pref_mapping = std::make_unique<PrefMapping>( pref, is_local_state, check_for_mandatory, check_for_recommended, indicator_test_url, indicator_test_setup_js, indicator_selector); - const base::ListValue* indicator_tests = NULL; + const base::ListValue* indicator_tests = nullptr; if (pref_mapping_dict->GetList("indicator_tests", &indicator_tests)) { for (size_t i = 0; i < indicator_tests->GetSize(); ++i) { - const base::DictionaryValue* indicator_test_dict = NULL; - const base::DictionaryValue* policy = NULL; + const base::DictionaryValue* indicator_test_dict = nullptr; + const base::DictionaryValue* policy = nullptr; if (!indicator_tests->GetDictionary(i, &indicator_test_dict) || !indicator_test_dict->GetDictionary("policy", &policy)) { ADD_FAILURE() << "Malformed indicator_tests entry for " << name @@ -391,22 +382,24 @@ auto policy = policy_test_cases.map().find(it.key()); if (policy == policy_test_cases.map().end()) { ADD_FAILURE() << "Missing policy test case for: " << it.key(); - } else { - bool has_test_case_for_this_os = false; - for (auto test_case = policy->second.begin(); - test_case != policy->second.end() && !has_test_case_for_this_os; - ++test_case) { - has_test_case_for_this_os |= (*test_case)->IsSupported(); - } - // This can only be a warning as many policies are not really testable - // this way and only present as a single line in the file. - // Although they could at least contain the "os" and "test_policy" fields. - // See http://crbug.com/791125. - LOG_IF(WARNING, !has_test_case_for_this_os) - << "Policy " << policy->first - << " is marked as supported on this OS in policy_templates.json but " - << "have a test for this platform in policy_test_cases.json."; + continue; } + + bool has_test_case_for_this_os = false; + for (const PolicyTestCase* test_case : policy->second) { + has_test_case_for_this_os |= test_case->IsSupported(); + if (has_test_case_for_this_os) + break; + } + + // This can only be a warning as many policies are not really testable + // this way and only present as a single line in the file. + // Although they could at least contain the "os" and "test_policy" fields. + // See http://crbug.com/791125. + LOG_IF(WARNING, !has_test_case_for_this_os) + << "Policy " << policy->first + << " is marked as supported on this OS in policy_templates.json but " + << "have a test for this platform in policy_test_cases.json."; } } @@ -434,16 +427,15 @@ void SetProviderPolicy(const base::DictionaryValue& policies, PolicyLevel level) { PolicyMap policy_map; - for (base::DictionaryValue::Iterator it(policies); - !it.IsAtEnd(); it.Advance()) { - const PolicyDetails* policy_details = GetChromePolicyDetails(it.key()); + for (const auto& it : policies.DictItems()) { + const PolicyDetails* policy_details = GetChromePolicyDetails(it.first); ASSERT_TRUE(policy_details); policy_map.Set( - it.key(), level, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, - it.value().CreateDeepCopy(), - base::WrapUnique(policy_details->max_external_data_size - ? new ExternalDataFetcher(nullptr, it.key()) - : nullptr)); + it.first, level, POLICY_SCOPE_USER, POLICY_SOURCE_CLOUD, + it.second.CreateDeepCopy(), + policy_details->max_external_data_size + ? std::make_unique<ExternalDataFetcher>(nullptr, it.first) + : nullptr); } provider_.UpdateChromePolicy(policy_map); base::RunLoop().RunUntilIdle(); @@ -461,11 +453,10 @@ PrefService* user_prefs = browser()->profile()->GetPrefs(); const PolicyTestCases test_cases; - for (auto policy = test_cases.begin(); policy != test_cases.end(); ++policy) { - for (auto test_case = policy->second.begin(); - test_case != policy->second.end(); ++test_case) { - const auto& pref_mappings = (*test_case)->pref_mappings(); - if (!chrome_schema.GetKnownProperty(policy->first).valid()) { + for (const auto& policy : test_cases) { + for (const PolicyTestCase* test_case : policy.second) { + const auto& pref_mappings = test_case->pref_mappings(); + if (!chrome_schema.GetKnownProperty(policy.first).valid()) { // If the policy is supported on this platform according to the test it // should be known otherwise we signal this as a failure. // ===================================================================== @@ -476,17 +467,17 @@ // replace it's definition with a single "note" value stating its // deprecation date (see other examples present in the file already). // ===================================================================== - EXPECT_FALSE((*test_case)->IsSupported()) - << "Policy " << policy->first + EXPECT_FALSE(test_case->IsSupported()) + << "Policy " << policy.first << " is marked as supported on this OS but does not exist in the " << "Chrome policy schema."; continue; } - if (!(*test_case)->IsSupported() || pref_mappings.empty()) + if (!test_case->IsSupported() || pref_mappings.empty()) continue; - LOG(INFO) << "Testing policy: " << policy->first; + LOG(INFO) << "Testing policy: " << policy.first; for (const auto& pref_mapping : pref_mappings) { // Skip Chrome OS preferences that use a different backend and cannot be @@ -505,7 +496,8 @@ // The preference must have been registered. const PrefService::Preference* pref = prefs->FindPreference(pref_mapping->pref().c_str()); - ASSERT_TRUE(pref); + ASSERT_TRUE(pref) << "Pref " << pref_mapping->pref().c_str() + << " not registered"; // Verify that setting the policy overrides the pref. ClearProviderPolicy(); @@ -515,7 +507,8 @@ EXPECT_FALSE(pref->IsUserControlled()); EXPECT_FALSE(pref->IsManaged()); - SetProviderPolicy((*test_case)->test_policy(), POLICY_LEVEL_MANDATORY); + ASSERT_NO_FATAL_FAILURE(SetProviderPolicy(test_case->test_policy(), + POLICY_LEVEL_MANDATORY)); EXPECT_FALSE(pref->IsDefaultValue()); EXPECT_FALSE(pref->IsUserModifiable()); EXPECT_FALSE(pref->IsUserControlled());
diff --git a/chrome/browser/prefs/pref_service_incognito_whitelist.cc b/chrome/browser/prefs/pref_service_incognito_whitelist.cc index c503165..0c6951a 100644 --- a/chrome/browser/prefs/pref_service_incognito_whitelist.cc +++ b/chrome/browser/prefs/pref_service_incognito_whitelist.cc
@@ -47,6 +47,7 @@ ash::prefs::kAccessibilityAutoclickDelayMs, ash::prefs::kAccessibilityAutoclickEventType, ash::prefs::kAccessibilityAutoclickRevertToLeftClick, + ash::prefs::kAccessibilityAutoclickStabilizePosition, ash::prefs::kAccessibilityAutoclickMovementThreshold, ash::prefs::kAccessibilityCaretHighlightEnabled, ash::prefs::kAccessibilityCursorHighlightEnabled, @@ -54,14 +55,17 @@ ash::prefs::kAccessibilitySelectToSpeakEnabled, ash::prefs::kAccessibilitySwitchAccessEnabled, ash::prefs::kAccessibilityDictationEnabled, - ash::prefs::kDockedMagnifierEnabled, ash::prefs::kDockedMagnifierScale, + ash::prefs::kDockedMagnifierEnabled, + ash::prefs::kDockedMagnifierScale, ash::prefs::kDockedMagnifierAcceleratorDialogHasBeenAccepted, ash::prefs::kHighContrastAcceleratorDialogHasBeenAccepted, ash::prefs::kScreenMagnifierAcceleratorDialogHasBeenAccepted, ash::prefs::kShouldAlwaysShowAccessibilityMenu, #endif // defined(OS_CHROMEOS) #if !defined(OS_ANDROID) - kAnimationPolicyAllowed, kAnimationPolicyOnce, kAnimationPolicyNone, + kAnimationPolicyAllowed, + kAnimationPolicyOnce, + kAnimationPolicyNone, #endif // !defined(OS_ANDROID) #if BUILDFLAG(ENABLE_EXTENSIONS) prefs::kAnimationPolicy, @@ -81,14 +85,19 @@ // Metrics preferences are out of profile scope and are merged between // incognito and regular modes. - metrics::prefs::kInstallDate, metrics::prefs::kMetricsClientID, - metrics::prefs::kMetricsDefaultOptIn, metrics::prefs::kMetricsInitialLogs, - metrics::prefs::kMetricsLowEntropySource, metrics::prefs::kMetricsMachineId, - metrics::prefs::kMetricsOngoingLogs, metrics::prefs::kMetricsResetIds, + metrics::prefs::kInstallDate, + metrics::prefs::kMetricsClientID, + metrics::prefs::kMetricsDefaultOptIn, + metrics::prefs::kMetricsInitialLogs, + metrics::prefs::kMetricsLowEntropySource, + metrics::prefs::kMetricsMachineId, + metrics::prefs::kMetricsOngoingLogs, + metrics::prefs::kMetricsResetIds, metrics::prefs::kMetricsReportingEnabled, metrics::prefs::kMetricsReportingEnabledTimestamp, - metrics::prefs::kMetricsSessionID, metrics::prefs::kMetricsLastSeenPrefix, + metrics::prefs::kMetricsSessionID, + metrics::prefs::kMetricsLastSeenPrefix, metrics::prefs::kStabilityBreakpadRegistrationFail, metrics::prefs::kStabilityBreakpadRegistrationSuccess, metrics::prefs::kStabilityBrowserLastLiveTimeStamp, @@ -123,8 +132,10 @@ metrics::prefs::kStabilityVersionMismatchCount, metrics::prefs::kUninstallLaunchCount, metrics::prefs::kUninstallMetricsPageLoadCount, - metrics::prefs::kUninstallMetricsUptimeSec, metrics::prefs::kUkmCellDataUse, - metrics::prefs::kUmaCellDataUse, metrics::prefs::kUserCellDataUse, + metrics::prefs::kUninstallMetricsUptimeSec, + metrics::prefs::kUkmCellDataUse, + metrics::prefs::kUmaCellDataUse, + metrics::prefs::kUserCellDataUse, #if defined(OS_ANDROID) // Clipboard modification state is updated over all profiles. @@ -134,21 +145,27 @@ // Default browser bar's status is aggregated between regular and incognito // modes. prefs::kBrowserSuppressDefaultBrowserPrompt, - prefs::kDefaultBrowserLastDeclined, prefs::kDefaultBrowserSettingEnabled, + prefs::kDefaultBrowserLastDeclined, + prefs::kDefaultBrowserSettingEnabled, prefs::kResetCheckDefaultBrowser, // Devtools preferences are stored cross profiles as they are not storing // user data and just keep debugging environment settings. - prefs::kDevToolsAdbKey, prefs::kDevToolsAvailability, - prefs::kDevToolsDiscoverUsbDevicesEnabled, prefs::kDevToolsEditedFiles, - prefs::kDevToolsFileSystemPaths, prefs::kDevToolsPortForwardingEnabled, + prefs::kDevToolsAdbKey, + prefs::kDevToolsAvailability, + prefs::kDevToolsDiscoverUsbDevicesEnabled, + prefs::kDevToolsEditedFiles, + prefs::kDevToolsFileSystemPaths, + prefs::kDevToolsPortForwardingEnabled, prefs::kDevToolsPortForwardingDefaultSet, - prefs::kDevToolsPortForwardingConfig, prefs::kDevToolsPreferences, + prefs::kDevToolsPortForwardingConfig, + prefs::kDevToolsPreferences, prefs::kDevToolsDiscoverTCPTargetsEnabled, prefs::kDevToolsTCPDiscoveryConfig, // Google URL prefs don't store user data and just keep track of the URL. - prefs::kLastKnownGoogleURL, prefs::kLastPromptedGoogleURL, + prefs::kLastKnownGoogleURL, + prefs::kLastPromptedGoogleURL, #if defined(OS_WIN) // The total number of times that network profile warning is shown is @@ -157,8 +174,10 @@ #endif // Tab stats metrics are aggregated between regular and incognio mode. - prefs::kTabStatsTotalTabCountMax, prefs::kTabStatsMaxTabsPerWindow, - prefs::kTabStatsWindowCountMax, prefs::kTabStatsDailySample, + prefs::kTabStatsTotalTabCountMax, + prefs::kTabStatsMaxTabsPerWindow, + prefs::kTabStatsWindowCountMax, + prefs::kTabStatsDailySample, #if defined(OS_MACOSX) prefs::kShowFullscreenToolbar, @@ -173,7 +192,8 @@ // Rappor preferences are not used in incognito mode, but they are written // in startup if they don't exist. So if the startup would be in incognito, // they need to be persisted. - rappor::prefs::kRapporCohortSeed, rappor::prefs::kRapporSecret, + rappor::prefs::kRapporCohortSeed, + rappor::prefs::kRapporSecret, // Reading list preferences are common between incognito and regular mode. reading_list::prefs::kReadingListHasUnseenEntries, @@ -181,7 +201,8 @@ // Although UKMs are not collected in incognito, theses preferences may be // changed by UMA/Sync/Unity consent, and need to be the same between // incognito and regular modes. - ukm::prefs::kUkmClientId, ukm::prefs::kUkmPersistedLogs, + ukm::prefs::kUkmClientId, + ukm::prefs::kUkmPersistedLogs, ukm::prefs::kUkmSessionId, // Variations preferences maybe changed from incognito mode and should be
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc index 9dfc98e..b723aa2 100644 --- a/chrome/browser/profiles/off_the_record_profile_impl.cc +++ b/chrome/browser/profiles/off_the_record_profile_impl.cc
@@ -139,7 +139,10 @@ } // namespace OffTheRecordProfileImpl::OffTheRecordProfileImpl(Profile* real_profile) - : profile_(real_profile), start_time_(base::Time::Now()) { + : profile_(real_profile), + start_time_(base::Time::Now()), + key_(std::make_unique<ProfileKey>(profile_->GetPath(), + profile_->GetProfileKey())) { // Must happen before we ask for prefs as prefs needs the connection to the // service manager, which is set up in Initialize. BrowserContext::Initialize(this, profile_->GetPath()); @@ -149,8 +152,7 @@ InProcessPrefServiceFactoryFactory::GetInstanceForContext(this) ->CreateDelegate()); - key_ = std::make_unique<ProfileKey>(profile_->GetPath(), prefs_.get(), - profile_->GetProfileKey()); + key_->SetPrefs(prefs_.get()); SimpleKeyMap::GetInstance()->Associate(this, key_.get()); // Register on BrowserContext.
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index a8014c8c..1f6b70e 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc
@@ -468,6 +468,7 @@ io_data_(this), last_session_exit_type_(EXIT_NORMAL), start_time_(base::Time::Now()), + key_(std::make_unique<ProfileKey>(GetPath())), delegate_(delegate), reporting_permissions_checker_factory_(this), shared_cors_origin_access_list_( @@ -583,7 +584,7 @@ user_prefs::UserPrefs::Set(this, prefs_.get()); } - key_ = std::make_unique<ProfileKey>(GetPath(), prefs_.get()); + key_->SetPrefs(prefs_.get()); SimpleKeyMap::GetInstance()->Associate(this, key_.get()); #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/profiles/profile_key.cc b/chrome/browser/profiles/profile_key.cc index fba157e7..b225f2b7 100644 --- a/chrome/browser/profiles/profile_key.cc +++ b/chrome/browser/profiles/profile_key.cc
@@ -4,13 +4,23 @@ #include "chrome/browser/profiles/profile_key.h" -ProfileKey::ProfileKey(const base::FilePath& path, - PrefService* prefs, - ProfileKey* original_key) - : SimpleFactoryKey(path), prefs_(prefs), original_key_(original_key) {} +#include "base/logging.h" + +ProfileKey::ProfileKey(const base::FilePath& path, ProfileKey* original_key) + : SimpleFactoryKey(path), prefs_(nullptr), original_key_(original_key) {} ProfileKey::~ProfileKey() = default; +PrefService* ProfileKey::GetPrefs() { + DCHECK(prefs_); + return prefs_; +} + +void ProfileKey::SetPrefs(PrefService* prefs) { + DCHECK(!prefs_); + prefs_ = prefs; +} + bool ProfileKey::IsOffTheRecord() const { return original_key_ != nullptr; }
diff --git a/chrome/browser/profiles/profile_key.h b/chrome/browser/profiles/profile_key.h index 5622047..511b146 100644 --- a/chrome/browser/profiles/profile_key.h +++ b/chrome/browser/profiles/profile_key.h
@@ -16,13 +16,13 @@ class ProfileKey : public SimpleFactoryKey { public: ProfileKey(const base::FilePath& path, - PrefService* prefs, ProfileKey* original_key = nullptr); ~ProfileKey() override; // Profile-specific APIs needed in reduced mode: ProfileKey* GetOriginalKey() { return original_key_; } - PrefService* GetPrefs() { return prefs_; } + PrefService* GetPrefs(); + void SetPrefs(PrefService* prefs); static ProfileKey* FromSimpleFactoryKey(SimpleFactoryKey* key);
diff --git a/chrome/browser/resource_coordinator/page_signal_receiver.cc b/chrome/browser/resource_coordinator/page_signal_receiver.cc index 4d49e2c..5839457 100644 --- a/chrome/browser/resource_coordinator/page_signal_receiver.cc +++ b/chrome/browser/resource_coordinator/page_signal_receiver.cc
@@ -22,12 +22,6 @@ &PageSignalObserver::OnPageAlmostIdle); } -void PageSignalReceiver::NotifyRendererIsBloated( - const PageNavigationIdentity& page_navigation_id) { - NotifyObserversIfKnownCu(page_navigation_id, - &PageSignalObserver::OnRendererIsBloated); -} - void PageSignalReceiver::SetExpectedTaskQueueingDuration( const PageNavigationIdentity& page_navigation_id, base::TimeDelta duration) {
diff --git a/chrome/browser/resource_coordinator/page_signal_receiver.h b/chrome/browser/resource_coordinator/page_signal_receiver.h index 10cd522..2d1c6548 100644 --- a/chrome/browser/resource_coordinator/page_signal_receiver.h +++ b/chrome/browser/resource_coordinator/page_signal_receiver.h
@@ -35,9 +35,6 @@ virtual void OnPageAlmostIdle( content::WebContents* web_contents, const PageNavigationIdentity& page_navigation_id) {} - virtual void OnRendererIsBloated( - content::WebContents* web_contents, - const PageNavigationIdentity& page_navigation_id) {} virtual void OnExpectedTaskQueueingDurationSet( content::WebContents* web_contents, const PageNavigationIdentity& page_navigation_id, @@ -72,8 +69,6 @@ // mojom::PageSignalReceiver implementation. void NotifyPageAlmostIdle( const PageNavigationIdentity& page_navigation_id) override; - void NotifyRendererIsBloated( - const PageNavigationIdentity& page_navigation_id) override; void SetExpectedTaskQueueingDuration( const PageNavigationIdentity& page_navigation_id, base::TimeDelta duration) override;
diff --git a/chrome/browser/resources/chromeos/camera/src/css/main.css b/chrome/browser/resources/chromeos/camera/src/css/main.css index 19563472..6716e21 100644 --- a/chrome/browser/resources/chromeos/camera/src/css/main.css +++ b/chrome/browser/resources/chromeos/camera/src/css/main.css
@@ -184,6 +184,12 @@ transform: translateX(50%); } +.horizontal-center-stripe { + left: 50%; + position: absolute; + transform: translateX(-50%); +} + .top-stripe.right-stripe { transform: translate(50%, -50%); } @@ -192,6 +198,10 @@ transform: translate(-50%, -50%); } +.top-stripe.horizontal-center-stripe { + transform: translate(-50%, -50%); +} + .bottom-stripe.right-stripe { transform: translate(50%, 50%); }
diff --git a/chrome/browser/resources/chromeos/camera/src/js/views/camera.js b/chrome/browser/resources/chromeos/camera/src/js/views/camera.js index 38b6516..a31d243 100644 --- a/chrome/browser/resources/chromeos/camera/src/js/views/camera.js +++ b/chrome/browser/resources/chromeos/camera/src/js/views/camera.js
@@ -223,17 +223,26 @@ (async () => { if (!suspend) { for (const id of await this.options_.videoDeviceIds()) { - const modesAndConstraints = - await this.modes_.getConstraitsForModes(id); - this.modes_.updateModeSelectionUI(modesAndConstraints.map(([ - m, - ]) => m)); - for (const [mode, candidates] of modesAndConstraints) { - for (const constraints of candidates) { + let supportedModes = null; + for (const mode of this.modes_.getModeCandidates()) { + if (supportedModes && !supportedModes.includes(mode)) { + continue; + } + for (const constraints of this.modes_.getConstraitsCandidates( + id, mode)) { try { const stream = await navigator.mediaDevices.getUserMedia(constraints); + if (!supportedModes) { + supportedModes = + await this.modes_.getSupportedModes(stream); + if (!supportedModes.includes(mode)) { + stream.getTracks()[0].stop(); + break; + } + } await this.preview_.start(stream); + await this.modes_.updateModeSelectionUI(supportedModes); this.facingMode_ = this.options_.updateValues(constraints, stream); await this.modes_.updateMode(mode, stream);
diff --git a/chrome/browser/resources/chromeos/camera/src/js/views/camera/modes.js b/chrome/browser/resources/chromeos/camera/src/js/views/camera/modes.js index deb74e2..c445901 100644 --- a/chrome/browser/resources/chromeos/camera/src/js/views/camera/modes.js +++ b/chrome/browser/resources/chromeos/camera/src/js/views/camera/modes.js
@@ -64,7 +64,7 @@ * @type {Object<string, Object>} * @private */ - this.allModes = { + this.allModes_ = { 'video-mode': { captureFactory: () => new cca.views.camera.Video(this.stream_, this.doSavePicture_), @@ -89,23 +89,20 @@ 'portrait-mode': { captureFactory: () => new cca.views.camera.Portrait(this.stream_, this.doSavePicture_), - isSupported: async function(deviceId) { - for (const constraints of this.deviceConstraints(deviceId)) { - try { - var stream = await navigator.mediaDevices.getUserMedia(constraints); - const imageCapture = - new cca.mojo.ImageCapture(stream.getVideoTracks()[0]); - const capabilities = await imageCapture.getPhotoCapabilities(); - return capabilities.supportedEffects && - capabilities.supportedEffects.includes( - cros.mojom.Effect.PORTRAIT_MODE); - } finally { - if (stream) { - stream.getTracks()[0].stop(); - } - } + isSupported: async (stream) => { + try { + const imageCapture = + new cca.mojo.ImageCapture(stream.getVideoTracks()[0]); + const capabilities = await imageCapture.getPhotoCapabilities(); + return capabilities.supportedEffects && + capabilities.supportedEffects.includes( + cros.mojom.Effect.PORTRAIT_MODE); + } catch (e) { + // The mode is considered unsupported for given stream. This includes + // the case where underlying camera HAL is V1 causing mojo connection + // unable to work. + return false; } - return false; }, deviceConstraints: cca.views.camera.Modes.photoConstraits, nextMode: 'video-mode', @@ -139,7 +136,7 @@ * @param {string} mode Mode to be toggled. */ cca.views.camera.Modes.prototype.updateModeUI_ = function(mode) { - Object.keys(this.allModes).forEach((m) => cca.state.set(m, m == mode)); + Object.keys(this.allModes_).forEach((m) => cca.state.set(m, m == mode)); const element = document.querySelector(`.mode-item>input[data-mode=${mode}]`); element.checked = true; const wrapper = element.parentElement; @@ -222,32 +219,50 @@ }; /** - * Gets all the supported modes and their constraints-candidates pairs for given - * deviceId. - * @async - * @param {?string} deviceId Id of updated video device. - * @return {Array<[string, Array<Object>]>} Array of supported mode name and - * constraints-candidates pairs for given deviceId. Mode values in array - * start with current mode and follow predefined retry order. + * Gets all mode candidates. Desired trying sequence of candidate modes is + * reflected in the order of the returned array. + * @return {Array<string>} Mode candidates to be tried out. */ -cca.views.camera.Modes.prototype.getConstraitsForModes = - async function(deviceId) { +cca.views.camera.Modes.prototype.getModeCandidates = function() { const tried = {}; const results = []; - let mode = Object.keys(this.allModes).find(cca.state.get); + let mode = Object.keys(this.allModes_).find(cca.state.get); while (!tried[mode]) { - const m = this.allModes[mode]; tried[mode] = true; - if (await m.isSupported(deviceId)) { - results.push([mode, m.deviceConstraints(deviceId)]); - } - mode = m.nextMode; + results.push(mode); + mode = this.allModes_[mode].nextMode; } return results; }; /** - * Updates mode selection UI according to input supported modes. + * Gets constraints-candidates for given mode and deviceId. + * @param {?string} deviceId Request video device id. + * @param {?string} mode Request mode. + * @return {Array<Object>} Constraints-candidates for given deviceId and mode. + */ +cca.views.camera.Modes.prototype.getConstraitsCandidates = function( + deviceId, mode) { + return this.allModes_[mode].deviceConstraints(deviceId); +}; + +/** + * Gets supported modes for video device of the given stream. + * @param {MediaStream} stream Stream of the video device. + * @return {Array<string>} Names of all supported mode for the video device. + */ +cca.views.camera.Modes.prototype.getSupportedModes = async function(stream) { + let supportedModes = []; + for (const [mode, obj] of Object.entries(this.allModes_)) { + if (await obj.isSupported(stream)) { + supportedModes.push(mode); + } + } + return supportedModes; +}; + +/** + * Updates mode selection UI according to given supported modes. * @param {Array<string>} supportedModes Supported mode names to be updated * with. */ @@ -272,7 +287,7 @@ } this.updateModeUI_(mode); this.stream_ = stream; - this.current = this.allModes[mode].captureFactory(); + this.current = this.allModes_[mode].captureFactory(); }; /**
diff --git a/chrome/browser/resources/chromeos/camera/src/views/main.html b/chrome/browser/resources/chromeos/camera/src/views/main.html index 61517a5..583004fc 100644 --- a/chrome/browser/resources/chromeos/camera/src/views/main.html +++ b/chrome/browser/resources/chromeos/camera/src/views/main.html
@@ -122,7 +122,7 @@ <button id="gallery-enter" tabindex="0" i18n-label="gallery_button" hidden></button> </div> - <div class="top-stripe" id="record-time" hidden> + <div class="top-stripe horizontal-center-stripe" id="record-time" hidden> <div class="icon"></div> <div id="record-time-msg"></div> </div>
diff --git a/chrome/browser/resources/management/management_ui.html b/chrome/browser/resources/management/management_ui.html index 2f15e52..7d5cf31 100644 --- a/chrome/browser/resources/management/management_ui.html +++ b/chrome/browser/resources/management/management_ui.html
@@ -200,7 +200,15 @@ </if> <div>[[accountManagedInfo_.overview]]</div> <ul class="overview-messages" hidden="[[!accountManagedInfo_]]"> +<if expr="chromeos"> + <li>[[accountManagedInfo_.setup]] + <a href="$i18nRaw{managementAccountLearnMoreUrl}" + target="_blank">$i18n{learnMore}</a> + </li> +</if> +<if expr="not chromeos"> <li>[[accountManagedInfo_.setup]]</li> +</if> <li>[[accountManagedInfo_.data]]</li> </ul> </section>
diff --git a/chrome/browser/resources/print_preview/new/BUILD.gn b/chrome/browser/resources/print_preview/new/BUILD.gn index 784a6a6..4d87996 100644 --- a/chrome/browser/resources/print_preview/new/BUILD.gn +++ b/chrome/browser/resources/print_preview/new/BUILD.gn
@@ -161,6 +161,7 @@ deps = [ ":input_behavior", ":settings_behavior", + ":state", ] } }
diff --git a/chrome/browser/resources/print_preview/new/pin_settings.html b/chrome/browser/resources/print_preview/new/pin_settings.html index 0e70698..3159f43 100644 --- a/chrome/browser/resources/print_preview/new/pin_settings.html +++ b/chrome/browser/resources/print_preview/new/pin_settings.html
@@ -7,6 +7,7 @@ <link rel="import" href="print_preview_shared_css.html"> <link rel="import" href="settings_behavior.html"> <link rel="import" href="settings_section.html"> +<link rel="import" href="state.html"> <dom-module id="print-preview-pin-settings"> <template> @@ -54,7 +55,7 @@ maxlength="4" data-timeout-delay="250" aria-labelledby="pin" placeholder="$i18n{pinPlaceholder}" spellcheck="false" disabled$="[[inputDisabled_(pinEnabled_, inputValid_, disabled)]]" - error-message="$i18n{pinErrorMessage}" auto-validate> + error-message="$i18n{pinErrorMessage}" required auto-validate> </cr-input> </div> </print-preview-settings-section>
diff --git a/chrome/browser/resources/print_preview/new/pin_settings.js b/chrome/browser/resources/print_preview/new/pin_settings.js index 0aed18d..10451467 100644 --- a/chrome/browser/resources/print_preview/new/pin_settings.js +++ b/chrome/browser/resources/print_preview/new/pin_settings.js
@@ -8,6 +8,9 @@ behaviors: [SettingsBehavior, print_preview_new.InputBehavior], properties: { + /** @type {!print_preview_new.State} */ + state: Number, + disabled: Boolean, /** @private {boolean} */ @@ -38,8 +41,10 @@ }, }, - observers: - ['onSettingsChanged_(settings.pin.value, settings.pinValue.value)'], + observers: [ + 'onSettingsChanged_(settings.pin.value, settings.pinValue.value)', + 'changePinValueSetting_(state)', + ], listeners: { 'input-change': 'onInputChange_', @@ -94,11 +99,27 @@ this.pinEnabled_ = pinEnabled; const pinValue = this.getSetting('pinValue'); this.inputString_ = /** @type {string} */ (pinValue.value); + this.resetString(); }, /** @private */ onPinChange_: function() { this.setSetting('pin', this.$.pin.checked); + // We need to set validity of pinValue to true to return to READY state + // after unchecking the pin and to check the validity again after checking + // the pin. + if (!this.$.pin.checked) { + this.setSettingValid('pinValue', true); + } else { + this.changePinValueSetting_(); + } + }, + + /** + * @private + */ + onInputChanged_: function() { + this.changePinValueSetting_(); }, /** @@ -106,14 +127,25 @@ * input. * @private */ - onInputChanged_: function() { + changePinValueSetting_: function() { if (this.settings === undefined) { return; } + // If the state is not READY and current pinValue is valid (so it's not the + // cause of the error) we need to wait until the state will be READY again. + // It's done because we don't permit multiple simultaneous validation errors + // in Print Preview and we also don't want to set the value when sticky + // settings may not yet have been set. + if (this.state != print_preview_new.State.READY && + this.settings.pinValue.valid) { + return; + } this.inputValid_ = this.computeValid_(); this.setSettingValid('pinValue', this.inputValid_); - if (this.inputValid_) { + // We allow to save the empty string as sticky setting value to give users + // the opportunity to unset their PIN in sticky settings. + if (this.inputValid_ || this.inputString_ == '') { this.setSetting('pinValue', this.inputString_); } }, @@ -126,6 +158,7 @@ computeValid_: function() { // Make sure value updates first, in case inputString_ was updated by JS. this.$.pinValue.value = this.inputString_; + this.$.pinValue.validate(); return !this.$.pinValue.invalid; }, });
diff --git a/chrome/browser/resources/print_preview/new/print_preview_sidebar.html b/chrome/browser/resources/print_preview/new/print_preview_sidebar.html index 179ce6e..3746a4a6 100644 --- a/chrome/browser/resources/print_preview/new/print_preview_sidebar.html +++ b/chrome/browser/resources/print_preview/new/print_preview_sidebar.html
@@ -108,7 +108,7 @@ available class="settings-section"> </print-preview-destination-settings> <if expr="chromeos"> - <print-preview-pin-settings settings="[[settings]]" + <print-preview-pin-settings state="[[state]]" settings="[[settings]]" disabled="[[controlsDisabled_]]" hidden$="[[!settings.pin.available]]" class="settings-section"> </print-preview-pin-settings>
diff --git a/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html b/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html index 253cd5c3..395f0453 100644 --- a/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html +++ b/chrome/browser/resources/settings/a11y_page/manage_a11y_page.html
@@ -160,6 +160,13 @@ disabled="[[!prefs.settings.a11y.autoclick.value]]"> </settings-dropdown-menu> </div> + <div class="sub-item"> + <settings-toggle-button class="continuation sub-item" + hidden$="[[!prefs.settings.a11y.autoclick.value]]" + pref="{{prefs.settings.a11y.autoclick_stabilize_position}}" + label="$i18n{autoclickStabilizeCursorPosition}"> + </settings-toggle-button> + </div> <template is="dom-if" if="[[showExperimentalAutoclick_]]"> <div class="sub-item"> <settings-toggle-button class="continuation sub-item"
diff --git a/chrome/browser/resources/user_manager/create_profile.html b/chrome/browser/resources/user_manager/create_profile.html index 110bafe..8dd7755 100644 --- a/chrome/browser/resources/user_manager/create_profile.html +++ b/chrome/browser/resources/user_manager/create_profile.html
@@ -117,6 +117,7 @@ max-height: 50vh; overflow-x: hidden; overflow-y: auto; + padding: 8px; } </style> <div id="message-container" visible$="[[isMessageVisble_]]">
diff --git a/chrome/browser/send_tab_to_self/desktop_notification_handler.cc b/chrome/browser/send_tab_to_self/desktop_notification_handler.cc index 5cbea721..037c959 100644 --- a/chrome/browser/send_tab_to_self/desktop_notification_handler.cc +++ b/chrome/browser/send_tab_to_self/desktop_notification_handler.cc
@@ -8,7 +8,6 @@ #include <utility> #include "base/guid.h" -#include "base/metrics/histogram_macros.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/notifications/notification_display_service.h" #include "chrome/browser/notifications/notification_display_service_factory.h" @@ -18,6 +17,7 @@ #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_navigator_params.h" #include "components/send_tab_to_self/send_tab_to_self_entry.h" +#include "components/send_tab_to_self/send_tab_to_self_metrics.h" #include "components/send_tab_to_self/send_tab_to_self_model.h" #include "components/send_tab_to_self/send_tab_to_self_sync_service.h" #include "ui/base/l10n/l10n_util.h" @@ -31,30 +31,8 @@ namespace { -// Metrics for measuring notification interaction. -// These values are persisted to logs. Entries should not be renumbered and -// numeric values should never be reused. -enum class SendTabToSelfNotification { - // The user opened a tab from a notification. - kOpened = 0, - // The user closed a notification. - kDismissed = 1, - // A notification was shown from a remotely added entry. - kShown = 2, - // A notification was dismissed remotely. - kDismissedRemotely = 3, - // Update kMaxValue when new enums are added. - kMaxValue = kDismissedRemotely, -}; - -const char kNotificationStatusHistogram[] = "SendTabToSelf.Notification"; - const char kDesktopNotificationSharedPrefix[] = "shared"; -void RecordNotificationHistogram(SendTabToSelfNotification status) { - UMA_HISTOGRAM_ENUMERATION(kNotificationStatusHistogram, status); -} - } // namespace DesktopNotificationHandler::DesktopNotificationHandler(Profile* profile)
diff --git a/chrome/browser/supervised_user/supervised_user_service.cc b/chrome/browser/supervised_user/supervised_user_service.cc index 58d8a1cf..03531cc 100644 --- a/chrome/browser/supervised_user/supervised_user_service.cc +++ b/chrome/browser/supervised_user/supervised_user_service.cc
@@ -969,18 +969,12 @@ } #endif // BUILDFLAG(ENABLE_EXTENSIONS) -syncer::ModelTypeSet SupervisedUserService::GetForcedDataTypes() const { +syncer::UserSelectableTypeSet SupervisedUserService::GetForcedTypes() const { if (!ProfileIsSupervised()) - return syncer::ModelTypeSet(); + return syncer::UserSelectableTypeSet(); - syncer::ModelTypeSet result; - result.Put(syncer::EXTENSIONS); - result.Put(syncer::EXTENSION_SETTINGS); - result.Put(syncer::APPS); - result.Put(syncer::APP_SETTINGS); - result.Put(syncer::APP_LIST); - result.Put(syncer::ARC_PACKAGE); - return result; + return {syncer::UserSelectableType::kExtensions, + syncer::UserSelectableType::kApps}; } bool SupervisedUserService::IsEncryptEverythingAllowed() const {
diff --git a/chrome/browser/supervised_user/supervised_user_service.h b/chrome/browser/supervised_user/supervised_user_service.h index c4507df..d9b83f2a 100644 --- a/chrome/browser/supervised_user/supervised_user_service.h +++ b/chrome/browser/supervised_user/supervised_user_service.h
@@ -174,7 +174,7 @@ void Shutdown() override; // SyncTypePreferenceProvider implementation: - syncer::ModelTypeSet GetForcedDataTypes() const override; + syncer::UserSelectableTypeSet GetForcedTypes() const override; bool IsEncryptEverythingAllowed() const override; #if !defined(OS_ANDROID)
diff --git a/chrome/browser/sync/OWNERS b/chrome/browser/sync/OWNERS index 553b61e..bcfd98f 100644 --- a/chrome/browser/sync/OWNERS +++ b/chrome/browser/sync/OWNERS
@@ -1,3 +1,5 @@ file://components/sync/OWNERS per-file profile_sync_service_android*=nyquist@chromium.org + +# COMPONENT: Services>Sync
diff --git a/chrome/browser/sync/profile_sync_service_android.cc b/chrome/browser/sync/profile_sync_service_android.cc index afa1a3b..17b6b27 100644 --- a/chrome/browser/sync/profile_sync_service_android.cc +++ b/chrome/browser/sync/profile_sync_service_android.cc
@@ -27,6 +27,7 @@ #include "components/signin/core/browser/account_info.h" #include "components/strings/grit/components_strings.h" #include "components/sync/base/model_type.h" +#include "components/sync/base/user_selectable_type.h" #include "components/sync/device_info/device_info.h" #include "components/sync/device_info/device_info_sync_service.h" #include "components/sync/device_info/device_info_tracker.h" @@ -213,9 +214,15 @@ ScopedJavaLocalRef<jintArray> ProfileSyncServiceAndroid::GetChosenDataTypes( JNIEnv* env, const JavaParamRef<jobject>& obj) { - syncer::ModelTypeSet types = - sync_service_->GetUserSettings()->GetChosenDataTypes(); - return JNI_ProfileSyncService_ModelTypeSetToJavaIntArray(env, types); + // TODO(crbug/950874): introduce UserSelectableType in java code, then remove + // workaround here and in SetChosenDataTypes(). + syncer::UserSelectableTypeSet types = + sync_service_->GetUserSettings()->GetSelectedTypes(); + syncer::ModelTypeSet model_types; + for (syncer::UserSelectableType type : types) { + model_types.Put(syncer::UserSelectableTypeToCanonicalModelType(type)); + } + return JNI_ProfileSyncService_ModelTypeSetToJavaIntArray(env, model_types); } ScopedJavaLocalRef<jintArray> ProfileSyncServiceAndroid::GetPreferredDataTypes( @@ -233,11 +240,18 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); std::vector<int> types_vector; base::android::JavaIntArrayToIntVector(env, model_type_array, &types_vector); - syncer::ModelTypeSet types; + syncer::ModelTypeSet model_types; for (size_t i = 0; i < types_vector.size(); i++) { - types.Put(static_cast<syncer::ModelType>(types_vector[i])); + model_types.Put(static_cast<syncer::ModelType>(types_vector[i])); } - sync_service_->GetUserSettings()->SetChosenDataTypes(sync_everything, types); + syncer::UserSelectableTypeSet selected_types; + for (syncer::UserSelectableType type : syncer::UserSelectableTypeSet::All()) { + if (model_types.Has(syncer::UserSelectableTypeToCanonicalModelType(type))) { + selected_types.Put(type); + } + } + sync_service_->GetUserSettings()->SetSelectedTypes(sync_everything, + selected_types); } jboolean ProfileSyncServiceAndroid::IsEncryptEverythingAllowed( @@ -334,7 +348,7 @@ base::Callback<void(std::unique_ptr<base::ListValue>)> native_callback = base::Bind(&NativeGetAllNodesCallback, java_callback); - sync_service_->GetAllNodes(native_callback); + sync_service_->GetAllNodesForDebugging(native_callback); } jint ProfileSyncServiceAndroid::GetAuthError(JNIEnv* env, @@ -460,7 +474,7 @@ jlong ProfileSyncServiceAndroid::GetLastSyncedTimeForTest( JNIEnv* env, const JavaParamRef<jobject>& obj) { - base::Time last_sync_time = sync_service_->GetLastSyncedTime(); + base::Time last_sync_time = sync_service_->GetLastSyncedTimeForDebugging(); return static_cast<jlong>( (last_sync_time - base::Time::UnixEpoch()).InMicroseconds()); }
diff --git a/chrome/browser/sync/test/integration/enable_disable_test.cc b/chrome/browser/sync/test/integration/enable_disable_test.cc index a99489b..5441a92 100644 --- a/chrome/browser/sync/test/integration/enable_disable_test.cc +++ b/chrome/browser/sync/test/integration/enable_disable_test.cc
@@ -16,21 +16,23 @@ #include "chrome/browser/sync/test/integration/updated_progress_marker_checker.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/sync/base/model_type.h" +#include "components/sync/base/user_selectable_type.h" #include "components/sync/driver/profile_sync_service.h" #include "components/sync/driver/sync_driver_switches.h" #include "components/sync/driver/sync_user_settings_impl.h" #include "components/sync/test/fake_server/bookmark_entity_builder.h" #include "components/sync/test/fake_server/entity_builder_factory.h" +namespace { + using syncer::ModelType; -using syncer::ModelTypeSet; using syncer::ModelTypeFromString; +using syncer::ModelTypeSet; using syncer::ModelTypeToString; using syncer::ProxyTypes; using syncer::SyncPrefs; -using syncer::UserSelectableTypes; - -namespace { +using syncer::UserSelectableType; +using syncer::UserSelectableTypeSet; const char kSyncedBookmarkURL[] = "http://www.mybookmark.com"; // Non-utf8 string to make sure it gets handled well. @@ -42,20 +44,16 @@ // it will be disabled, because the other selectable type(s) could already be // enabling it. And vice versa for disabling. ModelTypeSet MultiGroupTypes(const ModelTypeSet& registered_types) { - const ModelTypeSet selectable_types = UserSelectableTypes(); ModelTypeSet seen; ModelTypeSet multi; - // TODO(vitaliii): Do not use such short variable names here (and possibly - // elsewhere in the file). - for (ModelType st : selectable_types) { + for (UserSelectableType type : UserSelectableTypeSet::All()) { const ModelTypeSet grouped_types = - syncer::SyncUserSettingsImpl::ResolvePrefGroupsForTesting( - ModelTypeSet(st)); - for (ModelType gt : grouped_types) { - if (seen.Has(gt)) { - multi.Put(gt); + syncer::SyncUserSettingsImpl::ResolvePreferredTypesForTesting({type}); + for (ModelType grouped_type : grouped_types) { + if (seen.Has(grouped_type)) { + multi.Put(grouped_type); } else { - seen.Put(gt); + seen.Put(grouped_type); } } } @@ -76,7 +74,7 @@ bool ModelTypeExists(ModelType type) { base::RunLoop loop; std::unique_ptr<base::ListValue> all_nodes; - GetSyncService(0)->GetAllNodes( + GetSyncService(0)->GetAllNodesForDebugging( base::BindLambdaForTesting([&](std::unique_ptr<base::ListValue> nodes) { all_nodes = std::move(nodes); loop.Quit(); @@ -111,7 +109,7 @@ int GetNumUpdatesDownloadedInLastCycle() { return GetSyncService(0) - ->GetLastCycleSnapshot() + ->GetLastCycleSnapshotForDebugging() .model_neutral_state() .num_updates_downloaded_total; } @@ -122,19 +120,18 @@ if (all_types_enabled) { ASSERT_TRUE(GetClient(0)->SetupSync()); } else { - ASSERT_TRUE(GetClient(0)->SetupSyncNoWaitForCompletion(ModelTypeSet())); + ASSERT_TRUE( + GetClient(0)->SetupSyncNoWaitForCompletion(UserSelectableTypeSet())); ASSERT_TRUE(GetClient(0)->AwaitSyncSetupCompletion()); } registered_types_ = GetSyncService(0)->GetRegisteredDataTypes(); - selectable_types_ = UserSelectableTypes(); multi_grouped_types_ = MultiGroupTypes(registered_types_); } - ModelTypeSet ResolveGroup(ModelType type) { + ModelTypeSet ResolveGroup(UserSelectableType type) { ModelTypeSet grouped_types = - syncer::SyncUserSettingsImpl::ResolvePrefGroupsForTesting( - ModelTypeSet(type)); + syncer::SyncUserSettingsImpl::ResolvePreferredTypesForTesting({type}); grouped_types.RetainAll(registered_types_); grouped_types.RemoveAll(ProxyTypes()); return grouped_types; @@ -145,7 +142,6 @@ } ModelTypeSet registered_types_; - ModelTypeSet selectable_types_; ModelTypeSet multi_grouped_types_; private: @@ -158,29 +154,30 @@ // Setup sync with no enabled types. SetupTest(/*all_types_enabled=*/false); - for (ModelType st : selectable_types_) { - const ModelTypeSet grouped_types = ResolveGroup(st); - const ModelTypeSet single_grouped_types = WithoutMultiTypes(grouped_types); - for (ModelType sgt : single_grouped_types) { - ASSERT_FALSE(ModelTypeExists(sgt)) << " for " << ModelTypeToString(st); + for (UserSelectableType type : UserSelectableTypeSet::All()) { + const ModelTypeSet grouped_types = ResolveGroup(type); + for (ModelType single_grouped_type : WithoutMultiTypes(grouped_types)) { + ASSERT_FALSE(ModelTypeExists(single_grouped_type)) + << " for " << GetUserSelectableTypeName(type); } base::HistogramTester histogram_tester; - EXPECT_TRUE(GetClient(0)->EnableSyncForDatatype(st)); + EXPECT_TRUE(GetClient(0)->EnableSyncForType(type)); - for (ModelType gt : grouped_types) { - EXPECT_TRUE(ModelTypeExists(gt)) << " for " << ModelTypeToString(st); + for (ModelType grouped_type : grouped_types) { + EXPECT_TRUE(ModelTypeExists(grouped_type)) + << " for " << GetUserSelectableTypeName(type); - if (syncer::CommitOnlyTypes().Has(gt)) { + if (syncer::CommitOnlyTypes().Has(grouped_type)) { EXPECT_EQ(0, histogram_tester.GetBucketCount( "Sync.PostedDataTypeGetUpdatesRequest", - ModelTypeToHistogramInt(gt))) - << " for " << ModelTypeToString(gt); + ModelTypeToHistogramInt(grouped_type))) + << " for " << ModelTypeToString(grouped_type); } else { EXPECT_NE(0, histogram_tester.GetBucketCount( "Sync.PostedDataTypeGetUpdatesRequest", - ModelTypeToHistogramInt(gt))) - << " for " << ModelTypeToString(gt); + ModelTypeToHistogramInt(grouped_type))) + << " for " << ModelTypeToString(grouped_type); } } } @@ -190,24 +187,26 @@ // Setup sync with no disabled types. SetupTest(/*all_types_enabled=*/true); - for (ModelType st : selectable_types_) { - const ModelTypeSet grouped_types = ResolveGroup(st); - for (ModelType gt : grouped_types) { - ASSERT_TRUE(ModelTypeExists(gt)) << " for " << ModelTypeToString(st); + for (UserSelectableType type : UserSelectableTypeSet::All()) { + const ModelTypeSet grouped_types = ResolveGroup(type); + for (ModelType grouped_type : grouped_types) { + ASSERT_TRUE(ModelTypeExists(grouped_type)) + << " for " << GetUserSelectableTypeName(type); } - EXPECT_TRUE(GetClient(0)->DisableSyncForDatatype(st)); + EXPECT_TRUE(GetClient(0)->DisableSyncForType(type)); - const ModelTypeSet single_grouped_types = WithoutMultiTypes(grouped_types); - for (ModelType sgt : single_grouped_types) { - EXPECT_FALSE(ModelTypeExists(sgt)) << " for " << ModelTypeToString(st); + for (ModelType single_grouped_type : WithoutMultiTypes(grouped_types)) { + EXPECT_FALSE(ModelTypeExists(single_grouped_type)) + << " for " << GetUserSelectableTypeName(type); } } // Lastly make sure that all the multi grouped times are all gone, since we // did not check these after disabling inside the above loop. - for (ModelType mgt : multi_grouped_types_) { - EXPECT_FALSE(ModelTypeExists(mgt)) << " for " << ModelTypeToString(mgt); + for (ModelType multi_grouped_type : multi_grouped_types_) { + EXPECT_FALSE(ModelTypeExists(multi_grouped_type)) + << " for " << ModelTypeToString(multi_grouped_type); } } @@ -216,27 +215,30 @@ // Setup sync with no enabled types. SetupTest(/*all_types_enabled=*/false); - for (ModelType st : selectable_types_) { - const ModelTypeSet grouped_types = ResolveGroup(st); + for (UserSelectableType type : UserSelectableTypeSet::All()) { + const ModelTypeSet grouped_types = ResolveGroup(type); const ModelTypeSet single_grouped_types = WithoutMultiTypes(grouped_types); - for (ModelType sgt : single_grouped_types) { - ASSERT_FALSE(ModelTypeExists(sgt)) << " for " << ModelTypeToString(st); + for (ModelType single_grouped_type : single_grouped_types) { + ASSERT_FALSE(ModelTypeExists(single_grouped_type)) + << " for " << GetUserSelectableTypeName(type); } // Enable and then disable immediately afterwards, before the datatype has // had the chance to finish startup (which usually involves task posting). - EXPECT_TRUE(GetClient(0)->EnableSyncForDatatype(st)); - EXPECT_TRUE(GetClient(0)->DisableSyncForDatatype(st)); + EXPECT_TRUE(GetClient(0)->EnableSyncForType(type)); + EXPECT_TRUE(GetClient(0)->DisableSyncForType(type)); - for (ModelType sgt : single_grouped_types) { - EXPECT_FALSE(ModelTypeExists(sgt)) << " for " << ModelTypeToString(st); + for (ModelType single_grouped_type : single_grouped_types) { + EXPECT_FALSE(ModelTypeExists(single_grouped_type)) + << " for " << GetUserSelectableTypeName(type); } } // Lastly make sure that all the multi grouped times are all gone, since we // did not check these after disabling inside the above loop. - for (ModelType mgt : multi_grouped_types_) { - EXPECT_FALSE(ModelTypeExists(mgt)) << " for " << ModelTypeToString(mgt); + for (ModelType multi_grouped_type : multi_grouped_types_) { + EXPECT_FALSE(ModelTypeExists(multi_grouped_type)) + << " for " << ModelTypeToString(multi_grouped_type); } } @@ -245,19 +247,21 @@ // Setup sync with no disabled types. SetupTest(/*all_types_enabled=*/true); - for (ModelType st : selectable_types_) { - const ModelTypeSet grouped_types = ResolveGroup(st); - for (ModelType gt : grouped_types) { - ASSERT_TRUE(ModelTypeExists(gt)) << " for " << ModelTypeToString(st); + for (UserSelectableType type : UserSelectableTypeSet::All()) { + const ModelTypeSet grouped_types = ResolveGroup(type); + for (ModelType grouped_type : grouped_types) { + ASSERT_TRUE(ModelTypeExists(grouped_type)) + << " for " << GetUserSelectableTypeName(type); } // Disable and then reenable immediately afterwards, before the datatype has // had the chance to stop fully (which usually involves task posting). - EXPECT_TRUE(GetClient(0)->DisableSyncForDatatype(st)); - EXPECT_TRUE(GetClient(0)->EnableSyncForDatatype(st)); + EXPECT_TRUE(GetClient(0)->DisableSyncForType(type)); + EXPECT_TRUE(GetClient(0)->EnableSyncForType(type)); - for (ModelType gt : grouped_types) { - EXPECT_TRUE(ModelTypeExists(gt)) << " for " << ModelTypeToString(st); + for (ModelType grouped_type : grouped_types) { + EXPECT_TRUE(ModelTypeExists(grouped_type)) + << " for " << GetUserSelectableTypeName(type); } } } @@ -267,21 +271,23 @@ // Setup sync with no enabled types. SetupTest(/*all_types_enabled=*/false); - for (ModelType st : selectable_types_) { - const ModelTypeSet grouped_types = ResolveGroup(st); - const ModelTypeSet single_grouped_types = WithoutMultiTypes(grouped_types); - for (ModelType sgt : single_grouped_types) { - ASSERT_FALSE(ModelTypeExists(sgt)) << " for " << ModelTypeToString(st); + for (UserSelectableType type : UserSelectableTypeSet::All()) { + const ModelTypeSet single_grouped_types = + WithoutMultiTypes(ResolveGroup(type)); + for (ModelType single_grouped_type : single_grouped_types) { + ASSERT_FALSE(ModelTypeExists(single_grouped_type)) + << " for " << GetUserSelectableTypeName(type); } // Fast enable-disable-enable sequence, before the datatype has had the // chance to transition fully across states (usually involves task posting). - EXPECT_TRUE(GetClient(0)->EnableSyncForDatatype(st)); - EXPECT_TRUE(GetClient(0)->DisableSyncForDatatype(st)); - EXPECT_TRUE(GetClient(0)->EnableSyncForDatatype(st)); + EXPECT_TRUE(GetClient(0)->EnableSyncForType(type)); + EXPECT_TRUE(GetClient(0)->DisableSyncForType(type)); + EXPECT_TRUE(GetClient(0)->EnableSyncForType(type)); - for (ModelType sgt : single_grouped_types) { - EXPECT_TRUE(ModelTypeExists(sgt)) << " for " << ModelTypeToString(st); + for (ModelType single_grouped_type : single_grouped_types) { + EXPECT_TRUE(ModelTypeExists(single_grouped_type)) + << " for " << GetUserSelectableTypeName(type); } } } @@ -295,8 +301,11 @@ GetClient(0)->EnableSyncForAllDatatypes(); GetClient(0)->DisableSyncForAllDatatypes(); - for (ModelType st : selectable_types_) { - EXPECT_FALSE(ModelTypeExists(st)) << " for " << ModelTypeToString(st); + for (UserSelectableType type : UserSelectableTypeSet::All()) { + for (ModelType grouped_type : ResolveGroup(type)) { + EXPECT_FALSE(ModelTypeExists(grouped_type)) + << " for " << GetUserSelectableTypeName(type); + } } } @@ -309,12 +318,11 @@ EXPECT_TRUE(GetClient(0)->AwaitEngineInitialization()); - // Proxy types don't really run. - const ModelTypeSet non_proxy_types = - Difference(selectable_types_, ProxyTypes()); - - for (ModelType type : non_proxy_types) { - EXPECT_TRUE(ModelTypeExists(type)) << " for " << ModelTypeToString(type); + for (UserSelectableType type : UserSelectableTypeSet::All()) { + for (ModelType model_type : ResolveGroup(type)) { + EXPECT_TRUE(ModelTypeExists(model_type)) + << " for " << ModelTypeToString(model_type); + } } } @@ -328,12 +336,11 @@ GetClient(0)->DisableSyncForAllDatatypes(); GetClient(0)->EnableSyncForAllDatatypes(); - // Proxy types don't really run. - const ModelTypeSet non_proxy_types = - Difference(selectable_types_, ProxyTypes()); - - for (ModelType type : non_proxy_types) { - EXPECT_TRUE(ModelTypeExists(type)) << " for " << ModelTypeToString(type); + for (UserSelectableType type : UserSelectableTypeSet::All()) { + for (ModelType model_type : ResolveGroup(type)) { + EXPECT_TRUE(ModelTypeExists(model_type)) + << " for " << ModelTypeToString(model_type); + } } }
diff --git a/chrome/browser/sync/test/integration/p2p_sync_refresher.cc b/chrome/browser/sync/test/integration/p2p_sync_refresher.cc index a8e14e4..ad89e83 100644 --- a/chrome/browser/sync/test/integration/p2p_sync_refresher.cc +++ b/chrome/browser/sync/test/integration/p2p_sync_refresher.cc
@@ -22,7 +22,8 @@ } void P2PSyncRefresher::OnSyncCycleCompleted(syncer::SyncService* sync) { - const syncer::SyncCycleSnapshot& snap = sync_service_->GetLastCycleSnapshot(); + const syncer::SyncCycleSnapshot& snap = + sync_service_->GetLastCycleSnapshotForDebugging(); bool is_notifiable_commit = (snap.model_neutral_state().num_successful_commits > 0); if (is_notifiable_commit) {
diff --git a/chrome/browser/sync/test/integration/profile_sync_service_harness.cc b/chrome/browser/sync/test/integration/profile_sync_service_harness.cc index bf5400d..889bc96 100644 --- a/chrome/browser/sync/test/integration/profile_sync_service_harness.cc +++ b/chrome/browser/sync/test/integration/profile_sync_service_harness.cc
@@ -194,8 +194,9 @@ } bool ProfileSyncServiceHarness::SetupSync() { - bool result = SetupSyncNoWaitForCompletion(syncer::UserSelectableTypes()) && - AwaitSyncSetupCompletion(); + bool result = + SetupSyncNoWaitForCompletion(syncer::UserSelectableTypeSet::All()) && + AwaitSyncSetupCompletion(); if (!result) { LOG(ERROR) << profile_debug_name_ << ": SetupSync failed. Syncer status:\n" << GetServiceStatus(); @@ -206,29 +207,29 @@ } bool ProfileSyncServiceHarness::SetupSyncNoWaitForCompletion( - syncer::ModelTypeSet synced_datatypes) { - return SetupSyncImpl(synced_datatypes, EncryptionSetupMode::kNoEncryption, + syncer::UserSelectableTypeSet selected_types) { + return SetupSyncImpl(selected_types, EncryptionSetupMode::kNoEncryption, /*encryption_passphrase=*/base::nullopt); } bool ProfileSyncServiceHarness:: SetupSyncWithEncryptionPassphraseNoWaitForCompletion( - syncer::ModelTypeSet synced_datatypes, + syncer::UserSelectableTypeSet selected_types, const std::string& passphrase) { - return SetupSyncImpl(synced_datatypes, EncryptionSetupMode::kEncryption, + return SetupSyncImpl(selected_types, EncryptionSetupMode::kEncryption, passphrase); } bool ProfileSyncServiceHarness:: SetupSyncWithDecryptionPassphraseNoWaitForCompletion( - syncer::ModelTypeSet synced_datatypes, + syncer::UserSelectableTypeSet selected_types, const std::string& passphrase) { - return SetupSyncImpl(synced_datatypes, EncryptionSetupMode::kDecryption, + return SetupSyncImpl(selected_types, EncryptionSetupMode::kDecryption, passphrase); } bool ProfileSyncServiceHarness::SetupSyncImpl( - syncer::ModelTypeSet synced_datatypes, + syncer::UserSelectableTypeSet selected_types, EncryptionSetupMode encryption_mode, const base::Optional<std::string>& passphrase) { DCHECK(encryption_mode == EncryptionSetupMode::kNoEncryption || @@ -257,9 +258,10 @@ } // Choose the datatypes to be synced. If all datatypes are to be synced, // set sync_everything to true; otherwise, set it to false. - bool sync_everything = (synced_datatypes == syncer::UserSelectableTypes()); - service()->GetUserSettings()->SetChosenDataTypes(sync_everything, - synced_datatypes); + bool sync_everything = + (selected_types == syncer::UserSelectableTypeSet::All()); + service()->GetUserSettings()->SetSelectedTypes(sync_everything, + selected_types); if (encryption_mode == EncryptionSetupMode::kEncryption) { service()->GetUserSettings()->SetEncryptionPassphrase(passphrase.value()); @@ -425,88 +427,73 @@ return true; } -bool ProfileSyncServiceHarness::EnableSyncForDatatype( - syncer::ModelType datatype) { +bool ProfileSyncServiceHarness::EnableSyncForType( + syncer::UserSelectableType type) { DVLOG(1) << GetClientInfoString( - "EnableSyncForDatatype(" - + std::string(syncer::ModelTypeToString(datatype)) + ")"); + "EnableSyncForType(" + + std::string(syncer::GetUserSelectableTypeName(type)) + ")"); if (!IsSyncEnabledByUser()) { bool result = - SetupSyncNoWaitForCompletion(syncer::ModelTypeSet(datatype)) && - AwaitSyncSetupCompletion(); + SetupSyncNoWaitForCompletion({type}) && AwaitSyncSetupCompletion(); // If SetupSync() succeeded, then Sync must now be enabled. DCHECK(!result || IsSyncEnabledByUser()); return result; } if (service() == nullptr) { - LOG(ERROR) << "EnableSyncForDatatype(): service() is null."; + LOG(ERROR) << "EnableSyncForType(): service() is null."; return false; } - if (!syncer::UserSelectableTypes().Has(datatype)) { - LOG(ERROR) << "Can only enable user selectable types, requested " - << syncer::ModelTypeToString(datatype); - return false; - } - - syncer::ModelTypeSet synced_datatypes = - service()->GetUserSettings()->GetChosenDataTypes(); - if (synced_datatypes.Has(datatype)) { - DVLOG(1) << "EnableSyncForDatatype(): Sync already enabled for datatype " - << syncer::ModelTypeToString(datatype) - << " on " << profile_debug_name_ << "."; + syncer::UserSelectableTypeSet selected_types = + service()->GetUserSettings()->GetSelectedTypes(); + if (selected_types.Has(type)) { + DVLOG(1) << "EnableSyncForType(): Sync already enabled for type " + << syncer::GetUserSelectableTypeName(type) << " on " + << profile_debug_name_ << "."; return true; } - synced_datatypes.Put(syncer::ModelTypeFromInt(datatype)); - synced_datatypes.RetainAll(syncer::UserSelectableTypes()); - service()->GetUserSettings()->SetChosenDataTypes(false, synced_datatypes); + selected_types.Put(type); + service()->GetUserSettings()->SetSelectedTypes(false, selected_types); if (AwaitSyncSetupCompletion()) { - DVLOG(1) << "EnableSyncForDatatype(): Enabled sync for datatype " - << syncer::ModelTypeToString(datatype) - << " on " << profile_debug_name_ << "."; + DVLOG(1) << "EnableSyncForType(): Enabled sync for type " + << syncer::GetUserSelectableTypeName(type) << " on " + << profile_debug_name_ << "."; return true; } - DVLOG(0) << GetClientInfoString("EnableSyncForDatatype failed"); + DVLOG(0) << GetClientInfoString("EnableSyncForType failed"); return false; } -bool ProfileSyncServiceHarness::DisableSyncForDatatype( - syncer::ModelType datatype) { +bool ProfileSyncServiceHarness::DisableSyncForType( + syncer::UserSelectableType type) { DVLOG(1) << GetClientInfoString( - "DisableSyncForDatatype(" - + std::string(syncer::ModelTypeToString(datatype)) + ")"); + "DisableSyncForType(" + + std::string(syncer::GetUserSelectableTypeName(type)) + ")"); if (service() == nullptr) { - LOG(ERROR) << "DisableSyncForDatatype(): service() is null."; + LOG(ERROR) << "DisableSyncForType(): service() is null."; return false; } - if (!syncer::UserSelectableTypes().Has(datatype)) { - LOG(ERROR) << "Can only disable user selectable types, requested " - << syncer::ModelTypeToString(datatype); - return false; - } - - syncer::ModelTypeSet synced_datatypes = - service()->GetUserSettings()->GetChosenDataTypes(); - if (!synced_datatypes.Has(datatype)) { - DVLOG(1) << "DisableSyncForDatatype(): Sync already disabled for datatype " - << syncer::ModelTypeToString(datatype) - << " on " << profile_debug_name_ << "."; + syncer::UserSelectableTypeSet selected_types = + service()->GetUserSettings()->GetSelectedTypes(); + if (!selected_types.Has(type)) { + DVLOG(1) << "DisableSyncForType(): Sync already disabled for type " + << syncer::GetUserSelectableTypeName(type) << " on " + << profile_debug_name_ << "."; return true; } - synced_datatypes.RetainAll(syncer::UserSelectableTypes()); - synced_datatypes.Remove(datatype); - service()->GetUserSettings()->SetChosenDataTypes(false, synced_datatypes); + selected_types.Remove(type); + service()->GetUserSettings()->SetSelectedTypes(false, selected_types); if (AwaitSyncSetupCompletion()) { - DVLOG(1) << "DisableSyncForDatatype(): Disabled sync for datatype " - << syncer::ModelTypeToString(datatype) - << " on " << profile_debug_name_ << "."; + DVLOG(1) << "DisableSyncForType(): Disabled sync for type " + << syncer::GetUserSelectableTypeName(type) << " on " + << profile_debug_name_ << "."; return true; } @@ -529,8 +516,8 @@ return false; } - service()->GetUserSettings()->SetChosenDataTypes( - true, syncer::UserSelectableTypes()); + service()->GetUserSettings()->SetSelectedTypes( + true, syncer::UserSelectableTypeSet::All()); if (AwaitSyncSetupCompletion()) { DVLOG(1) << "EnableSyncForAllDatatypes(): Enabled sync for all datatypes " @@ -560,7 +547,7 @@ SyncCycleSnapshot ProfileSyncServiceHarness::GetLastCycleSnapshot() const { DCHECK(service() != nullptr) << "Sync service has not yet been set up."; if (service()->IsSyncFeatureActive()) { - return service()->GetLastCycleSnapshot(); + return service()->GetLastCycleSnapshotForDebugging(); } return SyncCycleSnapshot(); }
diff --git a/chrome/browser/sync/test/integration/profile_sync_service_harness.h b/chrome/browser/sync/test/integration/profile_sync_service_harness.h index ec5fae6..6677080 100644 --- a/chrome/browser/sync/test/integration/profile_sync_service_harness.h +++ b/chrome/browser/sync/test/integration/profile_sync_service_harness.h
@@ -12,7 +12,7 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "base/optional.h" -#include "components/sync/base/model_type.h" +#include "components/sync/base/user_selectable_type.h" #include "components/sync/driver/profile_sync_service.h" #include "components/sync/engine/cycle/sync_cycle_snapshot.h" @@ -63,23 +63,24 @@ // to process changes. bool SetupSync(); - // Enables and configures sync only for the given |synced_datatypes|. + // Enables and configures sync only for the given |selected_types|. // Does not wait for sync to be ready to process changes -- callers need to // ensure this by calling AwaitSyncSetupCompletion() or // AwaitSyncTransportActive(). // Returns true on success. - bool SetupSyncNoWaitForCompletion(syncer::ModelTypeSet synced_datatypes); + bool SetupSyncNoWaitForCompletion( + syncer::UserSelectableTypeSet selected_types); // Same as SetupSyncNoWaitForCompletion(), but also sets the given encryption // passphrase during setup. bool SetupSyncWithEncryptionPassphraseNoWaitForCompletion( - syncer::ModelTypeSet synced_datatypes, + syncer::UserSelectableTypeSet selected_types, const std::string& passphrase); // Same as SetupSyncNoWaitForCompletion(), but also sets the given decryption // passphrase during setup. bool SetupSyncWithDecryptionPassphraseNoWaitForCompletion( - syncer::ModelTypeSet synced_datatypes, + syncer::UserSelectableTypeSet selected_types, const std::string& passphrase); // Signals that sync setup is complete, and that PSS may begin syncing. @@ -145,11 +146,13 @@ // Returns the debug name for this profile. Used for logging. const std::string& profile_debug_name() const { return profile_debug_name_; } - // Enables sync for a particular sync datatype. Returns true on success. - bool EnableSyncForDatatype(syncer::ModelType datatype); + // Enables sync for a particular selectable sync type (will enable sync for + // all corresponding datatypes). Returns true on success. + bool EnableSyncForType(syncer::UserSelectableType type); - // Disables sync for a particular sync datatype. Returns true on success. - bool DisableSyncForDatatype(syncer::ModelType datatype); + // Disables sync for a particular selectable sync type (will enable sync for + // all corresponding datatypes). Returns true on success. + bool DisableSyncForType(syncer::UserSelectableType type); // Enables sync for all sync datatypes. Returns true on success. bool EnableSyncForAllDatatypes(); @@ -180,7 +183,7 @@ // |encryption_mode|. // If |encryption_mode| is kDecryption or kEncryption, |encryption_passphrase| // has to have a value which will be used to properly setup sync. - bool SetupSyncImpl(syncer::ModelTypeSet synced_datatypes, + bool SetupSyncImpl(syncer::UserSelectableTypeSet selected_types, EncryptionSetupMode encryption_mode, const base::Optional<std::string>& encryption_passphrase);
diff --git a/chrome/browser/sync/test/integration/quiesce_status_change_checker.cc b/chrome/browser/sync/test/integration/quiesce_status_change_checker.cc index 3005938..a351fa1 100644 --- a/chrome/browser/sync/test/integration/quiesce_status_change_checker.cc +++ b/chrome/browser/sync/test/integration/quiesce_status_change_checker.cc
@@ -56,8 +56,10 @@ Intersection(service1->GetActiveDataTypes(), service2->GetActiveDataTypes()); - const syncer::SyncCycleSnapshot& snap1 = service1->GetLastCycleSnapshot(); - const syncer::SyncCycleSnapshot& snap2 = service2->GetLastCycleSnapshot(); + const syncer::SyncCycleSnapshot& snap1 = + service1->GetLastCycleSnapshotForDebugging(); + const syncer::SyncCycleSnapshot& snap2 = + service2->GetLastCycleSnapshotForDebugging(); for (syncer::ModelType type : common_types) { // Look up the progress markers. Fail if either one is missing.
diff --git a/chrome/browser/sync/test/integration/single_client_app_list_sync_test.cc b/chrome/browser/sync/test/integration/single_client_app_list_sync_test.cc index 186a450..1953e6a 100644 --- a/chrome/browser/sync/test/integration/single_client_app_list_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_app_list_sync_test.cc
@@ -172,8 +172,8 @@ ASSERT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait()); // Disable app sync. - sync_service->GetUserSettings()->SetChosenDataTypes(false, - syncer::ModelTypeSet()); + sync_service->GetUserSettings()->SetSelectedTypes( + false, syncer::UserSelectableTypeSet()); // Change data when sync is off. for (const auto& app_id : app_ids) { @@ -188,8 +188,8 @@ EXPECT_FALSE(SyncItemsMatch(service, &compare_service)); // Restore sync and sync data should override local changes. - sync_service->GetUserSettings()->SetChosenDataTypes(true, - syncer::ModelTypeSet()); + sync_service->GetUserSettings()->SetSelectedTypes( + true, syncer::UserSelectableTypeSet()); EXPECT_TRUE(AppListSyncUpdateWaiter(service).Wait()); EXPECT_TRUE(SyncItemsMatch(service, &compare_service)); }
diff --git a/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc b/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc index 8bace26..4d6505f 100644 --- a/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_secondary_account_sync_test.cc
@@ -150,8 +150,8 @@ // Make sure that some model type which is not allowed in transport-only mode // got activated. ASSERT_FALSE(AllowedTypesInStandaloneTransportMode().Has(syncer::BOOKMARKS)); - ASSERT_TRUE(GetSyncService(0)->GetUserSettings()->GetChosenDataTypes().Has( - syncer::BOOKMARKS)); + ASSERT_TRUE(GetSyncService(0)->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kBookmarks)); EXPECT_TRUE(GetSyncService(0)->GetActiveDataTypes().Has(syncer::BOOKMARKS)); } #endif // !defined(OS_CHROMEOS)
diff --git a/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc b/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc index 57c1655..550ed9e 100644 --- a/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc
@@ -178,7 +178,8 @@ SessionSyncServiceFactory::GetForProfile(GetProfile(0)); EXPECT_NE(nullptr, service->GetOpenTabsUIDelegate()); - ASSERT_TRUE(GetClient(0)->DisableSyncForDatatype(syncer::PROXY_TABS)); + ASSERT_TRUE( + GetClient(0)->DisableSyncForType(syncer::UserSelectableType::kTabs)); EXPECT_EQ(nullptr, service->GetOpenTabsUIDelegate()); } @@ -269,7 +270,8 @@ // If the user disables history sync on settings, but still enables tab sync, // then sessions should be synced but the server should be able to tell the // difference based on active datatypes. - ASSERT_TRUE(GetClient(0)->DisableSyncForDatatype(syncer::TYPED_URLS)); + ASSERT_TRUE( + GetClient(0)->DisableSyncForType(syncer::UserSelectableType::kHistory)); ASSERT_TRUE(CheckInitialState(0)); ASSERT_TRUE(OpenTab(0, GURL(kURL1)));
diff --git a/chrome/browser/sync/test/integration/single_client_standalone_transport_sync_test.cc b/chrome/browser/sync/test/integration/single_client_standalone_transport_sync_test.cc index bbb953a..53524bb 100644 --- a/chrome/browser/sync/test/integration/single_client_standalone_transport_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_standalone_transport_sync_test.cc
@@ -126,8 +126,8 @@ // Make sure that some model type which is not allowed in transport-only mode // got activated. ASSERT_FALSE(AllowedTypesInStandaloneTransportMode().Has(syncer::BOOKMARKS)); - ASSERT_TRUE(GetSyncService(0)->GetUserSettings()->GetChosenDataTypes().Has( - syncer::BOOKMARKS)); + ASSERT_TRUE(GetSyncService(0)->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kBookmarks)); EXPECT_TRUE(GetSyncService(0)->GetActiveDataTypes().Has(syncer::BOOKMARKS)); // Turn off Sync-the-feature by user choice. The machinery should start up
diff --git a/chrome/browser/sync/test/integration/single_client_user_events_sync_test.cc b/chrome/browser/sync/test/integration/single_client_user_events_sync_test.cc index a47fe82..17d47bf2 100644 --- a/chrome/browser/sync/test/integration/single_client_user_events_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_user_events_sync_test.cc
@@ -200,13 +200,15 @@ event_service->RecordUserEvent(test_event1); // Wait until the first events is committed before disabling sync, - // because disabled TYPED_URLS also disables user event sync, dropping all + // because disabled kHistory also disables user event sync, dropping all // uncommitted events. EXPECT_TRUE(ExpectUserEvents({test_event1})); - ASSERT_TRUE(GetClient(0)->DisableSyncForDatatype(syncer::TYPED_URLS)); + ASSERT_TRUE( + GetClient(0)->DisableSyncForType(syncer::UserSelectableType::kHistory)); event_service->RecordUserEvent(test_event2); - ASSERT_TRUE(GetClient(0)->EnableSyncForDatatype(syncer::TYPED_URLS)); + ASSERT_TRUE( + GetClient(0)->EnableSyncForType(syncer::UserSelectableType::kHistory)); event_service->RecordUserEvent(test_event3); // No |test_event2| because it was recorded while history was disabled. @@ -217,7 +219,8 @@ const UserEventSpecifics specifics = CreateTestEvent(base::Time() + base::TimeDelta::FromMicroseconds(1)); ASSERT_TRUE(SetupSync()); - ASSERT_TRUE(GetClient(0)->DisableSyncForDatatype(syncer::PROXY_TABS)); + ASSERT_TRUE( + GetClient(0)->DisableSyncForType(syncer::UserSelectableType::kTabs)); syncer::UserEventService* event_service = browser_sync::UserEventServiceFactory::GetForProfile(GetProfile(0));
diff --git a/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc b/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc index c1353fc..1836e9e 100644 --- a/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_wallet_sync_test.cc
@@ -128,7 +128,8 @@ bool IsExitConditionSatisfied() override { // GetLastCycleSnapshot() returns by value, so make sure to capture it for // iterator use. - const syncer::SyncCycleSnapshot snap = service_->GetLastCycleSnapshot(); + const syncer::SyncCycleSnapshot snap = + service_->GetLastCycleSnapshotForDebugging(); const syncer::ProgressMarkerMap& progress_markers = snap.download_progress_markers(); auto marker_it = progress_markers.find(syncer::AUTOFILL_WALLET_DATA); @@ -152,7 +153,8 @@ const syncer::ProfileSyncService* service) { // GetLastCycleSnapshot() returns by value, so make sure to capture it for // iterator use. - const syncer::SyncCycleSnapshot snap = service->GetLastCycleSnapshot(); + const syncer::SyncCycleSnapshot snap = + service->GetLastCycleSnapshotForDebugging(); const syncer::ProgressMarkerMap& progress_markers = snap.download_progress_markers(); auto marker_it = progress_markers.find(syncer::AUTOFILL_WALLET_DATA); @@ -1069,7 +1071,8 @@ ASSERT_EQ(1U, GetServerAddressesMetadata(0).size()); // Turn off autofill sync, the data & metadata should be gone. - ASSERT_TRUE(GetClient(0)->DisableSyncForDatatype(syncer::AUTOFILL)); + ASSERT_TRUE( + GetClient(0)->DisableSyncForType(syncer::UserSelectableType::kAutofill)); WaitForOnPersonalDataChanged(/*should_trigger_refresh=*/false, pdm); EXPECT_EQ(0uL, pdm->GetServerProfiles().size()); @@ -1569,8 +1572,8 @@ ASSERT_EQ(syncer::SyncService::TransportState::PENDING_DESIRED_CONFIGURATION, GetSyncService(0)->GetTransportState()); - GetSyncService(0)->GetUserSettings()->SetChosenDataTypes( - /*sync_everything=*/false, syncer::ModelTypeSet(syncer::AUTOFILL)); + GetSyncService(0)->GetUserSettings()->SetSelectedTypes( + /*sync_everything=*/false, {syncer::UserSelectableType::kAutofill}); // Once the user finishes the setup, we can actually configure. setup_handle.reset();
diff --git a/chrome/browser/sync/test/integration/sync_errors_test.cc b/chrome/browser/sync/test/integration/sync_errors_test.cc index bf1f998d..5b5ebc8c 100644 --- a/chrome/browser/sync/test/integration/sync_errors_test.cc +++ b/chrome/browser/sync/test/integration/sync_errors_test.cc
@@ -177,7 +177,8 @@ // In contrast on auto start enabled platforms like chrome os we should be // able to set up even if the first sync while setting up fails. ASSERT_TRUE(SetupSync()) << "Setup sync failed"; - ASSERT_TRUE(GetClient(0)->DisableSyncForDatatype(syncer::AUTOFILL)); + ASSERT_TRUE( + GetClient(0)->DisableSyncForType(syncer::UserSelectableType::kAutofill)); #endif EXPECT_TRUE(GetFakeServer()->TriggerError( @@ -190,7 +191,8 @@ #else // Now enable a datatype, whose first 2 syncs would fail, but we should // recover and setup succesfully on the third attempt. - ASSERT_TRUE(GetClient(0)->EnableSyncForDatatype(syncer::AUTOFILL)); + ASSERT_TRUE( + GetClient(0)->EnableSyncForType(syncer::UserSelectableType::kAutofill)); #endif }
diff --git a/chrome/browser/sync/test/integration/sync_exponential_backoff_test.cc b/chrome/browser/sync/test/integration/sync_exponential_backoff_test.cc index d36d9388..3fd52dc 100644 --- a/chrome/browser/sync/test/integration/sync_exponential_backoff_test.cc +++ b/chrome/browser/sync/test/integration/sync_exponential_backoff_test.cc
@@ -42,14 +42,16 @@ public: explicit ExponentialBackoffChecker(syncer::ProfileSyncService* pss) : SingleClientStatusChangeChecker(pss) { - const SyncCycleSnapshot& snap = service()->GetLastCycleSnapshot(); + const SyncCycleSnapshot& snap = + service()->GetLastCycleSnapshotForDebugging(); retry_verifier_.Initialize(snap); } // Checks if backoff is complete. Called repeatedly each time PSS notifies // observers of a state change. bool IsExitConditionSatisfied() override { - const SyncCycleSnapshot& snap = service()->GetLastCycleSnapshot(); + const SyncCycleSnapshot& snap = + service()->GetLastCycleSnapshotForDebugging(); retry_verifier_.VerifyRetryInterval(snap); return (retry_verifier_.done() && retry_verifier_.Succeeded()); } @@ -100,7 +102,7 @@ // Verify that recovery time is short. Without canary job recovery time would // be more than 5 seconds. base::TimeDelta recovery_time = - GetSyncService(0)->GetLastCycleSnapshot().sync_start_time() - + GetSyncService(0)->GetLastCycleSnapshotForDebugging().sync_start_time() - network_notification_time; ASSERT_LE(recovery_time, base::TimeDelta::FromSeconds(2)); }
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc index 951fa3d..204949b 100644 --- a/chrome/browser/sync/test/integration/sync_test.cc +++ b/chrome/browser/sync/test/integration/sync_test.cc
@@ -734,14 +734,17 @@ if (encryption_passphrase_provided) { CHECK(client->SetupSyncWithEncryptionPassphraseNoWaitForCompletion( - syncer::UserSelectableTypes(), encryption_passphrase_it->second)) + syncer::UserSelectableTypeSet::All(), + encryption_passphrase_it->second)) << "SetupSync() failed."; } else if (decryption_passphrase_provided) { CHECK(client->SetupSyncWithDecryptionPassphraseNoWaitForCompletion( - syncer::UserSelectableTypes(), decryption_passphrase_it->second)) + syncer::UserSelectableTypeSet::All(), + decryption_passphrase_it->second)) << "SetupSync() failed."; } else { - CHECK(client->SetupSyncNoWaitForCompletion(syncer::UserSelectableTypes())) + CHECK(client->SetupSyncNoWaitForCompletion( + syncer::UserSelectableTypeSet::All())) << "SetupSync() failed."; } if (wait_for_completion) { @@ -983,11 +986,11 @@ // In order to kick off the encryption we have to reconfigure. Just grab the // currently synced types and use them. - syncer::ModelTypeSet synced_datatypes = - service->GetUserSettings()->GetChosenDataTypes(); - bool sync_everything = (synced_datatypes == syncer::UserSelectableTypes()); - service->GetUserSettings()->SetChosenDataTypes(sync_everything, - synced_datatypes); + syncer::UserSelectableTypeSet selected_types = + service->GetUserSettings()->GetSelectedTypes(); + bool sync_everything = + (selected_types == syncer::UserSelectableTypeSet::All()); + service->GetUserSettings()->SetSelectedTypes(sync_everything, selected_types); return AwaitEncryptionComplete(index); }
diff --git a/chrome/browser/sync/test/integration/two_client_app_list_sync_test.cc b/chrome/browser/sync/test/integration/two_client_app_list_sync_test.cc index d002a3d..88a79ad 100644 --- a/chrome/browser/sync/test/integration/two_client_app_list_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_app_list_sync_test.cc
@@ -314,14 +314,16 @@ ASSERT_TRUE(SetupSync()); ASSERT_TRUE(AllProfilesHaveSameAppList()); - // Disable APP_LIST by disabling APPS since APP_LIST is in APPS groups. - ASSERT_TRUE(GetClient(1)->DisableSyncForDatatype(syncer::APPS)); + // Disable APP_LIST by disabling kApps since APP_LIST is in kApps groups. + ASSERT_TRUE( + GetClient(1)->DisableSyncForType(syncer::UserSelectableType::kApps)); InstallApp(GetProfile(0), 0); ASSERT_TRUE(UpdatedProgressMarkerChecker(GetSyncService(0)).Wait()); ASSERT_FALSE(AllProfilesHaveSameAppList()); - // Enable APP_LIST by enabling APPS since APP_LIST is in APPS groups. - ASSERT_TRUE(GetClient(1)->EnableSyncForDatatype(syncer::APPS)); + // Enable APP_LIST by enabling kApps since APP_LIST is in kApps groups. + ASSERT_TRUE( + GetClient(1)->EnableSyncForType(syncer::UserSelectableType::kApps)); AwaitQuiescenceAndInstallAppsPendingForSync(); ASSERT_TRUE(AllProfilesHaveSameAppList());
diff --git a/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc b/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc index c6fef52b..b10658e4 100644 --- a/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc
@@ -1598,12 +1598,14 @@ ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; ASSERT_TRUE(AllModelsMatchVerifier()); - ASSERT_TRUE(GetClient(1)->DisableSyncForDatatype(syncer::BOOKMARKS)); + ASSERT_TRUE( + GetClient(1)->DisableSyncForType(syncer::UserSelectableType::kBookmarks)); ASSERT_NE(nullptr, AddFolder(1, kGenericFolderName)); ASSERT_TRUE(AwaitQuiescence()); ASSERT_FALSE(AllModelsMatch()); - ASSERT_TRUE(GetClient(1)->EnableSyncForDatatype(syncer::BOOKMARKS)); + ASSERT_TRUE( + GetClient(1)->EnableSyncForType(syncer::UserSelectableType::kBookmarks)); ASSERT_TRUE(BookmarksMatchChecker().Wait()); } @@ -1651,7 +1653,8 @@ IN_PROC_BROWSER_TEST_P(TwoClientBookmarksSyncTestIncludingUssTests, MC_DeleteBookmark) { ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; - ASSERT_TRUE(GetClient(1)->DisableSyncForDatatype(syncer::BOOKMARKS)); + ASSERT_TRUE( + GetClient(1)->DisableSyncForType(syncer::UserSelectableType::kBookmarks)); const GURL bar_url("http://example.com/bar"); const GURL other_url("http://example.com/other"); @@ -1672,7 +1675,8 @@ ASSERT_FALSE(HasNodeWithURL(0, bar_url)); ASSERT_TRUE(HasNodeWithURL(0, other_url)); - ASSERT_TRUE(GetClient(1)->EnableSyncForDatatype(syncer::BOOKMARKS)); + ASSERT_TRUE( + GetClient(1)->EnableSyncForType(syncer::UserSelectableType::kBookmarks)); ASSERT_TRUE(AwaitQuiescence()); ASSERT_FALSE(HasNodeWithURL(0, bar_url)); @@ -2258,11 +2262,13 @@ // Disable bookmark syncing on the first client, add another bookmark, // re-enable bookmark syncing and see that the second bookmark reaches the // second client. - ASSERT_TRUE(GetClient(0)->DisableSyncForDatatype(syncer::BOOKMARKS)); + ASSERT_TRUE( + GetClient(0)->DisableSyncForType(syncer::UserSelectableType::kBookmarks)); const std::string url_title_2 = "another happy little url"; const GURL url_2("https://example.com/second"); ASSERT_NE(nullptr, AddURL(0, GetBookmarkBarNode(0), 0, url_title_2, url_2)); - ASSERT_TRUE(GetClient(0)->EnableSyncForDatatype(syncer::BOOKMARKS)); + ASSERT_TRUE( + GetClient(0)->EnableSyncForType(syncer::UserSelectableType::kBookmarks)); ASSERT_TRUE(BookmarksMatchChecker().Wait()); ASSERT_EQ(initial_count + 2, CountAllBookmarks(0)); ASSERT_EQ(initial_count + 2, CountAllBookmarks(1));
diff --git a/chrome/browser/sync/test/integration/two_client_custom_passphrase_sync_test.cc b/chrome/browser/sync/test/integration/two_client_custom_passphrase_sync_test.cc index bec63c3..fd47be2 100644 --- a/chrome/browser/sync/test/integration/two_client_custom_passphrase_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_custom_passphrase_sync_test.cc
@@ -106,7 +106,7 @@ // Set up a new sync client. ASSERT_TRUE( GetClient(kDecryptingClientId) - ->SetupSyncNoWaitForCompletion(syncer::UserSelectableTypes())); + ->SetupSyncNoWaitForCompletion(syncer::UserSelectableTypeSet::All())); ASSERT_TRUE( PassphraseRequiredChecker(GetSyncService(kDecryptingClientId)).Wait());
diff --git a/chrome/browser/sync/test/integration/two_client_passwords_sync_test.cc b/chrome/browser/sync/test/integration/two_client_passwords_sync_test.cc index d092f99..ba88eca7 100644 --- a/chrome/browser/sync/test/integration/two_client_passwords_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_passwords_sync_test.cc
@@ -306,7 +306,7 @@ // When client 1 hits a passphrase required state, we can infer that // client 0's passphrase has been committed. to the server. ASSERT_TRUE(GetClient(1)->SetupSyncNoWaitForCompletion( - syncer::UserSelectableTypes())); + syncer::UserSelectableTypeSet::All())); ASSERT_TRUE(PassphraseRequiredChecker(GetSyncService(1)).Wait()); // Get client 1 out of the passphrase required state.
diff --git a/chrome/browser/sync/test/integration/two_client_polling_sync_test.cc b/chrome/browser/sync/test/integration/two_client_polling_sync_test.cc index 8924e7e..2f44aa6 100644 --- a/chrome/browser/sync/test/integration/two_client_polling_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_polling_sync_test.cc
@@ -81,8 +81,8 @@ // clear its data even with KEEP_DATA, which means we'd always send a regular // GetUpdates request on starting Sync again, and so we'd have no need for a // poll. - GetClient(0)->DisableSyncForDatatype(syncer::AUTOFILL); - GetClient(1)->DisableSyncForDatatype(syncer::AUTOFILL); + GetClient(0)->DisableSyncForType(syncer::UserSelectableType::kAutofill); + GetClient(1)->DisableSyncForType(syncer::UserSelectableType::kAutofill); // TODO(crbug.com/890737): Once AUTOFILL_WALLET_DATA gets properly disabled // based on the pref, we can just disable that instead of all of AUTOFILL: // autofill::prefs::SetPaymentsIntegrationEnabled(GetProfile(0)->GetPrefs(),
diff --git a/chrome/browser/sync/test/integration/two_client_typed_urls_sync_test.cc b/chrome/browser/sync/test/integration/two_client_typed_urls_sync_test.cc index f8c7392..31c9057a 100644 --- a/chrome/browser/sync/test/integration/two_client_typed_urls_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_typed_urls_sync_test.cc
@@ -427,8 +427,8 @@ const base::string16 kUrl2(ASCIIToUTF16("http://history2.google.com/")); ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; - // Disable typed url sync for one client, leave it active for the other. - GetClient(0)->DisableSyncForDatatype(syncer::TYPED_URLS); + // Disable history sync for one client, leave it active for the other. + GetClient(0)->DisableSyncForType(syncer::UserSelectableType::kHistory); // Add one URL to non-syncing client, add a different URL to the other, // wait for sync cycle to complete. No data should be exchanged. @@ -446,8 +446,8 @@ ASSERT_EQ(1U, post_sync_urls.size()); ASSERT_EQ(url2, post_sync_urls[0].url()); - // Enable typed url sync, make both URLs are synced to each client. - GetClient(0)->EnableSyncForDatatype(syncer::TYPED_URLS); + // Enable history sync, make both URLs are synced to each client. + GetClient(0)->EnableSyncForType(syncer::UserSelectableType::kHistory); ASSERT_TRUE(ProfilesHaveSameTypedURLsChecker().Wait()); }
diff --git a/chrome/browser/sync/test/integration/two_client_user_events_sync_test.cc b/chrome/browser/sync/test/integration/two_client_user_events_sync_test.cc index d5f35d3..2e3e3843 100644 --- a/chrome/browser/sync/test/integration/two_client_user_events_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_user_events_sync_test.cc
@@ -75,7 +75,7 @@ // Set up sync on the second client. ASSERT_TRUE( GetClient(kDecryptingClientId) - ->SetupSyncNoWaitForCompletion(syncer::UserSelectableTypes())); + ->SetupSyncNoWaitForCompletion(syncer::UserSelectableTypeSet::All())); // The second client asks the user to provide a password for decryption. ASSERT_TRUE( PassphraseRequiredChecker(GetSyncService(kDecryptingClientId)).Wait());
diff --git a/chrome/browser/sync/test/integration/two_client_uss_sync_test.cc b/chrome/browser/sync/test/integration/two_client_uss_sync_test.cc index ad8ffb6..0b1edb5 100644 --- a/chrome/browser/sync/test/integration/two_client_uss_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_uss_sync_test.cc
@@ -211,7 +211,8 @@ : SingleClientStatusChangeChecker(service) {} bool IsExitConditionSatisfied() override { - const syncer::SyncCycleSnapshot& snap = service()->GetLastCycleSnapshot(); + const syncer::SyncCycleSnapshot& snap = + service()->GetLastCycleSnapshotForDebugging(); return HasSyncerError(snap.model_neutral_state()); } @@ -310,9 +311,9 @@ ASSERT_EQ(1U, model1->db().metadata_count()); // Disable PREFERENCES. - syncer::ModelTypeSet types = syncer::UserSelectableTypes(); - types.Remove(syncer::PREFERENCES); - GetSyncService(0)->GetUserSettings()->SetChosenDataTypes(false, types); + syncer::UserSelectableTypeSet types = syncer::UserSelectableTypeSet::All(); + types.Remove(syncer::UserSelectableType::kPreferences); + GetSyncService(0)->GetUserSettings()->SetSelectedTypes(false, types); // Wait for it to take effect and remove the metadata. ASSERT_TRUE(MetadataAbsentChecker(model0, kKey1).Wait()); @@ -323,8 +324,8 @@ ASSERT_EQ(1U, model1->db().metadata_count()); // Re-enable PREFERENCES. - GetSyncService(0)->GetUserSettings()->SetChosenDataTypes( - true, syncer::UserSelectableTypes()); + GetSyncService(0)->GetUserSettings()->SetSelectedTypes( + true, syncer::UserSelectableTypeSet::All()); // Wait for metadata to be re-added. ASSERT_TRUE(MetadataPresentChecker(model0, kKey1).Wait());
diff --git a/chrome/browser/sync/test/integration/updated_progress_marker_checker.cc b/chrome/browser/sync/test/integration/updated_progress_marker_checker.cc index 3d70c20..a561c53b 100644 --- a/chrome/browser/sync/test/integration/updated_progress_marker_checker.cc +++ b/chrome/browser/sync/test/integration/updated_progress_marker_checker.cc
@@ -30,7 +30,8 @@ return false; } - const syncer::SyncCycleSnapshot& snap = service()->GetLastCycleSnapshot(); + const syncer::SyncCycleSnapshot& snap = + service()->GetLastCycleSnapshotForDebugging(); // Assuming the lack of ongoing remote changes, the progress marker can be // considered updated when: // 1. Progress markers are non-empty (which discards the default value for @@ -63,7 +64,8 @@ } // Override |has_unsynced_items_| with the result of the sync cycle. - const syncer::SyncCycleSnapshot& snap = service()->GetLastCycleSnapshot(); + const syncer::SyncCycleSnapshot& snap = + service()->GetLastCycleSnapshotForDebugging(); has_unsynced_items_ = snap.has_remaining_local_changes(); CheckExitCondition(); }
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index d01183f6..535c4f0 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -70,8 +70,6 @@ "autofill/popup_controller_common.h", "autofill/popup_view_common.cc", "autofill/popup_view_common.h", - "bloated_renderer/bloated_renderer_tab_helper.cc", - "bloated_renderer/bloated_renderer_tab_helper.h", "blocked_content/blocked_window_params.cc", "blocked_content/blocked_window_params.h", "blocked_content/list_item_position.cc",
diff --git a/chrome/browser/ui/android/passwords/password_generation_dialog_view_android.cc b/chrome/browser/ui/android/passwords/password_generation_dialog_view_android.cc index 4e1253b..6aec6269 100644 --- a/chrome/browser/ui/android/passwords/password_generation_dialog_view_android.cc +++ b/chrome/browser/ui/android/passwords/password_generation_dialog_view_android.cc
@@ -6,10 +6,12 @@ #include "base/android/jni_android.h" #include "base/android/jni_string.h" +#include "base/memory/weak_ptr.h" #include "base/strings/string16.h" #include "chrome/browser/password_manager/password_generation_controller_impl.h" #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" +#include "components/password_manager/core/browser/password_manager_driver.h" #include "components/strings/grit/components_strings.h" #include "jni/PasswordGenerationDialogBridge_jni.h" #include "ui/android/window_android.h" @@ -32,7 +34,11 @@ base::android::AttachCurrentThread(), java_object_); } -void PasswordGenerationDialogViewAndroid::Show(base::string16& password) { +void PasswordGenerationDialogViewAndroid::Show( + base::string16& password, + base::WeakPtr<password_manager::PasswordManagerDriver> + target_frame_driver) { + target_frame_driver_ = std::move(target_frame_driver); JNIEnv* env = base::android::AttachCurrentThread(); base::string16 explanation_text = @@ -48,7 +54,8 @@ const base::android::JavaParamRef<jobject>& obj, const base::android::JavaParamRef<jstring>& password) { controller_->GeneratedPasswordAccepted( - base::android::ConvertJavaStringToUTF16(env, password)); + base::android::ConvertJavaStringToUTF16(env, password), + std::move(target_frame_driver_)); } void PasswordGenerationDialogViewAndroid::PasswordRejected(
diff --git a/chrome/browser/ui/android/passwords/password_generation_dialog_view_android.h b/chrome/browser/ui/android/passwords/password_generation_dialog_view_android.h index 1335e7c..21e62e0a 100644 --- a/chrome/browser/ui/android/passwords/password_generation_dialog_view_android.h +++ b/chrome/browser/ui/android/passwords/password_generation_dialog_view_android.h
@@ -26,7 +26,9 @@ ~PasswordGenerationDialogViewAndroid() override; // Called to show the dialog. |password| is the generated password. - void Show(base::string16& password) override; + void Show(base::string16& password, + base::WeakPtr<password_manager::PasswordManagerDriver> + target_frame_driver) override; // Called from Java via JNI. void PasswordAccepted(JNIEnv* env, @@ -44,6 +46,10 @@ // The corresponding java object. base::android::ScopedJavaGlobalRef<jobject> java_object_; + // The driver corresponding to the frame for which the generation request was + // made. Used to ensure that the accepted password message is sent back to the + // same frame. + base::WeakPtr<password_manager::PasswordManagerDriver> target_frame_driver_; DISALLOW_COPY_AND_ASSIGN(PasswordGenerationDialogViewAndroid); };
diff --git a/chrome/browser/ui/bloated_renderer/OWNERS b/chrome/browser/ui/bloated_renderer/OWNERS deleted file mode 100644 index 51f6060..0000000 --- a/chrome/browser/ui/bloated_renderer/OWNERS +++ /dev/null
@@ -1,4 +0,0 @@ -hpayer@chromium.org -ulan@chromium.org - -# COMPONENT: Blink>JavaScript
diff --git a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.cc b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.cc deleted file mode 100644 index 273ad22d..0000000 --- a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.cc +++ /dev/null
@@ -1,148 +0,0 @@ -// 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/ui/bloated_renderer/bloated_renderer_tab_helper.h" - -#include "base/metrics/histogram_macros.h" -#include "chrome/browser/infobars/infobar_service.h" -#include "chrome/browser/resource_coordinator/utils.h" -#include "chrome/grit/generated_resources.h" -#include "components/infobars/core/simple_alert_infobar_delegate.h" -#include "content/public/browser/navigation_entry.h" -#include "content/public/browser/navigation_handle.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/common/content_features.h" -#include "content/public/common/page_importance_signals.h" -#include "ui/base/l10n/l10n_util.h" - -namespace { - -// These values are persisted to logs. Entries should not be renumbered and -// numeric values should never be reused. -enum class BloatedRendererHandlingInBrowser { - kReloaded = 0, - kCannotReload = 1, - kCannotShutdown = 2, - kMaxValue = kCannotShutdown -}; - -void RecordBloatedRendererHandling(BloatedRendererHandlingInBrowser handling) { - UMA_HISTOGRAM_ENUMERATION("BloatedRenderer.HandlingInBrowser", handling); -} - -} // anonymous namespace - -BloatedRendererTabHelper::BloatedRendererTabHelper( - content::WebContents* contents) - : content::WebContentsObserver(contents) { - if (auto* page_signal_receiver = - resource_coordinator::GetPageSignalReceiver()) - page_signal_receiver->AddObserver(this); -} - -void BloatedRendererTabHelper::DidStartNavigation( - content::NavigationHandle* navigation_handle) { - if (state_ == State::kRequestingReload) { - saved_navigation_id_ = navigation_handle->GetNavigationId(); - state_ = State::kStartedNavigation; - } -} - -void BloatedRendererTabHelper::DidFinishNavigation( - content::NavigationHandle* navigation_handle) { - if (state_ == State::kStartedNavigation && - saved_navigation_id_ == navigation_handle->GetNavigationId()) { - ShowInfoBar(InfoBarService::FromWebContents(web_contents())); - state_ = State::kInactive; - saved_navigation_id_ = 0; - } -} - -void BloatedRendererTabHelper::WebContentsDestroyed() { - if (auto* page_signal_receiver = - resource_coordinator::GetPageSignalReceiver()) - page_signal_receiver->RemoveObserver(this); -} - -void BloatedRendererTabHelper::ShowInfoBar(InfoBarService* infobar_service) { - if (!infobar_service) { - // No infobar service in unit-tests. - return; - } - const bool auto_expire_on_navigation = true; - SimpleAlertInfoBarDelegate::Create( - infobar_service, - infobars::InfoBarDelegate::BLOATED_RENDERER_INFOBAR_DELEGATE, nullptr, - l10n_util::GetStringUTF16(IDS_BROWSER_BLOATED_RENDERER_INFOBAR), - auto_expire_on_navigation); -} - -bool BloatedRendererTabHelper::CanReloadBloatedTab() { - if (web_contents()->IsCrashed()) - return false; - - // Do not reload tabs that don't have a valid URL (most probably they have - // just been opened and discarding them would lose the URL). - if (!web_contents()->GetLastCommittedURL().is_valid() || - web_contents()->GetLastCommittedURL().is_empty()) { - return false; - } - - // Do not reload tabs in which the user has entered text in a form. - if (web_contents()->GetPageImportanceSignals().had_form_interaction) - return false; - - // Do not reload if no entry was committed. - content::NavigationEntry* committed_entry = - web_contents()->GetController().GetLastCommittedEntry(); - if (!committed_entry) - return false; - - // Do not reload if the visible entry does not match the last committed entry. - // This means that the entry is either transient or pending. - content::NavigationEntry* visible_entry = - web_contents()->GetController().GetVisibleEntry(); - if (visible_entry != committed_entry) - return false; - - // Do not reload if the last committed entry has post data. - if (committed_entry->GetHasPostData()) - return false; - - return true; -} - -void BloatedRendererTabHelper::OnRendererIsBloated( - content::WebContents* bloated_web_contents, - const resource_coordinator::PageNavigationIdentity& page_navigation_id) { - if (!base::FeatureList::IsEnabled(features::kBloatedRendererDetection)) { - return; - } - if (web_contents() != bloated_web_contents) { - // Ignore if the notification is about a different tab. - return; - } - auto* page_signal_receiver = resource_coordinator::GetPageSignalReceiver(); - DCHECK_NE(nullptr, page_signal_receiver); - if (page_navigation_id.navigation_id != - page_signal_receiver->GetNavigationIDForWebContents(web_contents())) { - // Ignore if the notification is pursuant to an earlier navigation. - return; - } - - if (CanReloadBloatedTab()) { - const bool check_for_repost = true; - // Clear the state and the saved navigation id. - state_ = State::kRequestingReload; - saved_navigation_id_ = 0; - web_contents()->GetController().Reload(content::ReloadType::NORMAL, - check_for_repost); - RecordBloatedRendererHandling(BloatedRendererHandlingInBrowser::kReloaded); - } else { - RecordBloatedRendererHandling( - BloatedRendererHandlingInBrowser::kCannotReload); - } -} - -WEB_CONTENTS_USER_DATA_KEY_IMPL(BloatedRendererTabHelper)
diff --git a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h deleted file mode 100644 index 33468cf8..0000000 --- a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h +++ /dev/null
@@ -1,90 +0,0 @@ -// 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_UI_BLOATED_RENDERER_BLOATED_RENDERER_TAB_HELPER_H_ -#define CHROME_BROWSER_UI_BLOATED_RENDERER_BLOATED_RENDERER_TAB_HELPER_H_ - -#include "base/gtest_prod_util.h" -#include "base/macros.h" -#include "chrome/browser/resource_coordinator/page_signal_receiver.h" -#include "content/public/browser/web_contents_observer.h" -#include "content/public/browser/web_contents_user_data.h" - -class InfoBarService; - -// This tab helper observes the OnRendererIsBloated event for its -// WebContents. Upon receiving the event it reloads the bloated tab if -// possible and activates the logic to show an infobar on the -// subsequent DidFinishNavigation event. -// -// Note that we need to show the infobar after NavigationEntryCommitted -// because the infobar service removes existing infobars there. -class BloatedRendererTabHelper - : public content::WebContentsObserver, - public content::WebContentsUserData<BloatedRendererTabHelper>, - public resource_coordinator::PageSignalObserver { - public: - ~BloatedRendererTabHelper() override = default; - - // content::WebContentsObserver: - void DidStartNavigation( - content::NavigationHandle* navigation_handle) override; - void DidFinishNavigation( - content::NavigationHandle* navigation_handle) override; - void WebContentsDestroyed() override; - - // resource_coordinator::PageSignalObserver: - void OnRendererIsBloated(content::WebContents* web_contents, - const resource_coordinator::PageNavigationIdentity& - page_navigation_id) override; - - static void ShowInfoBar(InfoBarService* infobar_service); - - private: - friend class content::WebContentsUserData<BloatedRendererTabHelper>; - FRIEND_TEST_ALL_PREFIXES(BloatedRendererTabHelperTest, DetectReload); - FRIEND_TEST_ALL_PREFIXES(BloatedRendererTabHelperTest, - IgnoreUnrelatedNavigation); - FRIEND_TEST_ALL_PREFIXES(BloatedRendererTabHelperTest, CanReloadBloatedTab); - FRIEND_TEST_ALL_PREFIXES(BloatedRendererTabHelperTest, - CannotReloadBloatedTabCrashed); - FRIEND_TEST_ALL_PREFIXES(BloatedRendererTabHelperTest, - CannotReloadBloatedTabInvalidURL); - FRIEND_TEST_ALL_PREFIXES(BloatedRendererTabHelperTest, - CannotReloadBloatedTabPendingUserInteraction); - FRIEND_TEST_ALL_PREFIXES(BloatedRendererTabHelperTest, - CannotReloadBloatedTabWithPostData); - - enum class State { kInactive, kRequestingReload, kStartedNavigation }; - - explicit BloatedRendererTabHelper(content::WebContents* contents); - - bool CanReloadBloatedTab(); - - // The state transitions as follows: - // - kInactive is the initial state. - // - // - any state => kRequestingReload transition happens in - // OnRendererIsBloated before invoking NavigationController::Reload. - // - // - kRequestingReload => kStartedNavigation transition happens in - // NavigationController::Reload when it invokes DidStartNavigation. - // - // - kStartedNavigation => kInactive transitions happens in - // DidFinishNavigation. - State state_ = State::kInactive; - - // The navigation id is saved on DidStartNavigation event when the state is - // kRequestingReload. The infobar is shown on the subsequent - // DidFinishNavigation only if its navigation id matches the saved id. This - // ensures that the infobar is shown only for the reload that was requested - // in OnRendererIsBloated event. - int64_t saved_navigation_id_ = 0; - - WEB_CONTENTS_USER_DATA_KEY_DECL(); - - DISALLOW_COPY_AND_ASSIGN(BloatedRendererTabHelper); -}; - -#endif // CHROME_BROWSER_UI_BLOATED_RENDERER_BLOATED_RENDERER_TAB_HELPER_H_
diff --git a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper_browsertest.cc b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper_browsertest.cc deleted file mode 100644 index 14675f3d..0000000 --- a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper_browsertest.cc +++ /dev/null
@@ -1,52 +0,0 @@ -// 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/ui/bloated_renderer/bloated_renderer_tab_helper.h" - -#include "base/test/scoped_feature_list.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/infobars/infobar_service.h" -#include "chrome/browser/resource_coordinator/utils.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/common/url_constants.h" -#include "chrome/test/base/in_process_browser_test.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/notification_types.h" -#include "content/public/common/content_features.h" -#include "content/public/test/test_navigation_observer.h" -#include "content/public/test/test_utils.h" - -using BloatedRendererTabHelperBrowserTest = InProcessBrowserTest; - -IN_PROC_BROWSER_TEST_F(BloatedRendererTabHelperBrowserTest, ReloadBloatedTab) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(features::kBloatedRendererDetection); - content::WindowedNotificationObserver load( - content::NOTIFICATION_NAV_ENTRY_COMMITTED, - content::NotificationService::AllSources()); - content::OpenURLParams url( - GURL(chrome::kChromeUIAboutURL), content::Referrer(), - WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, false); - browser()->OpenURL(url); - load.Wait(); - - content::WindowedNotificationObserver reload( - content::NOTIFICATION_NAV_ENTRY_COMMITTED, - content::NotificationService::AllSources()); - content::WebContents* web_contents = - browser()->tab_strip_model()->GetWebContentsAt(0); - InfoBarService* infobar_service = - InfoBarService::FromWebContents(web_contents); - EXPECT_EQ(0u, infobar_service->infobar_count()); - - auto* page_signal_receiver = resource_coordinator::GetPageSignalReceiver(); - resource_coordinator::PageNavigationIdentity page_id; - page_id.navigation_id = - page_signal_receiver->GetNavigationIDForWebContents(web_contents); - BloatedRendererTabHelper::FromWebContents(web_contents) - ->OnRendererIsBloated(web_contents, page_id); - reload.Wait(); - EXPECT_EQ(1u, infobar_service->infobar_count()); -}
diff --git a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper_unittest.cc b/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper_unittest.cc deleted file mode 100644 index ae84766..0000000 --- a/chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper_unittest.cc +++ /dev/null
@@ -1,86 +0,0 @@ -// 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/ui/bloated_renderer/bloated_renderer_tab_helper.h" -#include "chrome/test/base/chrome_render_view_host_test_harness.h" -#include "content/public/browser/navigation_entry.h" -#include "content/public/common/page_importance_signals.h" -#include "content/public/test/mock_navigation_handle.h" -#include "content/public/test/web_contents_tester.h" -#include "testing/gtest/include/gtest/gtest.h" - -class BloatedRendererTabHelperTest : public ChromeRenderViewHostTestHarness { - protected: - void SetUp() override { - ChromeRenderViewHostTestHarness::SetUp(); - BloatedRendererTabHelper::CreateForWebContents(web_contents()); - tab_helper_ = BloatedRendererTabHelper::FromWebContents(web_contents()); - web_contents_tester_ = content::WebContentsTester::For(web_contents()); - web_contents_tester_->SetLastCommittedURL(GURL("https://test.test")); - } - BloatedRendererTabHelper* tab_helper_; - content::WebContentsTester* web_contents_tester_; -}; - -TEST_F(BloatedRendererTabHelperTest, DetectReload) { - EXPECT_EQ(BloatedRendererTabHelper::State::kInactive, tab_helper_->state_); - tab_helper_->state_ = BloatedRendererTabHelper::State::kRequestingReload; - content::MockNavigationHandle reload_navigation; - tab_helper_->DidStartNavigation(&reload_navigation); - EXPECT_EQ(BloatedRendererTabHelper::State::kStartedNavigation, - tab_helper_->state_); - EXPECT_EQ(reload_navigation.GetNavigationId(), - tab_helper_->saved_navigation_id_); - tab_helper_->DidFinishNavigation(&reload_navigation); - EXPECT_EQ(BloatedRendererTabHelper::State::kInactive, tab_helper_->state_); -} - -TEST_F(BloatedRendererTabHelperTest, IgnoreUnrelatedNavigation) { - EXPECT_EQ(BloatedRendererTabHelper::State::kInactive, tab_helper_->state_); - tab_helper_->state_ = BloatedRendererTabHelper::State::kRequestingReload; - content::MockNavigationHandle reload_navigation; - tab_helper_->DidStartNavigation(&reload_navigation); - EXPECT_EQ(BloatedRendererTabHelper::State::kStartedNavigation, - tab_helper_->state_); - EXPECT_EQ(reload_navigation.GetNavigationId(), - tab_helper_->saved_navigation_id_); - content::MockNavigationHandle unrelated_navigation; - tab_helper_->DidFinishNavigation(&unrelated_navigation); - EXPECT_EQ(BloatedRendererTabHelper::State::kStartedNavigation, - tab_helper_->state_); - EXPECT_EQ(reload_navigation.GetNavigationId(), - tab_helper_->saved_navigation_id_); -} - -TEST_F(BloatedRendererTabHelperTest, CanReloadBloatedTab) { - web_contents_tester_->NavigateAndCommit(GURL("https://test.test")); - EXPECT_TRUE(tab_helper_->CanReloadBloatedTab()); -} - -TEST_F(BloatedRendererTabHelperTest, CannotReloadBloatedTabCrashed) { - web_contents()->SetIsCrashed(base::TERMINATION_STATUS_PROCESS_CRASHED, 0); - - EXPECT_FALSE(tab_helper_->CanReloadBloatedTab()); -} - -TEST_F(BloatedRendererTabHelperTest, CannotReloadBloatedTabInvalidURL) { - web_contents_tester_->SetLastCommittedURL(GURL("invalid :)")); - - EXPECT_FALSE(tab_helper_->CanReloadBloatedTab()); -} - -TEST_F(BloatedRendererTabHelperTest, CannotReloadBloatedTabWithPostData) { - web_contents_tester_->NavigateAndCommit(GURL("https://test.test")); - web_contents()->GetController().GetLastCommittedEntry()->SetHasPostData(true); - - EXPECT_FALSE(tab_helper_->CanReloadBloatedTab()); -} - -TEST_F(BloatedRendererTabHelperTest, - CannotReloadBloatedTabPendingUserInteraction) { - content::PageImportanceSignals signals; - signals.had_form_interaction = true; - web_contents_tester_->SetPageImportanceSignals(signals); - EXPECT_FALSE(tab_helper_->CanReloadBloatedTab()); -}
diff --git a/chrome/browser/ui/cocoa/applescript/OWNERS b/chrome/browser/ui/cocoa/applescript/OWNERS deleted file mode 100644 index a4e5ade2..0000000 --- a/chrome/browser/ui/cocoa/applescript/OWNERS +++ /dev/null
@@ -1,2 +0,0 @@ -pinkerton@chromium.org -spqchan@chromium.org \ No newline at end of file
diff --git a/chrome/browser/ui/global_error/global_error_browsertest.cc b/chrome/browser/ui/global_error/global_error_browsertest.cc index ff0b184..2eeb0f4 100644 --- a/chrome/browser/ui/global_error/global_error_browsertest.cc +++ b/chrome/browser/ui/global_error/global_error_browsertest.cc
@@ -26,6 +26,7 @@ #include "chrome/browser/ui/test/test_browser_dialog.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/pref_names.h" +#include "components/crx_file/crx_verifier.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/test/test_utils.h" @@ -34,6 +35,7 @@ #include "extensions/browser/extension_registry.h" #include "extensions/browser/extension_system.h" #include "extensions/browser/mock_external_provider.h" +#include "extensions/browser/sandboxed_unpacker.h" #include "extensions/common/extension_builder.h" #include "extensions/common/feature_switch.h" @@ -202,6 +204,8 @@ IN_PROC_BROWSER_TEST_F(GlobalErrorBubbleTest, InvokeUi_ExternalInstallBubbleAlert) { + extensions::SandboxedUnpacker::ScopedVerifierFormatOverrideForTest + verifier_format_override(crx_file::VerifierFormat::CRX3); extensions::FeatureSwitch::ScopedOverride prompt( extensions::FeatureSwitch::prompt_for_external_extensions(), true); ShowAndVerifyUi();
diff --git a/chrome/browser/ui/search/search_tab_helper.cc b/chrome/browser/ui/search/search_tab_helper.cc index 69de202..9c72ae4 100644 --- a/chrome/browser/ui/search/search_tab_helper.cc +++ b/chrome/browser/ui/search/search_tab_helper.cc
@@ -35,6 +35,7 @@ #include "components/omnibox/browser/omnibox_view.h" #include "components/search/search.h" #include "components/strings/grit/components_strings.h" +#include "components/sync/base/user_selectable_type.h" #include "components/sync/driver/sync_service.h" #include "components/sync/driver/sync_user_settings.h" #include "content/public/browser/navigation_details.h" @@ -100,7 +101,8 @@ bool IsHistorySyncEnabled(Profile* profile) { syncer::SyncService* sync = ProfileSyncServiceFactory::GetForProfile(profile); return sync && sync->IsSyncFeatureEnabled() && - sync->GetUserSettings()->GetChosenDataTypes().Has(syncer::TYPED_URLS); + sync->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kHistory); } } // namespace
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc index 2c49c6b4..5b70f7a 100644 --- a/chrome/browser/ui/tab_helpers.cc +++ b/chrome/browser/ui/tab_helpers.cc
@@ -59,7 +59,6 @@ #include "chrome/browser/tracing/navigation_tracing.h" #include "chrome/browser/translate/chrome_translate_client.h" #include "chrome/browser/ui/autofill/chrome_autofill_client.h" -#include "chrome/browser/ui/bloated_renderer/bloated_renderer_tab_helper.h" #include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h" #include "chrome/browser/ui/blocked_content/popup_opener_tab_helper.h" #include "chrome/browser/ui/find_bar/find_tab_helper.h" @@ -195,7 +194,6 @@ autofill::ChromeAutofillClient::FromWebContents(web_contents), g_browser_process->GetApplicationLocale(), autofill::AutofillManager::ENABLE_AUTOFILL_DOWNLOAD_MANAGER); - BloatedRendererTabHelper::CreateForWebContents(web_contents); chrome_browser_net::NetErrorTabHelper::CreateForWebContents(web_contents); ChromePasswordManagerClient::CreateForWebContentsWithAutofillClient( web_contents,
diff --git a/chrome/browser/ui/views/crostini/crostini_installer_view.cc b/chrome/browser/ui/views/crostini/crostini_installer_view.cc index 09076bc..d7888cb 100644 --- a/chrome/browser/ui/views/crostini/crostini_installer_view.cc +++ b/chrome/browser/ui/views/crostini/crostini_installer_view.cc
@@ -56,6 +56,10 @@ // The size of the download for the VM image. // TODO(timloh): This is just a placeholder. constexpr int kDownloadSizeInBytes = 300 * 1024 * 1024; +// The minimum feasible size for a VM disk image. +constexpr int64_t kMinimumDiskSize = 1ll * 1024 * 1024 * 1024; // 1 GiB +// Minimum amount of free disk space to install crostini successfully. +constexpr int kMinimumFreeDiskSpace = kDownloadSizeInBytes + kMinimumDiskSize; constexpr int kUninitializedDiskSpace = -1; @@ -133,7 +137,7 @@ true); base::PostTaskWithTraitsAndReplyWithResult( - FROM_HERE, {base::MayBlock()}, + FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE}, base::BindOnce(&base::SysInfo::AmountOfFreeDiskSpace, base::FilePath(kHomeDirectory)), base::BindOnce( @@ -143,6 +147,9 @@ void CrostiniInstallerView::OnAvailableDiskSpace(int64_t bytes) { free_disk_space_ = bytes; + if (free_disk_space_callback_for_testing_) { + std::move(free_disk_space_callback_for_testing_).Run(); + } } int CrostiniInstallerView::GetDialogButtons() const { @@ -183,11 +190,26 @@ return false; } +void CrostiniInstallerView::PressAccept() { + GetDialogClientView()->AcceptWindow(); +} + bool CrostiniInstallerView::Accept() { // This dialog can be accepted from State::ERROR. In that case, we're doing a // Retry. DCHECK(state_ == State::PROMPT || state_ == State::ERROR); + // Delay starting the install process until we can check if there's enough + // disk space. + if (free_disk_space_ == kUninitializedDiskSpace) { + base::PostDelayedTaskWithTraits( + FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(&CrostiniInstallerView::PressAccept, + weak_ptr_factory_.GetWeakPtr()), + base::TimeDelta::FromMilliseconds(50)); + return false; + } + UpdateState(State::INSTALL_START); profile_->GetPrefs()->SetBoolean(crostini::prefs::kCrostiniEnabled, true); install_start_time_ = base::TimeTicks::Now(); @@ -213,6 +235,19 @@ return false; // should not close the dialog. } + // Don't enforce minimum disk size on dev box or trybots because + // base::SysInfo::AmountOfFreeDiskSpace returns zero in testing. + if (free_disk_space_ < kMinimumFreeDiskSpace && + base::SysInfo::IsRunningOnChromeOS()) { + HandleError(l10n_util::GetStringFUTF16( + IDS_CROSTINI_INSTALLER_INSUFFICIENT_DISK, + ui::FormatBytesWithUnits(kMinimumFreeDiskSpace, + ui::DATA_UNITS_GIBIBYTE, + /*show_units=*/true)), + SetupResult::kErrorInsufficientDiskSpace); + return false; // should not close the dialog. + } + // Kick off the Crostini Restart sequence. We will be added as an observer. restart_id_ = crostini::CrostiniManager::GetForProfile(profile_)->RestartCrostini( @@ -447,6 +482,15 @@ progress_bar_callback_for_testing_ = callback; } +void CrostiniInstallerView::SetGetFreeDiskSpaceCallbackForTesting( + base::OnceClosure quit_closure) { + if (free_disk_space_ == kUninitializedDiskSpace) { + free_disk_space_callback_for_testing_ = std::move(quit_closure); + } else { + std::move(free_disk_space_callback_for_testing_).Run(); + } +} + CrostiniInstallerView::CrostiniInstallerView(Profile* profile) : profile_(profile), free_disk_space_(kUninitializedDiskSpace),
diff --git a/chrome/browser/ui/views/crostini/crostini_installer_view.h b/chrome/browser/ui/views/crostini/crostini_installer_view.h index f208a5e4..0c4e107 100644 --- a/chrome/browser/ui/views/crostini/crostini_installer_view.h +++ b/chrome/browser/ui/views/crostini/crostini_installer_view.h
@@ -52,6 +52,7 @@ kErrorFetchingSshKeys = 9, kErrorMountingContainer = 10, kErrorSettingUpContainer = 11, + kErrorInsufficientDiskSpace = 22, kUserCancelledStart = 12, kUserCancelledInstallImageLoader = 13, @@ -99,6 +100,7 @@ void SetCloseCallbackForTesting(base::OnceClosure quit_closure); void SetProgressBarCallbackForTesting( base::RepeatingCallback<void(double)> callback); + void SetGetFreeDiskSpaceCallbackForTesting(base::OnceClosure quit_closure); private: enum class State { @@ -137,6 +139,8 @@ void OnAvailableDiskSpace(int64_t bytes); + void PressAccept(); + State state_ = State::PROMPT; views::ImageView* logo_image_ = nullptr; views::Label* big_message_label_ = nullptr; @@ -166,6 +170,7 @@ base::RepeatingCallback<void(double)> progress_bar_callback_for_testing_; base::OnceClosure quit_closure_for_testing_; + base::OnceClosure free_disk_space_callback_for_testing_; base::WeakPtrFactory<CrostiniInstallerView> weak_ptr_factory_;
diff --git a/chrome/browser/ui/views/crostini/crostini_installer_view_browsertest.cc b/chrome/browser/ui/views/crostini/crostini_installer_view_browsertest.cc index ff43690..ea570262 100644 --- a/chrome/browser/ui/views/crostini/crostini_installer_view_browsertest.cc +++ b/chrome/browser/ui/views/crostini/crostini_installer_view_browsertest.cc
@@ -165,6 +165,10 @@ EXPECT_TRUE(crostini::CrostiniManager::GetForProfile(browser()->profile()) ->GetInstallerViewStatus()); + base::RunLoop run_loop; + ActiveView()->SetGetFreeDiskSpaceCallbackForTesting(run_loop.QuitClosure()); + run_loop.Run(); + ActiveView()->GetDialogClientView()->AcceptWindow(); EXPECT_FALSE(ActiveView()->GetWidget()->IsClosed()); EXPECT_FALSE(HasAcceptButton()); @@ -220,6 +224,10 @@ EXPECT_TRUE(crostini::CrostiniManager::GetForProfile(browser()->profile()) ->GetInstallerViewStatus()); + base::RunLoop run_loop; + ActiveView()->SetGetFreeDiskSpaceCallbackForTesting(run_loop.QuitClosure()); + run_loop.Run(); + ActiveView()->GetDialogClientView()->AcceptWindow(); EXPECT_FALSE(ActiveView()->GetWidget()->IsClosed()); EXPECT_TRUE(HasAcceptButton()); @@ -273,6 +281,10 @@ response.set_status(vm_tools::concierge::VM_STATUS_FAILURE); waiting_fake_concierge_client_->set_start_vm_response(std::move(response)); + base::RunLoop run_loop; + ActiveView()->SetGetFreeDiskSpaceCallbackForTesting(run_loop.QuitClosure()); + run_loop.Run(); + ActiveView()->GetDialogClientView()->AcceptWindow(); EXPECT_FALSE(ActiveView()->GetWidget()->IsClosed()); waiting_fake_concierge_client_->WaitForStartTerminaVmCalled();
diff --git a/chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view.cc b/chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view.cc index 4e1e2eb..d9c884f 100644 --- a/chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view.cc +++ b/chrome/browser/ui/views/plugin_vm/plugin_vm_launcher_view.cc
@@ -418,20 +418,19 @@ base::Optional<double> fraction_complete = GetFractionComplete(bytes_downloaded, content_length); - base::string16 bytes_downloaded_str = - ui::FormatBytesWithUnits(bytes_downloaded, ui::DATA_UNITS_GIBIBYTE, - /*show_units=*/true); - // If download size isn't known |fraction_complete| should be empty. if (fraction_complete.has_value()) { return l10n_util::GetStringFUTF16( - IDS_PLUGIN_VM_LAUNCHER_DOWNLOAD_PROGRESS_MESSAGE, bytes_downloaded_str, + IDS_PLUGIN_VM_LAUNCHER_DOWNLOAD_PROGRESS_MESSAGE, + ui::FormatBytesWithUnits(bytes_downloaded, ui::DATA_UNITS_GIBIBYTE, + /*show_units=*/false), ui::FormatBytesWithUnits(content_length, ui::DATA_UNITS_GIBIBYTE, /*show_units=*/true)); } else { return l10n_util::GetStringFUTF16( IDS_PLUGIN_VM_LAUNCHER_DOWNLOAD_PROGRESS_WITHOUT_DOWNLOAD_SIZE_MESSAGE, - bytes_downloaded_str); + ui::FormatBytesWithUnits(bytes_downloaded, ui::DATA_UNITS_GIBIBYTE, + /*show_units=*/true)); } }
diff --git a/chrome/browser/ui/web_applications/web_app_ui_delegate_impl.cc b/chrome/browser/ui/web_applications/web_app_ui_delegate_impl.cc index 2a31b94..a9fbcf1 100644 --- a/chrome/browser/ui/web_applications/web_app_ui_delegate_impl.cc +++ b/chrome/browser/ui/web_applications/web_app_ui_delegate_impl.cc
@@ -4,6 +4,9 @@ #include "chrome/browser/ui/web_applications/web_app_ui_delegate_impl.h" +#include <utility> + +#include "base/callback.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/web_app_browser_controller.h" @@ -19,6 +22,15 @@ WebAppUiDelegateImpl::WebAppUiDelegateImpl(Profile* profile) : profile_(profile) { + for (Browser* browser : *BrowserList::GetInstance()) { + base::Optional<AppId> app_id = GetAppIdForBrowser(browser); + if (!app_id.has_value()) + continue; + + ++num_windows_for_apps_map_[app_id.value()]; + } + + BrowserList::AddObserver(this); WebAppProvider::Get(profile_)->set_ui_delegate(this); } @@ -26,22 +38,71 @@ void WebAppUiDelegateImpl::Shutdown() { WebAppProvider::Get(profile_)->set_ui_delegate(nullptr); + BrowserList::RemoveObserver(this); } size_t WebAppUiDelegateImpl::GetNumWindowsForApp(const AppId& app_id) { - size_t num_windows_for_app = 0; - for (Browser* browser : *BrowserList::GetInstance()) { - if (browser->profile() != profile_) - continue; + auto it = num_windows_for_apps_map_.find(app_id); + if (it == num_windows_for_apps_map_.end()) + return 0; - if (!browser->web_app_controller()) - continue; + return it->second; +} - if (browser->web_app_controller()->GetAppId() == app_id) - ++num_windows_for_app; +void WebAppUiDelegateImpl::NotifyOnAllAppWindowsClosed( + const AppId& app_id, + base::OnceClosure callback) { + const size_t num_windows_for_app = GetNumWindowsForApp(app_id); + if (num_windows_for_app == 0) { + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + std::move(callback)); + return; } - return num_windows_for_app; + windows_closed_requests_map_[app_id].push_back(std::move(callback)); +} + +void WebAppUiDelegateImpl::OnBrowserAdded(Browser* browser) { + base::Optional<AppId> app_id = GetAppIdForBrowser(browser); + if (!app_id.has_value()) + return; + + ++num_windows_for_apps_map_[app_id.value()]; +} + +void WebAppUiDelegateImpl::OnBrowserRemoved(Browser* browser) { + base::Optional<AppId> app_id_opt = GetAppIdForBrowser(browser); + if (!app_id_opt.has_value()) + return; + + const auto& app_id = app_id_opt.value(); + + size_t& num_windows_for_app = num_windows_for_apps_map_[app_id]; + DCHECK_GT(num_windows_for_app, 0u); + --num_windows_for_app; + + if (num_windows_for_app > 0) + return; + + auto it = windows_closed_requests_map_.find(app_id); + if (it == windows_closed_requests_map_.end()) + return; + + for (auto& callback : it->second) + std::move(callback).Run(); + + windows_closed_requests_map_.erase(app_id); +} + +base::Optional<AppId> WebAppUiDelegateImpl::GetAppIdForBrowser( + Browser* browser) { + if (browser->profile() != profile_) + return base::nullopt; + + if (!browser->web_app_controller()) + return base::nullopt; + + return browser->web_app_controller()->GetAppId(); } } // namespace web_app
diff --git a/chrome/browser/ui/web_applications/web_app_ui_delegate_impl.h b/chrome/browser/ui/web_applications/web_app_ui_delegate_impl.h index a2c8547..7987502 100644 --- a/chrome/browser/ui/web_applications/web_app_ui_delegate_impl.h +++ b/chrome/browser/ui/web_applications/web_app_ui_delegate_impl.h
@@ -5,15 +5,24 @@ #ifndef CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_UI_DELEGATE_IMPL_H_ #define CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_UI_DELEGATE_IMPL_H_ +#include <map> +#include <vector> + +#include "base/callback_forward.h" #include "base/macros.h" +#include "base/optional.h" +#include "chrome/browser/ui/browser_list_observer.h" #include "chrome/browser/web_applications/components/web_app_ui_delegate.h" #include "components/keyed_service/core/keyed_service.h" class Profile; +class Browser; namespace web_app { -class WebAppUiDelegateImpl : public KeyedService, public WebAppUiDelegate { +class WebAppUiDelegateImpl : public KeyedService, + public BrowserListObserver, + public WebAppUiDelegate { public: static WebAppUiDelegateImpl* Get(Profile* profile); @@ -25,10 +34,21 @@ // WebAppUiDelegate size_t GetNumWindowsForApp(const AppId& app_id) override; + void NotifyOnAllAppWindowsClosed(const AppId& app_id, + base::OnceClosure callback) override; + + // BrowserListObserver + void OnBrowserAdded(Browser* browser) override; + void OnBrowserRemoved(Browser* browser) override; private: + base::Optional<AppId> GetAppIdForBrowser(Browser* browser); + Profile* profile_; + std::map<AppId, std::vector<base::OnceClosure>> windows_closed_requests_map_; + std::map<AppId, size_t> num_windows_for_apps_map_; + DISALLOW_COPY_AND_ASSIGN(WebAppUiDelegateImpl); };
diff --git a/chrome/browser/ui/web_applications/web_app_ui_delegate_impl_browsertest.cc b/chrome/browser/ui/web_applications/web_app_ui_delegate_impl_browsertest.cc index 1d3bd08..9e86c16 100644 --- a/chrome/browser/ui/web_applications/web_app_ui_delegate_impl_browsertest.cc +++ b/chrome/browser/ui/web_applications/web_app_ui_delegate_impl_browsertest.cc
@@ -2,17 +2,89 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/web_applications/web_app_ui_delegate_impl.h" -#include "chrome/browser/web_applications/web_app.h" + +#include "base/barrier_closure.h" +#include "base/test/bind_test_util.h" +#include "base/threading/thread_task_runner_handle.h" +#include "chrome/browser/extensions/browsertest_util.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/browser_list_observer.h" +#include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/web_applications/components/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_provider.h" +#include "chrome/common/web_application_info.h" #include "chrome/test/base/in_process_browser_test.h" +#include "extensions/common/extension.h" +#include "url/gurl.h" namespace web_app { -using WebAppUiDelegateImplBrowsertest = InProcessBrowserTest; +namespace { -IN_PROC_BROWSER_TEST_F(WebAppUiDelegateImplBrowsertest, NoAppWindows) { +// Waits for |browser| to be removed from BrowserList and then calls |callback|. +class BrowserRemovedWaiter final : public BrowserListObserver { + public: + explicit BrowserRemovedWaiter(Browser* browser) : browser_(browser) {} + ~BrowserRemovedWaiter() override = default; + + void Wait() { + BrowserList::AddObserver(this); + run_loop_.Run(); + } + + // BrowserListObserver + void OnBrowserRemoved(Browser* browser) override { + if (browser != browser_) + return; + + BrowserList::RemoveObserver(this); + // Post a task to ensure the Remove event has been dispatched to all + // observers. + base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, + run_loop_.QuitClosure()); + } + + private: + Browser* browser_; + base::RunLoop run_loop_; +}; + +void CloseAndWait(Browser* browser) { + BrowserRemovedWaiter waiter(browser); + browser->window()->Close(); + waiter.Wait(); +} + +} // namespace + +const GURL kFooUrl = GURL("https://foo.example"); +const GURL kBarUrl = GURL("https://bar.example"); + +class WebAppUiDelegateImplBrowserTest : public InProcessBrowserTest { + protected: + Profile* profile() { return browser()->profile(); } + + const extensions::Extension* InstallWebApp(const GURL& app_url) { + WebApplicationInfo web_app_info; + web_app_info.app_url = app_url; + web_app_info.open_as_window = true; + return extensions::browsertest_util::InstallBookmarkApp(profile(), + web_app_info); + } + + Browser* LaunchApp(const extensions::Extension* app) { + return extensions::browsertest_util::LaunchAppBrowser(profile(), app); + } + + WebAppUiDelegateImpl* ui_delegate() { + return WebAppUiDelegateImpl::Get(profile()); + } +}; + +IN_PROC_BROWSER_TEST_F(WebAppUiDelegateImplBrowserTest, + GetNumWindowsForApp_AppWindowsAdded) { // Should not crash. auto& delegate = WebAppProvider::Get(browser()->profile())->ui_delegate(); auto* delegate_impl = WebAppUiDelegateImpl::Get(browser()->profile()); @@ -20,6 +92,146 @@ // Zero apps on start: EXPECT_EQ(0u, delegate.GetNumWindowsForApp(AppId())); + + const auto* foo_app = InstallWebApp(kFooUrl); + LaunchApp(foo_app); + + EXPECT_EQ(1u, delegate.GetNumWindowsForApp(foo_app->id())); +} + +IN_PROC_BROWSER_TEST_F(WebAppUiDelegateImplBrowserTest, + GetNumWindowsForApp_AppWindowsRemoved) { + const auto* foo_app = InstallWebApp(kFooUrl); + auto* foo_window1 = LaunchApp(foo_app); + auto* foo_window2 = LaunchApp(foo_app); + + const auto* bar_app = InstallWebApp(kBarUrl); + LaunchApp(bar_app); + + // Wait for the browser windows to be fully opened, otherwise we'll crash when + // closing them. + // TODO(ortuno): Investigate removing this. + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(2u, ui_delegate()->GetNumWindowsForApp(foo_app->id())); + EXPECT_EQ(1u, ui_delegate()->GetNumWindowsForApp(bar_app->id())); + + CloseAndWait(foo_window1); + + EXPECT_EQ(1u, ui_delegate()->GetNumWindowsForApp(foo_app->id())); + EXPECT_EQ(1u, ui_delegate()->GetNumWindowsForApp(bar_app->id())); + + CloseAndWait(foo_window2); + + EXPECT_EQ(0u, ui_delegate()->GetNumWindowsForApp(foo_app->id())); + EXPECT_EQ(1u, ui_delegate()->GetNumWindowsForApp(bar_app->id())); +} + +IN_PROC_BROWSER_TEST_F(WebAppUiDelegateImplBrowserTest, + NotifyOnAllAppWindowsClosed_NoOpenedWindows) { + const auto* foo_app = InstallWebApp(kFooUrl); + const auto* bar_app = InstallWebApp(kBarUrl); + LaunchApp(bar_app); + + // Wait for the browser windows to be fully opened, otherwise we'll crash when + // closing them. + // TODO(ortuno): Investigate removing this. + base::RunLoop().RunUntilIdle(); + + base::RunLoop run_loop; + // Should return early; no windows for |foo_app|. + ui_delegate()->NotifyOnAllAppWindowsClosed(foo_app->id(), + run_loop.QuitClosure()); + run_loop.Run(); +} + +// Tests that the callback is correctly called when there is more than one +// app window. +IN_PROC_BROWSER_TEST_F(WebAppUiDelegateImplBrowserTest, + NotifyOnAllAppWindowsClosed_MultipleOpenedWindows) { + const auto* foo_app = InstallWebApp(kFooUrl); + const auto* bar_app = InstallWebApp(kBarUrl); + + // Test that NotifyOnAllAppWindowsClosed can be called more than once for + // the same app. + for (int i = 0; i < 2; i++) { + auto* foo_window1 = LaunchApp(foo_app); + auto* foo_window2 = LaunchApp(foo_app); + auto* bar_window = LaunchApp(bar_app); + + // Wait for the browser windows to be fully opened, otherwise we'll crash + // when closing them. + // TODO(ortuno): Investigate removing this. + base::RunLoop().RunUntilIdle(); + + bool callback_ran = false; + base::RunLoop run_loop; + ui_delegate()->NotifyOnAllAppWindowsClosed( + foo_app->id(), base::BindLambdaForTesting([&]() { + callback_ran = true; + run_loop.Quit(); + })); + + CloseAndWait(foo_window1); + // The callback shouldn't have run yet because there is still one window + // opened. + EXPECT_FALSE(callback_ran); + + CloseAndWait(bar_window); + EXPECT_FALSE(callback_ran); + + CloseAndWait(foo_window2); + run_loop.Run(); + EXPECT_TRUE(callback_ran); + } +} + +// Tests that callbacks are correctly called when there is more than one +// request. +IN_PROC_BROWSER_TEST_F(WebAppUiDelegateImplBrowserTest, + NotifyOnAllAppWindowsClosed_MultipleRequests) { + const auto* foo_app = InstallWebApp(kFooUrl); + const auto* bar_app = InstallWebApp(kBarUrl); + + auto* foo_window1 = LaunchApp(foo_app); + auto* foo_window2 = LaunchApp(foo_app); + auto* bar_window = LaunchApp(bar_app); + + // Wait for the browser windows to be fully opened, otherwise we'll crash when + // closing them. + // TODO(ortuno): Investigate removing this. + base::RunLoop().RunUntilIdle(); + + bool callback_ran1 = false; + bool callback_ran2 = false; + + base::RunLoop run_loop; + auto barrier_closure = base::BarrierClosure(2, run_loop.QuitClosure()); + ui_delegate()->NotifyOnAllAppWindowsClosed(foo_app->id(), + base::BindLambdaForTesting([&]() { + callback_ran1 = true; + barrier_closure.Run(); + })); + ui_delegate()->NotifyOnAllAppWindowsClosed(foo_app->id(), + base::BindLambdaForTesting([&]() { + callback_ran2 = true; + barrier_closure.Run(); + })); + + CloseAndWait(foo_window1); + // The callback shouldn't have run yet because there is still one window + // opened. + EXPECT_FALSE(callback_ran1); + EXPECT_FALSE(callback_ran2); + + CloseAndWait(bar_window); + EXPECT_FALSE(callback_ran1); + EXPECT_FALSE(callback_ran2); + + CloseAndWait(foo_window2); + run_loop.Run(); + EXPECT_TRUE(callback_ran1); + EXPECT_TRUE(callback_ran2); } } // namespace web_app
diff --git a/chrome/browser/ui/webui/management_ui.cc b/chrome/browser/ui/webui/management_ui.cc index 3faffd3d4..14e182d 100644 --- a/chrome/browser/ui/webui/management_ui.cc +++ b/chrome/browser/ui/webui/management_ui.cc
@@ -97,6 +97,8 @@ #if defined(OS_CHROMEOS) source->AddString("managementDeviceLearnMoreUrl", chrome::kLearnMoreEnterpriseURL); + source->AddString("managementAccountLearnMoreUrl", + chrome::kManagedUiLearnMoreUrl); #endif // defined(OS_CHROMEOS) source->SetJsonPath("strings.js"); @@ -128,19 +130,21 @@ policy::BrowserPolicyConnectorChromeOS* connector = g_browser_process->platform_part()->browser_policy_connector_chromeos(); const auto device_type = ui::GetChromeOSDeviceTypeResourceId(); - if (!connector->IsEnterpriseManaged()) { + if (!connector->IsEnterpriseManaged() && + !policy::ProfilePolicyConnectorFactory::IsProfileManaged(profile)) { return l10n_util::GetStringFUTF16(IDS_MANAGEMENT_NOT_MANAGED_SUBTITLE, l10n_util::GetStringUTF16(device_type)); } std::string display_domain = connector->GetEnterpriseDisplayDomain(); - if (display_domain.empty()) { - if (!connector->IsActiveDirectoryManaged()) { - return l10n_util::GetStringFUTF16(IDS_MANAGEMENT_SUBTITLE_MANAGED, - l10n_util::GetStringUTF16(device_type)); - } + if (display_domain.empty()) display_domain = connector->GetRealm(); + if (display_domain.empty()) + display_domain = ManagementUIHandler::GetAccountDomain(profile); + if (display_domain.empty()) { + return l10n_util::GetStringFUTF16(IDS_MANAGEMENT_SUBTITLE_MANAGED, + l10n_util::GetStringUTF16(device_type)); } return l10n_util::GetStringFUTF16(IDS_MANAGEMENT_SUBTITLE_MANAGED_BY, l10n_util::GetStringUTF16(device_type),
diff --git a/chrome/browser/ui/webui/management_ui_handler.cc b/chrome/browser/ui/webui/management_ui_handler.cc index 34b12d5..9082306 100644 --- a/chrome/browser/ui/webui/management_ui_handler.cc +++ b/chrome/browser/ui/webui/management_ui_handler.cc
@@ -131,6 +131,14 @@ return policy::ProfilePolicyConnectorFactory::IsProfileManaged(profile); } +#if defined(OS_CHROMEOS) +bool IsDeviceManaged() { + policy::BrowserPolicyConnectorChromeOS* connector = + g_browser_process->platform_part()->browser_policy_connector_chromeos(); + return connector->IsEnterpriseManaged(); +} +#endif // defined(OS_CHROMEOS) + #if !defined(OS_CHROMEOS) bool IsBrowserManaged() { return g_browser_process->browser_policy_connector() @@ -336,7 +344,7 @@ auto handler = std::make_unique<ManagementUIHandler>(); #if defined(OS_CHROMEOS) - handler->managed_ = IsProfileManaged(profile); + handler->managed_ = IsProfileManaged(profile) || IsDeviceManaged(); #else handler->managed_ = IsProfileManaged(profile) || IsBrowserManaged(); #endif // defined(OS_CHROMEOS) @@ -478,7 +486,18 @@ base::DictionaryValue ManagementUIHandler::GetContextualManagedData( Profile* profile) const { base::DictionaryValue response; - auto management_domain = GetAccountDomain(profile); + +#if defined(OS_CHROMEOS) + policy::BrowserPolicyConnectorChromeOS* connector = + g_browser_process->platform_part()->browser_policy_connector_chromeos(); + std::string management_domain = connector->GetEnterpriseDisplayDomain(); + if (management_domain.empty()) + management_domain = connector->GetRealm(); + if (management_domain.empty()) + management_domain = GetAccountDomain(profile); +#else + std::string management_domain = GetAccountDomain(profile); +#endif if (management_domain.empty()) { response.SetString( @@ -497,12 +516,13 @@ : IDS_MANAGEMENT_NOT_MANAGED_SUBTITLE)); #else const auto device_type = ui::GetChromeOSDeviceTypeResourceId(); - response.SetString( - "pageSubtitle", - managed_ - ? l10n_util::GetStringFUTF16(IDS_MANAGEMENT_SUBTITLE_MANAGED, - l10n_util::GetStringUTF16(device_type)) - : l10n_util::GetStringUTF16(IDS_MANAGEMENT_NOT_MANAGED_SUBTITLE)); + response.SetString("pageSubtitle", + managed_ ? l10n_util::GetStringFUTF16( + IDS_MANAGEMENT_SUBTITLE_MANAGED, + l10n_util::GetStringUTF16(device_type)) + : l10n_util::GetStringFUTF16( + IDS_MANAGEMENT_NOT_MANAGED_SUBTITLE, + l10n_util::GetStringUTF16(device_type))); #endif // !defined(OS_CHROMEOS) } else { @@ -529,13 +549,14 @@ : l10n_util::GetStringUTF16(IDS_MANAGEMENT_NOT_MANAGED_SUBTITLE)); #else const auto device_type = ui::GetChromeOSDeviceTypeResourceId(); - response.SetString( - "pageSubtitle", - managed_ - ? l10n_util::GetStringFUTF16(IDS_MANAGEMENT_SUBTITLE_MANAGED_BY, - l10n_util::GetStringUTF16(device_type), - base::UTF8ToUTF16(management_domain)) - : l10n_util::GetStringUTF16(IDS_MANAGEMENT_NOT_MANAGED_SUBTITLE)); + response.SetString("pageSubtitle", + managed_ ? l10n_util::GetStringFUTF16( + IDS_MANAGEMENT_SUBTITLE_MANAGED_BY, + l10n_util::GetStringUTF16(device_type), + base::UTF8ToUTF16(management_domain)) + : l10n_util::GetStringFUTF16( + IDS_MANAGEMENT_NOT_MANAGED_SUBTITLE, + l10n_util::GetStringUTF16(device_type))); #endif // !defined(OS_CHROMEOS) } GetManagementStatus(profile, &response); @@ -617,7 +638,7 @@ base::UTF8ToUTF16(device_domain), base::UTF8ToUTF16(account_domain)))); AddStatusDeviceManagedInfo(status, device_domain); - status->SetKey(kAccountManagedInfo, base::Value()); + AddStatusAccountManagedInfo(status, account_domain); } void AddStatusOverviewManagedDeviceAndAccount( @@ -818,7 +839,7 @@ void ManagementUIHandler::OnManagedStateChanged() { auto* profile = Profile::FromWebUI(web_ui()); #if defined(OS_CHROMEOS) - bool managed = IsProfileManaged(profile); + bool managed = IsProfileManaged(profile) || IsDeviceManaged(); #else bool managed = IsProfileManaged(profile) || IsBrowserManaged(); #endif // defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/webui/management_ui_handler_unittest.cc b/chrome/browser/ui/webui/management_ui_handler_unittest.cc index 8ff791f..3239e151 100644 --- a/chrome/browser/ui/webui/management_ui_handler_unittest.cc +++ b/chrome/browser/ui/webui/management_ui_handler_unittest.cc
@@ -24,6 +24,10 @@ #include "ui/base/l10n/l10n_util.h" +#if defined(OS_CHROMEOS) +#include "ui/chromeos/devicetype_utils.h" +#endif // defined(OS_CHROMEOS) + using testing::_; using testing::Return; using testing::ReturnRef; @@ -349,6 +353,63 @@ #endif // !defined(OS_CHROMEOS) +#if defined(OS_CHROMEOS) +TEST_F(ManagementUIHandlerTests, + ManagementContextualSourceUpdateManagedAccountKnownDomain) { + TestingProfile::Builder builder; + builder.SetProfileName("managed@manager.com"); + auto profile = builder.Build(); + const auto device_type = ui::GetChromeOSDeviceTypeResourceId(); + + base::string16 extensions_installed; + base::string16 browser_management_notice; + base::string16 subtitle; + base::string16 management_overview; + base::string16 management_overview_data_notice; + base::string16 management_overview_setup_notice; + ContextualManagementSourceUpdate extracted{&extensions_installed, + &browser_management_notice, + &subtitle, + &management_overview, + &management_overview_data_notice, + &management_overview_setup_notice}; + + handler_.SetManagedForTesting(true); + auto data = handler_.GetContextualManagedDataForTesting(profile.get()); + ExtractContextualSourceUpdate(data, extracted); + + EXPECT_EQ(subtitle, + l10n_util::GetStringFUTF16(IDS_MANAGEMENT_SUBTITLE_MANAGED_BY, + l10n_util::GetStringUTF16(device_type), + base::UTF8ToUTF16("manager.com"))); +} + +TEST_F(ManagementUIHandlerTests, ManagementContextualSourceUpdateUnmanaged) { + auto profile = TestingProfile::Builder().Build(); + const auto device_type = ui::GetChromeOSDeviceTypeResourceId(); + + base::string16 extension_reporting_title; + base::string16 browser_management_notice; + base::string16 subtitle; + base::string16 management_overview; + base::string16 management_overview_data_notice; + base::string16 management_overview_setup_notice; + ContextualManagementSourceUpdate extracted{&extension_reporting_title, + &browser_management_notice, + &subtitle, + &management_overview, + &management_overview_data_notice, + &management_overview_setup_notice}; + + handler_.SetManagedForTesting(false); + auto data = handler_.GetContextualManagedDataForTesting(profile.get()); + ExtractContextualSourceUpdate(data, extracted); + EXPECT_EQ(subtitle, + l10n_util::GetStringFUTF16(IDS_MANAGEMENT_NOT_MANAGED_SUBTITLE, + l10n_util::GetStringUTF16(device_type))); +} +#endif + TEST_F(ManagementUIHandlerTests, ExtensionReportingInfoNoPolicySetNoMessage) { handler_.EnableCloudReportingExtension(false); auto reporting_info = handler_.GetExtensionReportingInfo();
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc index a28457b..4eada935 100644 --- a/chrome/browser/ui/webui/settings/people_handler.cc +++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -42,6 +42,7 @@ #include "components/signin/core/browser/signin_pref_names.h" #include "components/strings/grit/components_strings.h" #include "components/sync/base/passphrase_enums.h" +#include "components/sync/base/user_selectable_type.h" #include "components/sync/driver/sync_service.h" #include "components/sync/driver/sync_service_utils.h" #include "components/sync/driver/sync_user_settings.h" @@ -84,7 +85,7 @@ bool encrypt_all; bool sync_everything; - syncer::ModelTypeSet data_types; + syncer::UserSelectableTypeSet selected_types; bool payments_integration_enabled; std::string passphrase; bool set_new_passphrase; @@ -119,18 +120,16 @@ return false; } - syncer::ModelTypeNameMap type_names = syncer::GetUserSelectableTypeNameMap(); - - for (syncer::ModelTypeNameMap::const_iterator it = type_names.begin(); - it != type_names.end(); ++it) { - std::string key_name = it->second + std::string("Synced"); + for (syncer::UserSelectableType type : syncer::UserSelectableTypeSet::All()) { + std::string key_name = + syncer::GetUserSelectableTypeName(type) + std::string("Synced"); bool sync_value; if (!result->GetBoolean(key_name, &sync_value)) { DLOG(ERROR) << "GetConfiguration() not passed a value for " << key_name; return false; } if (sync_value) - config->data_types.Put(it->first); + config->selected_types.Put(type); } // Encryption settings. @@ -497,8 +496,8 @@ return; } - service->GetUserSettings()->SetChosenDataTypes(configuration.sync_everything, - configuration.data_types); + service->GetUserSettings()->SetSelectedTypes(configuration.sync_everything, + configuration.selected_types); // Choosing data types to sync never fails. ResolveJavascriptCallback(*callback_id, base::Value(kConfigurePageStatus)); @@ -1065,41 +1064,41 @@ // base::DictionaryValue args; + syncer::SyncUserSettings* sync_user_settings = service->GetUserSettings(); // Tell the UI layer which data types are registered/enabled by the user. - const syncer::ModelTypeSet registered_types = - service->GetRegisteredDataTypes(); - const syncer::ModelTypeSet preferred_types = service->GetPreferredDataTypes(); - const syncer::ModelTypeSet enforced_types = service->GetForcedDataTypes(); - syncer::ModelTypeNameMap type_names = syncer::GetUserSelectableTypeNameMap(); - for (syncer::ModelTypeNameMap::const_iterator it = type_names.begin(); - it != type_names.end(); ++it) { - syncer::ModelType sync_type = it->first; - const std::string key_name = it->second; - args.SetBoolean(key_name + "Registered", registered_types.Has(sync_type)); - args.SetBoolean(key_name + "Synced", preferred_types.Has(sync_type)); - args.SetBoolean(key_name + "Enforced", enforced_types.Has(sync_type)); + const syncer::UserSelectableTypeSet registered_types = + sync_user_settings->GetRegisteredSelectableTypes(); + const syncer::UserSelectableTypeSet selected_types = + sync_user_settings->GetSelectedTypes(); + const syncer::UserSelectableTypeSet enforced_types = + sync_user_settings->GetForcedTypes(); + for (syncer::UserSelectableType type : syncer::UserSelectableTypeSet::All()) { + const std::string type_name = syncer::GetUserSelectableTypeName(type); + args.SetBoolean(type_name + "Registered", registered_types.Has(type)); + args.SetBoolean(type_name + "Synced", selected_types.Has(type)); + args.SetBoolean(type_name + "Enforced", enforced_types.Has(type)); } args.SetBoolean("syncAllDataTypes", - service->GetUserSettings()->IsSyncEverythingEnabled()); + sync_user_settings->IsSyncEverythingEnabled()); args.SetBoolean( "paymentsIntegrationEnabled", autofill::prefs::IsPaymentsIntegrationEnabled(profile_->GetPrefs())); args.SetBoolean("encryptAllData", - service->GetUserSettings()->IsEncryptEverythingEnabled()); + sync_user_settings->IsEncryptEverythingEnabled()); args.SetBoolean("encryptAllDataAllowed", - service->GetUserSettings()->IsEncryptEverythingAllowed()); + sync_user_settings->IsEncryptEverythingAllowed()); // We call IsPassphraseRequired() here, instead of calling // IsPassphraseRequiredForDecryption(), because we want to show the passphrase // UI even if no encrypted data types are enabled. args.SetBoolean("passphraseRequired", - service->GetUserSettings()->IsPassphraseRequired()); + sync_user_settings->IsPassphraseRequired()); syncer::PassphraseType passphrase_type = - service->GetUserSettings()->GetPassphraseType(); + sync_user_settings->GetPassphraseType(); if (syncer::IsExplicitPassphrase(passphrase_type)) { base::Time passphrase_time = - service->GetUserSettings()->GetExplicitPassphraseTime(); + sync_user_settings->GetExplicitPassphraseTime(); args.SetString("enterPassphraseBody", GetEnterPassphraseBody(passphrase_type, passphrase_time)); args.SetString("fullEncryptionBody",
diff --git a/chrome/browser/ui/webui/settings/people_handler_unittest.cc b/chrome/browser/ui/webui/settings/people_handler_unittest.cc index 1005b55f..a14675b46 100644 --- a/chrome/browser/ui/webui/settings/people_handler_unittest.cc +++ b/chrome/browser/ui/webui/settings/people_handler_unittest.cc
@@ -59,16 +59,16 @@ namespace { -MATCHER_P(ModelTypeSetMatches, value, "") { +MATCHER_P(UserSelectableTypeSetMatches, value, "") { return arg == value; } const char kTestUser[] = "chrome.p13n.test@gmail.com"; const char kTestCallbackId[] = "test-callback-id"; -// Returns a ModelTypeSet with all user selectable types set. -syncer::ModelTypeSet GetAllTypes() { - return syncer::UserSelectableTypes(); +// Returns a UserSelectableTypeSet with all types set. +syncer::UserSelectableTypeSet GetAllTypes() { + return syncer::UserSelectableTypeSet::All(); } enum SyncAllDataConfig { @@ -86,7 +86,7 @@ // the passed dictionary are added to the json. std::string GetConfiguration(const base::DictionaryValue* extra_values, SyncAllDataConfig sync_all, - syncer::ModelTypeSet types, + syncer::UserSelectableTypeSet types, const std::string& passphrase, EncryptAllConfig encrypt_all) { base::DictionaryValue result; @@ -97,15 +97,22 @@ if (!passphrase.empty()) result.SetString("passphrase", passphrase); // Add all of our data types. - result.SetBoolean("appsSynced", types.Has(syncer::APPS)); - result.SetBoolean("autofillSynced", types.Has(syncer::AUTOFILL)); - result.SetBoolean("bookmarksSynced", types.Has(syncer::BOOKMARKS)); - result.SetBoolean("extensionsSynced", types.Has(syncer::EXTENSIONS)); - result.SetBoolean("passwordsSynced", types.Has(syncer::PASSWORDS)); - result.SetBoolean("preferencesSynced", types.Has(syncer::PREFERENCES)); - result.SetBoolean("tabsSynced", types.Has(syncer::PROXY_TABS)); - result.SetBoolean("themesSynced", types.Has(syncer::THEMES)); - result.SetBoolean("typedUrlsSynced", types.Has(syncer::TYPED_URLS)); + result.SetBoolean("appsSynced", types.Has(syncer::UserSelectableType::kApps)); + result.SetBoolean("autofillSynced", + types.Has(syncer::UserSelectableType::kAutofill)); + result.SetBoolean("bookmarksSynced", + types.Has(syncer::UserSelectableType::kBookmarks)); + result.SetBoolean("extensionsSynced", + types.Has(syncer::UserSelectableType::kExtensions)); + result.SetBoolean("passwordsSynced", + types.Has(syncer::UserSelectableType::kPasswords)); + result.SetBoolean("preferencesSynced", + types.Has(syncer::UserSelectableType::kPreferences)); + result.SetBoolean("tabsSynced", types.Has(syncer::UserSelectableType::kTabs)); + result.SetBoolean("themesSynced", + types.Has(syncer::UserSelectableType::kThemes)); + result.SetBoolean("typedUrlsSynced", + types.Has(syncer::UserSelectableType::kHistory)); result.SetBoolean("paymentsIntegrationEnabled", false); std::string args; base::JSONWriter::Write(result, &args); @@ -142,17 +149,26 @@ // types. void CheckConfigDataTypeArguments(const base::DictionaryValue* dictionary, SyncAllDataConfig config, - syncer::ModelTypeSet types) { + syncer::UserSelectableTypeSet types) { CheckBool(dictionary, "syncAllDataTypes", config == SYNC_ALL_DATA); - CheckBool(dictionary, "appsSynced", types.Has(syncer::APPS)); - CheckBool(dictionary, "autofillSynced", types.Has(syncer::AUTOFILL)); - CheckBool(dictionary, "bookmarksSynced", types.Has(syncer::BOOKMARKS)); - CheckBool(dictionary, "extensionsSynced", types.Has(syncer::EXTENSIONS)); - CheckBool(dictionary, "passwordsSynced", types.Has(syncer::PASSWORDS)); - CheckBool(dictionary, "preferencesSynced", types.Has(syncer::PREFERENCES)); - CheckBool(dictionary, "tabsSynced", types.Has(syncer::PROXY_TABS)); - CheckBool(dictionary, "themesSynced", types.Has(syncer::THEMES)); - CheckBool(dictionary, "typedUrlsSynced", types.Has(syncer::TYPED_URLS)); + CheckBool(dictionary, "appsSynced", + types.Has(syncer::UserSelectableType::kApps)); + CheckBool(dictionary, "autofillSynced", + types.Has(syncer::UserSelectableType::kAutofill)); + CheckBool(dictionary, "bookmarksSynced", + types.Has(syncer::UserSelectableType::kBookmarks)); + CheckBool(dictionary, "extensionsSynced", + types.Has(syncer::UserSelectableType::kExtensions)); + CheckBool(dictionary, "passwordsSynced", + types.Has(syncer::UserSelectableType::kPasswords)); + CheckBool(dictionary, "preferencesSynced", + types.Has(syncer::UserSelectableType::kPreferences)); + CheckBool(dictionary, "tabsSynced", + types.Has(syncer::UserSelectableType::kTabs)); + CheckBool(dictionary, "themesSynced", + types.Has(syncer::UserSelectableType::kThemes)); + CheckBool(dictionary, "typedUrlsSynced", + types.Has(syncer::UserSelectableType::kHistory)); } std::unique_ptr<KeyedService> BuildMockSyncService( @@ -257,18 +273,13 @@ .WillByDefault(Return(syncer::SyncService::DISABLE_REASON_NONE)); ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsSyncRequested()) .WillByDefault(Return(true)); - ON_CALL(*mock_sync_service_, GetRegisteredDataTypes()) + ON_CALL(*mock_sync_service_->GetMockUserSettings(), + GetRegisteredSelectableTypes()) .WillByDefault(Return(GetAllTypes())); ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsSyncEverythingEnabled()) .WillByDefault(Return(true)); - ON_CALL(*mock_sync_service_->GetMockUserSettings(), GetChosenDataTypes()) - .WillByDefault(Return(GetAllTypes())); - ON_CALL(*mock_sync_service_, GetPreferredDataTypes()) - .WillByDefault( - Return(syncer::SyncUserSettingsImpl::ResolvePrefGroupsForTesting( - GetAllTypes()))); - ON_CALL(*mock_sync_service_, GetActiveDataTypes()) + ON_CALL(*mock_sync_service_->GetMockUserSettings(), GetSelectedTypes()) .WillByDefault(Return(GetAllTypes())); ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsEncryptEverythingAllowed()) @@ -807,7 +818,7 @@ .WillByDefault(Return(false)); SetupInitializedSyncService(); EXPECT_CALL(*mock_sync_service_->GetMockUserSettings(), - SetChosenDataTypes(true, _)); + SetSelectedTypes(true, _)); handler_->HandleSetDatatypes(&list_args); ExpectPageStatusResponse(PeopleHandler::kConfigurePageStatus); @@ -949,9 +960,8 @@ // Walks through each user selectable type, and tries to sync just that single // data type. TEST_F(PeopleHandlerTest, TestSyncIndividualTypes) { - syncer::ModelTypeSet user_selectable_types = GetAllTypes(); - for (syncer::ModelType type : user_selectable_types) { - syncer::ModelTypeSet type_to_set; + for (syncer::UserSelectableType type : GetAllTypes()) { + syncer::UserSelectableTypeSet type_to_set; type_to_set.Put(type); std::string args = GetConfiguration(NULL, CHOOSE_WHAT_TO_SYNC, @@ -967,8 +977,9 @@ ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsPassphraseRequired()) .WillByDefault(Return(false)); SetupInitializedSyncService(); - EXPECT_CALL(*mock_sync_service_->GetMockUserSettings(), - SetChosenDataTypes(false, ModelTypeSetMatches(type_to_set))); + EXPECT_CALL( + *mock_sync_service_->GetMockUserSettings(), + SetSelectedTypes(false, UserSelectableTypeSetMatches(type_to_set))); handler_->HandleSetDatatypes(&list_args); ExpectPageStatusResponse(PeopleHandler::kConfigurePageStatus); @@ -991,8 +1002,9 @@ ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsPassphraseRequired()) .WillByDefault(Return(false)); SetupInitializedSyncService(); - EXPECT_CALL(*mock_sync_service_->GetMockUserSettings(), - SetChosenDataTypes(false, ModelTypeSetMatches(GetAllTypes()))); + EXPECT_CALL( + *mock_sync_service_->GetMockUserSettings(), + SetSelectedTypes(false, UserSelectableTypeSetMatches(GetAllTypes()))); handler_->HandleSetDatatypes(&list_args); ExpectPageStatusResponse(PeopleHandler::kConfigurePageStatus); @@ -1120,8 +1132,7 @@ } TEST_F(PeopleHandlerTest, ShowSetupSyncForAllTypesIndividually) { - syncer::ModelTypeSet user_selectable_types = GetAllTypes(); - for (syncer::ModelType type : user_selectable_types) { + for (syncer::UserSelectableType type : GetAllTypes()) { ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsPassphraseRequired()) .WillByDefault(Return(false)); ON_CALL(*mock_sync_service_->GetMockUserSettings(), @@ -1132,12 +1143,9 @@ ON_CALL(*mock_sync_service_->GetMockUserSettings(), IsSyncEverythingEnabled()) .WillByDefault(Return(false)); - syncer::ModelTypeSet types(type); - ON_CALL(*mock_sync_service_->GetMockUserSettings(), GetChosenDataTypes()) + syncer::UserSelectableTypeSet types(type); + ON_CALL(*mock_sync_service_->GetMockUserSettings(), GetSelectedTypes()) .WillByDefault(Return(types)); - ON_CALL(*mock_sync_service_, GetPreferredDataTypes()) - .WillByDefault(Return( - syncer::SyncUserSettingsImpl::ResolvePrefGroupsForTesting(types))); // This should display the sync setup dialog (not login). handler_->HandleShowSetupUI(nullptr);
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index 47702e9..d9d49a0d 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -223,6 +223,8 @@ {"delayBeforeClickLong", IDS_SETTINGS_DELAY_BEFORE_CLICK_LONG}, {"delayBeforeClickVeryLong", IDS_SETTINGS_DELAY_BEFORE_CLICK_VERY_LONG}, {"autoclickRevertToLeftClick", IDS_SETTINGS_AUTOCLICK_REVERT_TO_LEFT_CLICK}, + {"autoclickStabilizeCursorPosition", + IDS_SETTINGS_AUTOCLICK_STABILIZE_CURSOR_POSITION}, {"autoclickMovementThresholdLabel", IDS_SETTINGS_AUTOCLICK_MOVEMENT_THRESHOLD_LABEL}, {"autoclickMovementThresholdExtraSmall",
diff --git a/chrome/browser/ui/webui/sync_internals_message_handler.cc b/chrome/browser/ui/webui/sync_internals_message_handler.cc index 3f5b7c97..dbcae7e4 100644 --- a/chrome/browser/ui/webui/sync_internals_message_handler.cc +++ b/chrome/browser/ui/webui/sync_internals_message_handler.cc
@@ -252,7 +252,7 @@ // asynchronously, and potentially at times we're not allowed to call into // the javascript side. We guard against this by invalidating this weak ptr // should javascript become disallowed. - service->GetAllNodes( + service->GetAllNodesForDebugging( base::Bind(&SyncInternalsMessageHandler::OnReceivedAllNodes, weak_ptr_factory_.GetWeakPtr(), request_id)); }
diff --git a/chrome/browser/ui/webui/sync_internals_message_handler_unittest.cc b/chrome/browser/ui/webui/sync_internals_message_handler_unittest.cc index b7c85e2..86df2a38 100644 --- a/chrome/browser/ui/webui/sync_internals_message_handler_unittest.cc +++ b/chrome/browser/ui/webui/sync_internals_message_handler_unittest.cc
@@ -65,8 +65,9 @@ return js_controller_.AsWeakPtr(); } - void GetAllNodes(const base::Callback<void(std::unique_ptr<base::ListValue>)>& - callback) override { + void GetAllNodesForDebugging( + const base::Callback<void(std::unique_ptr<base::ListValue>)>& callback) + override { get_all_nodes_callback_ = std::move(callback); }
diff --git a/chrome/browser/web_applications/bookmark_apps/policy/web_app_policy_manager_unittest.cc b/chrome/browser/web_applications/bookmark_apps/policy/web_app_policy_manager_unittest.cc index 5fb923e..e53b49a 100644 --- a/chrome/browser/web_applications/bookmark_apps/policy/web_app_policy_manager_unittest.cc +++ b/chrome/browser/web_applications/bookmark_apps/policy/web_app_policy_manager_unittest.cc
@@ -56,7 +56,7 @@ options.add_to_quick_launch_bar = false; options.install_placeholder = true; options.reinstall_placeholder = true; - options.stop_if_window_opened = true; + options.wait_for_windows_closed = true; return options; } @@ -76,7 +76,7 @@ options.add_to_quick_launch_bar = false; options.install_placeholder = true; options.reinstall_placeholder = true; - options.stop_if_window_opened = true; + options.wait_for_windows_closed = true; return options; } @@ -94,7 +94,7 @@ options.add_to_quick_launch_bar = false; options.install_placeholder = true; options.reinstall_placeholder = true; - options.stop_if_window_opened = true; + options.wait_for_windows_closed = true; return options; } @@ -112,7 +112,7 @@ options.add_to_quick_launch_bar = false; options.install_placeholder = true; options.reinstall_placeholder = true; - options.stop_if_window_opened = true; + options.wait_for_windows_closed = true; return options; } @@ -131,7 +131,7 @@ options.add_to_quick_launch_bar = false; options.install_placeholder = true; options.reinstall_placeholder = true; - options.stop_if_window_opened = true; + options.wait_for_windows_closed = true; return options; } @@ -150,7 +150,7 @@ options.add_to_quick_launch_bar = false; options.install_placeholder = true; options.reinstall_placeholder = true; - options.stop_if_window_opened = true; + options.wait_for_windows_closed = true; return options; } @@ -423,7 +423,7 @@ auto reinstall_options = GetWindowedInstallOptions(); reinstall_options.install_placeholder = false; reinstall_options.reinstall_placeholder = true; - reinstall_options.stop_if_window_opened = true; + reinstall_options.wait_for_windows_closed = true; expected_options_list.push_back(std::move(reinstall_options)); EXPECT_EQ(expected_options_list, install_options_list);
diff --git a/chrome/browser/web_applications/components/install_options.cc b/chrome/browser/web_applications/components/install_options.cc index d6edfc47..58ee0aa 100644 --- a/chrome/browser/web_applications/components/install_options.cc +++ b/chrome/browser/web_applications/components/install_options.cc
@@ -32,14 +32,14 @@ add_to_applications_menu, add_to_desktop, add_to_quick_launch_bar, override_previous_user_uninstall, bypass_service_worker_check, require_manifest, always_update, - stop_if_window_opened, install_placeholder, + wait_for_windows_closed, install_placeholder, reinstall_placeholder) == std::tie(other.url, other.launch_container, other.install_source, other.add_to_applications_menu, other.add_to_desktop, other.add_to_quick_launch_bar, other.override_previous_user_uninstall, other.bypass_service_worker_check, other.require_manifest, - other.always_update, other.stop_if_window_opened, + other.always_update, other.wait_for_windows_closed, other.install_placeholder, other.reinstall_placeholder); } @@ -60,8 +60,8 @@ << install_options.bypass_service_worker_check << "\n require_manifest: " << install_options.require_manifest << "\n always_update: " << install_options.always_update - << "\n stop_if_window_opened: " - << install_options.stop_if_window_opened + << "\n wait_for_windows_closed: " + << install_options.wait_for_windows_closed << "\n install_placeholder: " << install_options.install_placeholder << "\n reinstall_placeholder: "
diff --git a/chrome/browser/web_applications/components/install_options.h b/chrome/browser/web_applications/components/install_options.h index e509747..7f3d91e 100644 --- a/chrome/browser/web_applications/components/install_options.h +++ b/chrome/browser/web_applications/components/install_options.h
@@ -65,9 +65,9 @@ // Whether the app should be reinstalled even if it is already installed. bool always_update = false; - // Whether we should check if there are any opened windows for the app - // before we try to reinstall it. - bool stop_if_window_opened = false; + // Whether we should wait for all app windows being closed before reinstalling + // the placeholder. + bool wait_for_windows_closed = false; // Whether a placeholder app should be installed if we fail to retrieve the // metadata for the app. A placeholder app uses:
diff --git a/chrome/browser/web_applications/components/policy/web_app_policy_manager.cc b/chrome/browser/web_applications/components/policy/web_app_policy_manager.cc index f6efb41d..800ae0a 100644 --- a/chrome/browser/web_applications/components/policy/web_app_policy_manager.cc +++ b/chrome/browser/web_applications/components/policy/web_app_policy_manager.cc
@@ -104,7 +104,7 @@ ParseInstallOptionsFromPolicyEntry(*it, &install_options); // No need to install a placeholder because there should be one already. - install_options.stop_if_window_opened = true; + install_options.wait_for_windows_closed = true; install_options.reinstall_placeholder = true; // If the app is not a placeholder app, PendingAppManager will ignore the @@ -152,7 +152,7 @@ install_options.install_placeholder = true; // When the policy gets refreshed, we should try to reinstall placeholder // apps but only if they are not being used. - install_options.stop_if_window_opened = true; + install_options.wait_for_windows_closed = true; install_options.reinstall_placeholder = true; install_options_list.push_back(std::move(install_options));
diff --git a/chrome/browser/web_applications/components/web_app_ui_delegate.h b/chrome/browser/web_applications/components/web_app_ui_delegate.h index 02fd2b1..1ae5e90 100644 --- a/chrome/browser/web_applications/components/web_app_ui_delegate.h +++ b/chrome/browser/web_applications/components/web_app_ui_delegate.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_UI_DELEGATE_H_ #define CHROME_BROWSER_WEB_APPLICATIONS_COMPONENTS_WEB_APP_UI_DELEGATE_H_ +#include "base/callback_forward.h" #include "chrome/browser/web_applications/components/web_app_helpers.h" namespace web_app { @@ -14,6 +15,9 @@ class WebAppUiDelegate { public: virtual size_t GetNumWindowsForApp(const AppId& app_id) = 0; + + virtual void NotifyOnAllAppWindowsClosed(const AppId& app_id, + base::OnceClosure callback) = 0; }; } // namespace web_app
diff --git a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc index cef1ff2..03de80d 100644 --- a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc +++ b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager.cc
@@ -160,13 +160,13 @@ } if (registrar_->IsInstalled(extension_id.value())) { - // Stop if the app has any windows opened and |stop_if_window_opened| is - // true. - if (install_options.stop_if_window_opened && + if (install_options.wait_for_windows_closed && GetUiDelegate().GetNumWindowsForApp(extension_id.value()) != 0) { - std::move(front->callback) - .Run(install_options.url, - web_app::InstallResultCode::kWindowOpened); + GetUiDelegate().NotifyOnAllAppWindowsClosed( + extension_id.value(), + base::BindOnce(&PendingBookmarkAppManager::Install, + weak_ptr_factory_.GetWeakPtr(), install_options, + std::move(front->callback))); continue; }
diff --git a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager_unittest.cc b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager_unittest.cc index b91fd1d..b8b7bbf9 100644 --- a/chrome/browser/web_applications/extensions/pending_bookmark_app_manager_unittest.cc +++ b/chrome/browser/web_applications/extensions/pending_bookmark_app_manager_unittest.cc
@@ -1316,7 +1316,8 @@ } } -TEST_F(PendingBookmarkAppManagerTest, ReinstallPlaceholderAppIfUnused_Success) { +TEST_F(PendingBookmarkAppManagerTest, + ReinstallPlaceholderAppWhenUnused_NoOpenedWindows) { auto pending_app_manager = GetPendingBookmarkAppManagerWithTestFactories(); // Install a placeholder app auto install_options = GetFooInstallOptions(); @@ -1338,7 +1339,7 @@ // Reinstall placeholder { install_options.reinstall_placeholder = true; - install_options.stop_if_window_opened = true; + install_options.wait_for_windows_closed = true; ui_delegate()->SetNumWindowsForApp(GenerateFakeAppId(GURL(kFooWebAppUrl)), 0); url_loader()->SetNextLoadUrlResult( @@ -1362,7 +1363,7 @@ } TEST_F(PendingBookmarkAppManagerTest, - ReinstallPlaceholderAppIfUnused_FailsWindowOpened) { + ReinstallPlaceholderAppWhenUnused_OneWindowOpened) { auto pending_app_manager = GetPendingBookmarkAppManagerWithTestFactories(); // Install a placeholder app @@ -1385,20 +1386,25 @@ // Reinstall placeholder { install_options.reinstall_placeholder = true; - install_options.stop_if_window_opened = true; + install_options.wait_for_windows_closed = true; ui_delegate()->SetNumWindowsForApp(GenerateFakeAppId(GURL(kFooWebAppUrl)), 1); + url_loader()->SetNextLoadUrlResult( + GURL(kFooWebAppUrl), web_app::WebAppUrlLoader::Result::kUrlLoaded); + uninstaller()->SetNextResultForTesting(GURL(kFooWebAppUrl), true); base::Optional<GURL> url; base::Optional<web_app::InstallResultCode> code; std::tie(url, code) = InstallAndWait(pending_app_manager.get(), install_options); - EXPECT_EQ(web_app::InstallResultCode::kWindowOpened, code.value()); + EXPECT_EQ(web_app::InstallResultCode::kSuccess, code.value()); EXPECT_EQ(GURL(kFooWebAppUrl), url.value()); - EXPECT_EQ(0u, uninstall_call_count()); - EXPECT_EQ(0u, install_run_count()); + EXPECT_EQ(1u, uninstall_call_count()); + EXPECT_EQ(GURL(kFooWebAppUrl), last_uninstalled_app_url()); + + EXPECT_EQ(1u, install_run_count()); EXPECT_EQ(1u, install_placeholder_run_count()); } }
diff --git a/chrome/browser/web_applications/test/test_web_app_ui_delegate.cc b/chrome/browser/web_applications/test/test_web_app_ui_delegate.cc index 5262652..b79689d 100644 --- a/chrome/browser/web_applications/test/test_web_app_ui_delegate.cc +++ b/chrome/browser/web_applications/test/test_web_app_ui_delegate.cc
@@ -4,7 +4,12 @@ #include "chrome/browser/web_applications/test/test_web_app_ui_delegate.h" +#include <utility> + +#include "base/callback.h" #include "base/stl_util.h" +#include "base/test/bind_test_util.h" +#include "base/threading/thread_task_runner_handle.h" namespace web_app { @@ -22,4 +27,16 @@ return app_id_to_num_windows_map_[app_id]; } +void TestWebAppUiDelegate::NotifyOnAllAppWindowsClosed( + const AppId& app_id, + base::OnceClosure callback) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(base::BindLambdaForTesting( + [&, app_id](base::OnceClosure callback) { + app_id_to_num_windows_map_[app_id] = 0; + std::move(callback).Run(); + }), + std::move(callback))); +} + } // namespace web_app
diff --git a/chrome/browser/web_applications/test/test_web_app_ui_delegate.h b/chrome/browser/web_applications/test/test_web_app_ui_delegate.h index cd2d6d3..40ec6015 100644 --- a/chrome/browser/web_applications/test/test_web_app_ui_delegate.h +++ b/chrome/browser/web_applications/test/test_web_app_ui_delegate.h
@@ -21,6 +21,8 @@ // WebAppUiDelegate size_t GetNumWindowsForApp(const AppId& app_id) override; + void NotifyOnAllAppWindowsClosed(const AppId& app_id, + base::OnceClosure callback) override; private: std::map<AppId, size_t> app_id_to_num_windows_map_;
diff --git a/chrome/common/thread_profiler.cc b/chrome/common/thread_profiler.cc index db16b3b..ca9b35b 100644 --- a/chrome/common/thread_profiler.cc +++ b/chrome/common/thread_profiler.cc
@@ -234,7 +234,9 @@ std::make_unique<CallStackProfileBuilder>( CallStackProfileParams(GetProcess(), thread, CallStackProfileParams::PROCESS_STARTUP), - work_id_recorder_.get())); + work_id_recorder_.get(), + &metrics::CallStackProfileBuilder:: + GetStackSamplingProfilerMetadataRecorder())); startup_profiler_->Start(); @@ -280,7 +282,9 @@ std::make_unique<CallStackProfileBuilder>( CallStackProfileParams(GetProcess(), thread_, CallStackProfileParams::PERIODIC_COLLECTION), - work_id_recorder_.get(), nullptr, + work_id_recorder_.get(), + &metrics::CallStackProfileBuilder:: + GetStackSamplingProfilerMetadataRecorder(), base::BindOnce(&ThreadProfiler::OnPeriodicCollectionCompleted, owning_thread_task_runner_, weak_factory_.GetWeakPtr())));
diff --git a/chrome/renderer/BUILD.gn b/chrome/renderer/BUILD.gn index b1b07bd7..44798c35 100644 --- a/chrome/renderer/BUILD.gn +++ b/chrome/renderer/BUILD.gn
@@ -100,8 +100,6 @@ "prerender/prerenderer_client.h", "sandbox_status_extension_android.cc", "sandbox_status_extension_android.h", - "security_filter_peer.cc", - "security_filter_peer.h", "security_interstitials/security_interstitial_page_controller.cc", "security_interstitials/security_interstitial_page_controller.h", "supervised_user/supervised_user_error_page_controller.cc",
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 52162509..202376e 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -321,6 +321,9 @@ void ChromeContentRendererClient::RenderThreadStarted() { RenderThread* thread = RenderThread::Get(); + main_thread_profiler_->AddAuxUnwinder(std::make_unique<V8Unwinder>( + v8::Isolate::GetCurrent()->GetUnwindState())); + thread->SetRendererProcessType( IsStandaloneContentExtensionProcess() ? blink::scheduler::WebRendererProcessType::kExtensionRenderer
diff --git a/chrome/renderer/chrome_render_thread_observer.cc b/chrome/renderer/chrome_render_thread_observer.cc index d2cc601..21d307f 100644 --- a/chrome/renderer/chrome_render_thread_observer.cc +++ b/chrome/renderer/chrome_render_thread_observer.cc
@@ -36,7 +36,6 @@ #include "chrome/common/render_messages.h" #include "chrome/common/url_constants.h" #include "chrome/renderer/content_settings_observer.h" -#include "chrome/renderer/security_filter_peer.h" #include "components/visitedlink/renderer/visitedlink_slave.h" #include "content/public/child/child_thread.h" #include "content/public/common/content_switches.h" @@ -85,9 +84,7 @@ : weak_factory_(this) { } - std::unique_ptr<content::RequestPeer> OnRequestComplete( - std::unique_ptr<content::RequestPeer> current_peer, - int error_code) override { + void OnRequestComplete() override { // Update the browser about our cache. // Rate limit informing the host of our cache stats. if (!weak_factory_.HasWeakPtrs()) { @@ -97,14 +94,6 @@ weak_factory_.GetWeakPtr()), base::TimeDelta::FromMilliseconds(kCacheStatsDelayMS)); } - - if (error_code == net::ERR_ABORTED) { - return current_peer; - } - - // Resource canceled with a specific error are filtered. - return SecurityFilterPeer::CreateSecurityFilterPeerForDeniedRequest( - std::move(current_peer), error_code); } std::unique_ptr<content::RequestPeer> OnReceivedResponse(
diff --git a/chrome/renderer/security_filter_peer.cc b/chrome/renderer/security_filter_peer.cc deleted file mode 100644 index 5ce0a5f0..0000000 --- a/chrome/renderer/security_filter_peer.cc +++ /dev/null
@@ -1,101 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/renderer/security_filter_peer.h" - -#include <memory> -#include <string> -#include <utility> - -#include "base/memory/ptr_util.h" -#include "net/base/net_errors.h" -#include "net/http/http_response_headers.h" -#include "services/network/public/cpp/url_loader_completion_status.h" - -SecurityFilterPeer::SecurityFilterPeer( - std::unique_ptr<content::RequestPeer> peer) - : original_peer_(std::move(peer)) {} -SecurityFilterPeer::~SecurityFilterPeer() {} - -// static -std::unique_ptr<content::RequestPeer> -SecurityFilterPeer::CreateSecurityFilterPeerForDeniedRequest( - std::unique_ptr<content::RequestPeer> peer, - int os_error) { - // Create a filter for SSL and CERT errors. - switch (os_error) { - case net::ERR_SSL_PROTOCOL_ERROR: - case net::ERR_CERT_COMMON_NAME_INVALID: - case net::ERR_CERT_DATE_INVALID: - case net::ERR_CERT_AUTHORITY_INVALID: - case net::ERR_CERT_CONTAINS_ERRORS: - case net::ERR_CERT_NO_REVOCATION_MECHANISM: - case net::ERR_CERT_UNABLE_TO_CHECK_REVOCATION: - case net::ERR_CERT_REVOKED: - case net::ERR_CERT_INVALID: - case net::ERR_CERT_WEAK_SIGNATURE_ALGORITHM: - case net::ERR_CERT_WEAK_KEY: - case net::ERR_CERT_NAME_CONSTRAINT_VIOLATION: - case net::ERR_INSECURE_RESPONSE: - case net::ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN: - return base::WrapUnique(new SecurityFilterPeer(std::move(peer))); - default: - // For other errors, we use our normal error handling. - return peer; - } -} - -void SecurityFilterPeer::OnUploadProgress(uint64_t position, uint64_t size) { - NOTREACHED(); -} - -bool SecurityFilterPeer::OnReceivedRedirect( - const net::RedirectInfo& redirect_info, - const network::ResourceResponseInfo& info) { - NOTREACHED(); - return false; -} - -void SecurityFilterPeer::OnReceivedResponse( - const network::ResourceResponseInfo& info) { - NOTREACHED(); -} - -void SecurityFilterPeer::OnStartLoadingResponseBody( - mojo::ScopedDataPipeConsumerHandle body) { - NOTREACHED(); -} - -void SecurityFilterPeer::OnTransferSizeUpdated(int transfer_size_diff) { - NOTREACHED(); -} - -void SecurityFilterPeer::OnCompletedRequest( - const network::URLLoaderCompletionStatus& status) { - network::ResourceResponseInfo info; - info.headers = CreateHeaders(); - info.content_length = 0; - original_peer_->OnReceivedResponse(info); - network::URLLoaderCompletionStatus ok_status(status); - ok_status.error_code = net::OK; - original_peer_->OnCompletedRequest(ok_status); -} - -scoped_refptr<base::TaskRunner> SecurityFilterPeer::GetTaskRunner() { - return original_peer_->GetTaskRunner(); -} - -scoped_refptr<net::HttpResponseHeaders> SecurityFilterPeer::CreateHeaders() { - std::string raw_headers; - raw_headers.append("HTTP/1.1 200 OK"); - raw_headers.push_back('\0'); - // Don't cache the data we are serving, it is not the real data for that URL - // (if the filtered resource were to make it into the WebCore cache, then the - // same URL loaded in a safe scenario would still return the filtered - // resource). - raw_headers.append("cache-control: no-cache"); - raw_headers.push_back('\0'); - raw_headers.push_back('\0'); - return base::MakeRefCounted<net::HttpResponseHeaders>(raw_headers); -}
diff --git a/chrome/renderer/security_filter_peer.h b/chrome/renderer/security_filter_peer.h deleted file mode 100644 index b6f733b..0000000 --- a/chrome/renderer/security_filter_peer.h +++ /dev/null
@@ -1,56 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_RENDERER_SECURITY_FILTER_PEER_H_ -#define CHROME_RENDERER_SECURITY_FILTER_PEER_H_ - -#include <stdint.h> - -#include <memory> -#include <string> - -#include "base/macros.h" -#include "content/public/renderer/request_peer.h" -#include "services/network/public/cpp/resource_response_info.h" - -// The SecurityFilterPeer is a proxy to a -// content::RequestPeer instance. It is used to pre-process -// unsafe resources (such as mixed-content resource). -// Call the factory method CreateSecurityFilterPeer() to obtain an instance of -// SecurityFilterPeer based on the original Peer. -// A SecurityFilterPeer is created only when the associated request is rejected, -// which means content::RequestPeer methods other than OnCompletedRequest must -// not be called. -class SecurityFilterPeer final : public content::RequestPeer { - public: - ~SecurityFilterPeer() override; - - static std::unique_ptr<content::RequestPeer> - CreateSecurityFilterPeerForDeniedRequest( - std::unique_ptr<content::RequestPeer> peer, - int os_error); - - // content::RequestPeer methods. - void OnUploadProgress(uint64_t position, uint64_t size) override; - bool OnReceivedRedirect(const net::RedirectInfo& redirect_info, - const network::ResourceResponseInfo& info) override; - void OnReceivedResponse(const network::ResourceResponseInfo& info) override; - void OnStartLoadingResponseBody( - mojo::ScopedDataPipeConsumerHandle body) override; - void OnTransferSizeUpdated(int transfer_size_diff) override; - void OnCompletedRequest( - const network::URLLoaderCompletionStatus& status) override; - scoped_refptr<base::TaskRunner> GetTaskRunner() override; - - private: - explicit SecurityFilterPeer(std::unique_ptr<content::RequestPeer> peer); - - static scoped_refptr<net::HttpResponseHeaders> CreateHeaders(); - - std::unique_ptr<content::RequestPeer> original_peer_; - - DISALLOW_COPY_AND_ASSIGN(SecurityFilterPeer); -}; - -#endif // CHROME_RENDERER_SECURITY_FILTER_PEER_H_
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index e5d08b6..5406779a 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -886,7 +886,6 @@ "../browser/sessions/tab_restore_service_load_waiter.h", "../browser/site_isolation/chrome_site_per_process_browsertest.cc", "../browser/site_isolation/site_details_browsertest.cc", - "../browser/ui/bloated_renderer/bloated_renderer_tab_helper_browsertest.cc", "../browser/ui/blocked_content/popup_tracker_browsertest.cc", "../browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_browsertest.cc", "../browser/ui/blocked_content/tab_under_blocker_browsertest.cc", @@ -1841,6 +1840,7 @@ "../browser/chromeos/login/existing_user_controller_browsertest.cc", "../browser/chromeos/login/hid_detection_browsertest.cc", "../browser/chromeos/login/kiosk_browsertest.cc", + "../browser/chromeos/login/lock/fingerprint_unlock_browsertest.cc", "../browser/chromeos/login/lock/screen_locker_browsertest.cc", "../browser/chromeos/login/lock/screen_locker_tester.cc", "../browser/chromeos/login/lock/screen_locker_tester.h", @@ -2942,7 +2942,6 @@ "../browser/ui/autofill/popup_view_common_unittest.cc", "../browser/ui/autofill/popup_view_test_helpers.cc", "../browser/ui/autofill/popup_view_test_helpers.h", - "../browser/ui/bloated_renderer/bloated_renderer_tab_helper_unittest.cc", "../browser/ui/blocked_content/popup_opener_tab_helper_unittest.cc", "../browser/ui/blocked_content/safe_browsing_triggered_popup_blocker_unittest.cc", "../browser/ui/bookmarks/bookmark_editor_unittest.cc",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java index 68dc02b..d03a274c 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/ChromeActivityTestRule.java
@@ -435,7 +435,7 @@ ChromeTabUtils.waitForTabPageLoaded(tab, (String) null); - if (tab != null && NewTabPage.isNTPUrl(tab.getUrl())) { + if (tab != null && NewTabPage.isNTPUrl(tab.getUrl()) && !getActivity().isInOverviewMode()) { NewTabPageTestUtils.waitForNtpLoaded(tab); }
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index 853b39e..5233962 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc
@@ -388,6 +388,13 @@ profile_manager->GetSystemProfilePath()); } + if (IsOffTheRecord()) { + key_ = std::make_unique<ProfileKey>(original_profile_->GetPath(), + original_profile_->GetProfileKey()); + } else { + key_ = std::make_unique<ProfileKey>(profile_path_); + } + BrowserContext::Initialize(this, profile_path_); #if defined(OS_ANDROID) @@ -425,13 +432,7 @@ else CreateTestingPrefService(); - if (IsOffTheRecord()) { - key_ = - std::make_unique<ProfileKey>(original_profile_->GetPath(), prefs_.get(), - original_profile_->GetProfileKey()); - } else { - key_ = std::make_unique<ProfileKey>(profile_path_, prefs_.get()); - } + key_->SetPrefs(prefs_.get()); SimpleKeyMap::GetInstance()->Associate(this, key_.get()); if (!base::PathExists(profile_path_))
diff --git a/chrome/test/chromedriver/test/run_py_tests.py b/chrome/test/chromedriver/test/run_py_tests.py index 10fde09e..48e3ed8 100755 --- a/chrome/test/chromedriver/test/run_py_tests.py +++ b/chrome/test/chromedriver/test/run_py_tests.py
@@ -94,6 +94,8 @@ 'ChromeLogPathCapabilityTest.testChromeLogPath', # https://bugs.chromium.org/p/chromedriver/issues/detail?id=1367 'ChromeExtensionsCapabilityTest.testWaitsForExtensionToLoad', + # https://bugs.chromium.org/p/chromium/issues/detail?id=946704 + 'ChromeDownloadDirTest.testFileDownloadWithClick', ] _OS_SPECIFIC_FILTER['linux'] = [ # https://bugs.chromium.org/p/chromium/issues/detail?id=932073
diff --git a/chrome/test/data/android/render_tests/ExploreSitesPageTest.recycler_layout.Nexus_5-19.png.sha1 b/chrome/test/data/android/render_tests/ExploreSitesPageTest.recycler_layout.Nexus_5-19.png.sha1 index 44d81ba..ff1bb65 100644 --- a/chrome/test/data/android/render_tests/ExploreSitesPageTest.recycler_layout.Nexus_5-19.png.sha1 +++ b/chrome/test/data/android/render_tests/ExploreSitesPageTest.recycler_layout.Nexus_5-19.png.sha1
@@ -1 +1 @@ -d60de483ccbe01a433798e31df3f9f08dc387480 \ No newline at end of file +8d1722f71ac07ab22c7c126b00e18deff42827f1 \ No newline at end of file
diff --git a/chrome/test/data/android/render_tests/ExploreSitesPageTest.recycler_layout_back.Nexus_5-19.png.sha1 b/chrome/test/data/android/render_tests/ExploreSitesPageTest.recycler_layout_back.Nexus_5-19.png.sha1 index d6523ec..d7f7cc78 100644 --- a/chrome/test/data/android/render_tests/ExploreSitesPageTest.recycler_layout_back.Nexus_5-19.png.sha1 +++ b/chrome/test/data/android/render_tests/ExploreSitesPageTest.recycler_layout_back.Nexus_5-19.png.sha1
@@ -1 +1 @@ -33ecdb2b25aac53cc826f38e281a11cf6eefdb8e \ No newline at end of file +56c1615c2cae305efe6fdc0d73d660608d5470f5 \ No newline at end of file
diff --git a/chrome/test/data/downloads/large_image.png b/chrome/test/data/downloads/large_image.png new file mode 100644 index 0000000..6e91762 --- /dev/null +++ b/chrome/test/data/downloads/large_image.png Binary files differ
diff --git a/chrome/test/data/media/picture-in-picture/window-size.html b/chrome/test/data/media/picture-in-picture/window-size.html index ef26933..50c954c 100644 --- a/chrome/test/data/media/picture-in-picture/window-size.html +++ b/chrome/test/data/media/picture-in-picture/window-size.html
@@ -137,5 +137,13 @@ document.title = 'leavepictureinpicture'; }); } + + function tryToEnterPictureInPictureAfterLeaving() { + video.addEventListener('leavepictureinpicture', () => { + video.requestPictureInPicture() + .then(_ => { document.title = 'entered Picture-in-Picture after leaving'; }) + .catch(e => { document.title = 'failed to enter Picture-in-Picture after leaving'; }); + }); + } </script> </html>
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 58baa5e..8439165 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -4169,6 +4169,11 @@ "DeviceSamlLoginAuthenticationType": { }, + "DeviceScheduledUpdateCheck": { + "os": ["chromeos"], + "test_policy": { "DeviceScheduledUpdateCheck": {"update_check_time" : {"hour": 23, "minute": 35}, "frequency": "WEEKLY", "day_of_week": "MONDAY" }} + }, + "ChromeCleanupEnabled": { "os": ["win"], "test_policy": { "ChromeCleanupEnabled": true },
diff --git a/chrome/test/data/webui/print_preview/pin_settings_test.js b/chrome/test/data/webui/print_preview/pin_settings_test.js index 1743b07..13340ee4 100644 --- a/chrome/test/data/webui/print_preview/pin_settings_test.js +++ b/chrome/test/data/webui/print_preview/pin_settings_test.js
@@ -22,6 +22,7 @@ pinSection = document.createElement('print-preview-pin-settings'); pinSection.settings = model.settings; + pinSection.state = print_preview_new.State.READY; pinSection.disabled = false; test_util.fakeDataBind(model, pinSection, 'settings'); document.body.appendChild(pinSection);
diff --git a/chromecast/BUILD.gn b/chromecast/BUILD.gn index d44fba3..b579c227 100644 --- a/chromecast/BUILD.gn +++ b/chromecast/BUILD.gn
@@ -102,6 +102,16 @@ tests += [ "//chromecast/media/cma/backend/android:cast_android_cma_backend_unittests" ] } + cast_media_unittests_filter = { + test_name = "cast_media_unittests" + + gtest_excludes = vendor_cast_media_gtest_excludes + + # --test-launcher-jobs=1 => so internal code can bind to port + args = [ "--test-launcher-jobs=1" ] + } + filters += [ cast_media_unittests_filter ] + if (!is_android) { tests += [ ":cast_shell_browsertests", @@ -114,16 +124,6 @@ tests += [ "//jingle:jingle_unittests" ] } - cast_media_unittests_filter = { - test_name = "cast_media_unittests" - - gtest_excludes = vendor_cast_media_gtest_excludes - - # --test-launcher-jobs=1 => so internal code can bind to port - args = [ "--test-launcher-jobs=1" ] - } - filters += [ cast_media_unittests_filter ] - cast_shell_browsertests_filter = { test_name = "cast_shell_browsertests" @@ -229,6 +229,19 @@ } filters += [ base_unittests_filter ] + cast_avsettings_unittests_filter = { + test_name = "cast_avsettings_unittests" + gtest_excludes = [] + if (is_android_things) { + # Disable tests to enable presubmit. Re-enable for b/120669054. + gtest_excludes += [ + "JniVolumeControllerTest.SetMutedNotifiesAllVolumeObservers", + "JniVolumeControllerTest.SetVolumeNotifiesVolumeObserver", + ] + } + } + filters += [ cast_avsettings_unittests_filter ] + cc_unittests_filter = { test_name = "cc_unittests" @@ -256,8 +269,10 @@ # (b/36984215). gtest_excludes = [ "*.IsSupportedVideoConfig_VP9TransferFunctions" ] if (is_android_things) { - gtest_excludes += - [ "FontUniqueNameLookupTest.TestMatchPostScriptNameTtc" ] + gtest_excludes += [ + "FontUniqueNameLookupTest.TestMatchPostScriptNameTtc", + "SiteInstanceTest.HasWrongProcessForURL", + ] } if (target_os == "linux" && !is_cast_desktop_build) { # DesktopCaptureDeviceTest.*: No capture device on Eureka @@ -364,6 +379,16 @@ } } filters += [ net_unittests_filter ] + + cast_receiver_unittests_filter = { + test_name = "cast_receiver_unittests" + gtest_excludes = [] + if (is_android_things) { + # Disable tests to enable presubmit. Re-enable for b/120669054. + gtest_excludes += [ "ApplicationManagerImplTest.SwapBackgroundApp_StereoVirtualDevice_BitstreamNotSupported" ] + } + } + filters += [ cast_receiver_unittests_filter ] } # Creates the build and run lists for all test targets.
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc index 8dc9ba6..5ad00bf 100644 --- a/chromecast/browser/cast_content_browser_client.cc +++ b/chromecast/browser/cast_content_browser_client.cc
@@ -656,7 +656,7 @@ return locale.empty() ? "en-US" : locale; } -content::QuotaPermissionContext* +scoped_refptr<content::QuotaPermissionContext> CastContentBrowserClient::CreateQuotaPermissionContext() { return new CastQuotaPermissionContext(); }
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h index 6c96f35c..408a2cc 100644 --- a/chromecast/browser/cast_content_browser_client.h +++ b/chromecast/browser/cast_content_browser_client.h
@@ -147,7 +147,8 @@ content::WebPreferences* prefs) override; void ResourceDispatcherHostCreated() override; std::string GetApplicationLocale() override; - content::QuotaPermissionContext* CreateQuotaPermissionContext() override; + scoped_refptr<content::QuotaPermissionContext> CreateQuotaPermissionContext() + override; void GetQuotaSettings( content::BrowserContext* context, content::StoragePartition* partition,
diff --git a/chromecast/browser/cast_network_contexts.cc b/chromecast/browser/cast_network_contexts.cc index ddb6eeb..a39f2b0 100644 --- a/chromecast/browser/cast_network_contexts.cc +++ b/chromecast/browser/cast_network_contexts.cc
@@ -20,6 +20,7 @@ #include "components/variations/net/variations_http_headers.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/cors_exempt_headers.h" #include "content/public/browser/network_service_instance.h" #include "content/public/browser/storage_partition.h" #include "services/network/network_context.h" @@ -103,6 +104,7 @@ context_getter_ = std::move(context_getter); network::mojom::NetworkContextParamsPtr network_context_params = network::mojom::NetworkContextParams::New(); + content::UpdateCorsExemptHeader(network_context_params.get()); variations::UpdateCorsExemptHeaderForVariations( network_context_params.get()); network_context_ = std::make_unique<network::NetworkContext>(
diff --git a/chromecast/browser/network_context_manager.cc b/chromecast/browser/network_context_manager.cc index 3594894..c887d609 100644 --- a/chromecast/browser/network_context_manager.cc +++ b/chromecast/browser/network_context_manager.cc
@@ -11,6 +11,7 @@ #include "components/variations/net/variations_http_headers.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/cors_exempt_headers.h" #include "content/public/browser/network_service_instance.h" #include "net/url_request/url_request_context_getter.h" #include "services/network/network_context.h" @@ -52,6 +53,7 @@ : content::GetNetworkServiceImpl(); network::mojom::NetworkContextParamsPtr network_context_params = network::mojom::NetworkContextParams::New(); + content::UpdateCorsExemptHeader(network_context_params.get()); variations::UpdateCorsExemptHeaderForVariations(network_context_params.get()); network_context_ = std::make_unique<network::NetworkContext>( network_service, mojo::MakeRequest(&network_context_ptr_),
diff --git a/components/autofill_assistant/browser/BUILD.gn b/components/autofill_assistant/browser/BUILD.gn index b908c5ff..72407bce 100644 --- a/components/autofill_assistant/browser/BUILD.gn +++ b/components/autofill_assistant/browser/BUILD.gn
@@ -37,6 +37,8 @@ "actions/autofill_action.h", "actions/click_action.cc", "actions/click_action.h", + "actions/expect_navigation_action.cc", + "actions/expect_navigation_action.h", "actions/focus_element_action.cc", "actions/focus_element_action.h", "actions/get_payment_information_action.cc", @@ -71,6 +73,8 @@ "actions/upload_dom_action.h", "actions/wait_for_dom_action.cc", "actions/wait_for_dom_action.h", + "actions/wait_for_navigation_action.cc", + "actions/wait_for_navigation_action.h", "batch_element_checker.cc", "batch_element_checker.h", "chip.cc",
diff --git a/components/autofill_assistant/browser/actions/action.cc b/components/autofill_assistant/browser/actions/action.cc index 67dcd0f..a3acc6b 100644 --- a/components/autofill_assistant/browser/actions/action.cc +++ b/components/autofill_assistant/browser/actions/action.cc
@@ -109,6 +109,12 @@ case ActionProto::ActionInfoCase::kShowInfoBox: out << "ShowInfoBox"; break; + case ActionProto::ActionInfoCase::kExpectNavigation: + out << "ExpectNavigation"; + break; + case ActionProto::ActionInfoCase::kWaitForNavigation: + out << "WaitForNavigation"; + break; case ActionProto::ActionInfoCase::ACTION_INFO_NOT_SET: out << "ACTION_INFO_NOT_SET"; break;
diff --git a/components/autofill_assistant/browser/actions/action_delegate.h b/components/autofill_assistant/browser/actions/action_delegate.h index 706b6be7..9c3e404 100644 --- a/components/autofill_assistant/browser/actions/action_delegate.h +++ b/components/autofill_assistant/browser/actions/action_delegate.h
@@ -169,7 +169,6 @@ const Selector& selector, const std::string& value, bool simulate_key_presses, - int key_press_delay_in_millisecond, base::OnceCallback<void(const ClientStatus&)> callback) = 0; // Set the |value| of the |attribute| of the element given by |selector|. @@ -184,7 +183,6 @@ virtual void SendKeyboardInput( const Selector& selector, const std::vector<UChar32>& codepoints, - int key_press_delay_in_millisecond, base::OnceCallback<void(const ClientStatus&)> callback) = 0; // Return the outerHTML of an element given by |selector|. @@ -193,6 +191,25 @@ base::OnceCallback<void(const ClientStatus&, const std::string&)> callback) = 0; + // Make the next call to WaitForNavigation to expect a navigation event that + // started after this call. + virtual void ExpectNavigation() = 0; + + // Returns true if the expected navigation, on which WaitForNavigation() might + // be waiting, has started and maybe even ended. + virtual bool ExpectedNavigationHasStarted() = 0; + + // Wait for a navigation event to end that started after the last call to + // ExpectNavigation(). + // + // If ExpectNavigation() was never called in the script, the function returns + // false and never calls the callback. + // + // The callback is passed true if navigation succeeded. The callback might be + // called immediately if navigation has already succeeded. + virtual bool WaitForNavigation( + base::OnceCallback<void(bool)> on_navigation_done) = 0; + // Load |url| in the current tab. Returns immediately, before the new page has // been loaded. virtual void LoadURL(const GURL& url) = 0;
diff --git a/components/autofill_assistant/browser/actions/autofill_action.cc b/components/autofill_assistant/browser/actions/autofill_action.cc index dc62d46..3c1136bd 100644 --- a/components/autofill_assistant/browser/actions/autofill_action.cc +++ b/components/autofill_assistant/browser/actions/autofill_action.cc
@@ -252,7 +252,6 @@ Selector(required_fields.Get(required_fields_index).element()), fallback_value, required_fields.Get(required_fields_index).simulate_key_presses(), - required_fields.Get(required_fields_index).delay_in_millisecond(), base::BindOnce(&AutofillAction::OnSetFallbackFieldValue, weak_ptr_factory_.GetWeakPtr(), delegate, required_fields_index));
diff --git a/components/autofill_assistant/browser/actions/expect_navigation_action.cc b/components/autofill_assistant/browser/actions/expect_navigation_action.cc new file mode 100644 index 0000000..46841e4 --- /dev/null +++ b/components/autofill_assistant/browser/actions/expect_navigation_action.cc
@@ -0,0 +1,29 @@ +// 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 "components/autofill_assistant/browser/actions/expect_navigation_action.h" + +#include <utility> + +#include "base/callback.h" +#include "components/autofill_assistant/browser/actions/action_delegate.h" + +namespace autofill_assistant { + +ExpectNavigationAction::ExpectNavigationAction(const ActionProto& proto) + : Action(proto) { + DCHECK(proto_.has_expect_navigation()); +} + +ExpectNavigationAction::~ExpectNavigationAction() {} + +void ExpectNavigationAction::InternalProcessAction( + ActionDelegate* delegate, + ProcessActionCallback callback) { + delegate->ExpectNavigation(); + UpdateProcessedAction(ACTION_APPLIED); + std::move(callback).Run(std::move(processed_action_proto_)); +} + +} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/actions/expect_navigation_action.h b/components/autofill_assistant/browser/actions/expect_navigation_action.h new file mode 100644 index 0000000..c612894 --- /dev/null +++ b/components/autofill_assistant/browser/actions/expect_navigation_action.h
@@ -0,0 +1,29 @@ +// 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 COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_EXPECT_NAVIGATION_ACTION_H_ +#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_EXPECT_NAVIGATION_ACTION_H_ + +#include <string> + +#include "base/macros.h" +#include "components/autofill_assistant/browser/actions/action.h" + +namespace autofill_assistant { + +class ExpectNavigationAction : public Action { + public: + explicit ExpectNavigationAction(const ActionProto& proto); + ~ExpectNavigationAction() override; + + private: + // Overrides Action: + void InternalProcessAction(ActionDelegate* delegate, + ProcessActionCallback callback) override; + + DISALLOW_COPY_AND_ASSIGN(ExpectNavigationAction); +}; + +} // namespace autofill_assistant +#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_EXPECT_NAVIGATION_ACTION_H_
diff --git a/components/autofill_assistant/browser/actions/get_payment_information_action.cc b/components/autofill_assistant/browser/actions/get_payment_information_action.cc index a8b6adb..7960da8 100644 --- a/components/autofill_assistant/browser/actions/get_payment_information_action.cc +++ b/components/autofill_assistant/browser/actions/get_payment_information_action.cc
@@ -80,6 +80,13 @@ ->set_card_issuer_network(card_issuer_network); delegate->GetClientMemory()->set_selected_card( std::move(payment_information->card)); + + if (!get_payment_information.billing_address_name().empty()) { + DCHECK(payment_information->billing_address); + delegate->GetClientMemory()->set_selected_address( + get_payment_information.billing_address_name(), + std::move(payment_information->billing_address)); + } } if (!get_payment_information.shipping_address_name().empty()) { @@ -89,13 +96,6 @@ std::move(payment_information->shipping_address)); } - if (!get_payment_information.billing_address_name().empty()) { - DCHECK(payment_information->billing_address); - delegate->GetClientMemory()->set_selected_address( - get_payment_information.billing_address_name(), - std::move(payment_information->billing_address)); - } - if (get_payment_information.has_contact_details()) { auto contact_details_proto = get_payment_information.contact_details(); autofill::AutofillProfile contact_profile;
diff --git a/components/autofill_assistant/browser/actions/mock_action_delegate.h b/components/autofill_assistant/browser/actions/mock_action_delegate.h index 772365a..49e07b04 100644 --- a/components/autofill_assistant/browser/actions/mock_action_delegate.h +++ b/components/autofill_assistant/browser/actions/mock_action_delegate.h
@@ -116,7 +116,6 @@ void SetFieldValue(const Selector& selector, const std::string& value, bool ignored_simulate_key_presses, - int ignored_delay_in_millisecond, base::OnceCallback<void(const ClientStatus&)> callback) { OnSetFieldValue(selector, value, callback); } @@ -132,15 +131,18 @@ const std::string& value, base::OnceCallback<void(const ClientStatus&)> callback)); - MOCK_METHOD4(SendKeyboardInput, + MOCK_METHOD3(SendKeyboardInput, void(const Selector& selector, const std::vector<UChar32>& codepoints, - int delay_in_millisecond, base::OnceCallback<void(const ClientStatus&)> callback)); MOCK_METHOD2(GetOuterHtml, void(const Selector& selector, base::OnceCallback<void(const ClientStatus&, const std::string&)> callback)); + MOCK_METHOD0(ExpectNavigation, void()); + MOCK_METHOD0(ExpectedNavigationHasStarted, bool()); + MOCK_METHOD1(WaitForNavigation, + bool(base::OnceCallback<void(bool)> callback)); MOCK_METHOD1(LoadURL, void(const GURL& url)); MOCK_METHOD0(Shutdown, void()); MOCK_METHOD0(Close, void());
diff --git a/components/autofill_assistant/browser/actions/navigate_action.cc b/components/autofill_assistant/browser/actions/navigate_action.cc index 731f3e80..48be36d8 100644 --- a/components/autofill_assistant/browser/actions/navigate_action.cc +++ b/components/autofill_assistant/browser/actions/navigate_action.cc
@@ -21,6 +21,11 @@ void NavigateAction::InternalProcessAction(ActionDelegate* delegate, ProcessActionCallback callback) { + // We know to expect navigation to happen, since we're about to cause it. This + // allows scripts to put wait_for_navigation just after navigate, if needed, + // without having to add an expect_navigation first. + delegate->ExpectNavigation(); + GURL url(proto_.navigate().url()); delegate->LoadURL(url); UpdateProcessedAction(ACTION_APPLIED);
diff --git a/components/autofill_assistant/browser/actions/set_form_field_value_action.cc b/components/autofill_assistant/browser/actions/set_form_field_value_action.cc index a99b7c7e..67f5208 100644 --- a/components/autofill_assistant/browser/actions/set_form_field_value_action.cc +++ b/components/autofill_assistant/browser/actions/set_form_field_value_action.cc
@@ -69,7 +69,6 @@ const auto& key_field = proto_.set_form_value().value(next); bool simulate_key_presses = proto_.set_form_value().simulate_key_presses(); - int delay_in_millisecond = proto_.set_form_value().delay_in_millisecond(); switch (key_field.keypress_case()) { case SetFormFieldValueProto_KeyPress::kText: if (simulate_key_presses || key_field.text().empty()) { @@ -78,7 +77,6 @@ // to next value after |SetFieldValue| is done. delegate->SetFieldValue( selector, key_field.text(), simulate_key_presses, - delay_in_millisecond, base::BindOnce(&SetFormFieldValueAction::OnSetFieldValue, weak_ptr_factory_.GetWeakPtr(), delegate, std::move(callback), selector, @@ -87,7 +85,6 @@ // Trigger a check for keyboard fallback when |SetFieldValue| is done. delegate->SetFieldValue( selector, key_field.text(), simulate_key_presses, - delay_in_millisecond, base::BindOnce( &SetFormFieldValueAction::OnSetFieldValueAndCheckFallback, weak_ptr_factory_.GetWeakPtr(), delegate, std::move(callback), @@ -101,7 +98,7 @@ // You should use the `keyboard_input' field instead. if (key_field.keycode() < 128) { // US-ASCII delegate->SendKeyboardInput( - selector, {key_field.keycode()}, delay_in_millisecond, + selector, {key_field.keycode()}, base::BindOnce(&SetFormFieldValueAction::OnSetFieldValue, weak_ptr_factory_.GetWeakPtr(), delegate, std::move(callback), selector, @@ -118,7 +115,6 @@ case SetFormFieldValueProto_KeyPress::kKeyboardInput: delegate->SendKeyboardInput( selector, UTF8ToUnicode(key_field.keyboard_input()), - delay_in_millisecond, base::BindOnce(&SetFormFieldValueAction::OnSetFieldValue, weak_ptr_factory_.GetWeakPtr(), delegate, std::move(callback), selector, @@ -175,7 +171,6 @@ // afterwards. delegate->SetFieldValue( selector, key_field.text(), /*simulate_key_presses = */ true, - proto_.set_form_value().delay_in_millisecond(), base::BindOnce(&SetFormFieldValueAction::OnSetFieldValue, weak_ptr_factory_.GetWeakPtr(), delegate, std::move(callback), selector,
diff --git a/components/autofill_assistant/browser/actions/wait_for_navigation_action.cc b/components/autofill_assistant/browser/actions/wait_for_navigation_action.cc new file mode 100644 index 0000000..23cf323 --- /dev/null +++ b/components/autofill_assistant/browser/actions/wait_for_navigation_action.cc
@@ -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. + +#include "components/autofill_assistant/browser/actions/wait_for_navigation_action.h" + +#include <utility> + +#include "base/callback.h" +#include "components/autofill_assistant/browser/actions/action_delegate.h" + +namespace autofill_assistant { + +WaitForNavigationAction::WaitForNavigationAction(const ActionProto& proto) + : Action(proto), weak_ptr_factory_(this) { + DCHECK(proto_.has_wait_for_navigation()); +} + +WaitForNavigationAction::~WaitForNavigationAction() {} + +void WaitForNavigationAction::InternalProcessAction( + ActionDelegate* delegate, + ProcessActionCallback callback) { + callback_ = std::move(callback); + base::TimeDelta timeout = base::TimeDelta::FromMilliseconds( + proto_.wait_for_navigation().timeout_ms()); + if (timeout.is_zero()) + timeout = kDefaultTimeout; + + timer_.Start(FROM_HERE, timeout, + base::BindOnce(&WaitForNavigationAction::OnTimeout, + weak_ptr_factory_.GetWeakPtr(), + base::Unretained(delegate))); + if (!delegate->WaitForNavigation( + base::BindOnce(&WaitForNavigationAction::OnWaitForNavigation, + weak_ptr_factory_.GetWeakPtr()))) { + DVLOG(1) << __func__ + << ": WaitForNavigation with no corresponding ExpectNavigation or " + "Navigate"; + SendResult(INVALID_ACTION); + return; + } +} + +void WaitForNavigationAction::OnWaitForNavigation(bool success) { + if (!callback_) { + // Already timed out. + return; + } + + SendResult(success ? ACTION_APPLIED : NAVIGATION_ERROR); +} + +void WaitForNavigationAction::OnTimeout(ActionDelegate* delegate) { + if (!callback_) { + // Navigation has ended before. + return; + } + + if (delegate->ExpectedNavigationHasStarted()) { + // Navigation has started. Wait for it to end and to be reported to + // OnWaitForNavigation. + return; + } + SendResult(TIMED_OUT); +} + +void WaitForNavigationAction::SendResult(ProcessedActionStatusProto status) { + timer_.Stop(); + UpdateProcessedAction(status); + std::move(callback_).Run(std::move(processed_action_proto_)); +} + +} // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/actions/wait_for_navigation_action.h b/components/autofill_assistant/browser/actions/wait_for_navigation_action.h new file mode 100644 index 0000000..18e7d679 --- /dev/null +++ b/components/autofill_assistant/browser/actions/wait_for_navigation_action.h
@@ -0,0 +1,43 @@ +// 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 COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_WAIT_FOR_NAVIGATION_ACTION_H_ +#define COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_WAIT_FOR_NAVIGATION_ACTION_H_ + +#include <string> + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/time/time.h" +#include "base/timer/timer.h" +#include "components/autofill_assistant/browser/actions/action.h" + +namespace autofill_assistant { + +class WaitForNavigationAction : public Action { + public: + explicit WaitForNavigationAction(const ActionProto& proto); + ~WaitForNavigationAction() override; + + private: + static constexpr base::TimeDelta kDefaultTimeout = + base::TimeDelta::FromSeconds(20); + + // Overrides Action: + void InternalProcessAction(ActionDelegate* delegate, + ProcessActionCallback callback) override; + + void OnWaitForNavigation(bool has_navigation_error); + void OnTimeout(ActionDelegate* delegate); + void SendResult(ProcessedActionStatusProto status); + + ProcessActionCallback callback_; + base::OneShotTimer timer_; + base::WeakPtrFactory<WaitForNavigationAction> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(WaitForNavigationAction); +}; + +} // namespace autofill_assistant +#endif // COMPONENTS_AUTOFILL_ASSISTANT_BROWSER_ACTIONS_WAIT_FOR_NAVIGATION_ACTION_H_
diff --git a/components/autofill_assistant/browser/controller_unittest.cc b/components/autofill_assistant/browser/controller_unittest.cc index b319607..df4fa2b 100644 --- a/components/autofill_assistant/browser/controller_unittest.cc +++ b/components/autofill_assistant/browser/controller_unittest.cc
@@ -42,6 +42,7 @@ using ::testing::Pointee; using ::testing::Return; using ::testing::ReturnRef; +using ::testing::SaveArg; using ::testing::Sequence; using ::testing::SizeIs; using ::testing::StrEq; @@ -136,14 +137,21 @@ run_once->set_status(SCRIPT_STATUS_NOT_RUN); } - void SetupScriptsForURL(const std::string& url, - SupportsScriptResponseProto scripts) { + void SetupScripts(SupportsScriptResponseProto scripts) { std::string scripts_str; scripts.SerializeToString(&scripts_str); - EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(Eq(GURL(url)), _, _)) + EXPECT_CALL(*mock_service_, OnGetScriptsForUrl(_, _, _)) .WillOnce(RunOnceCallback<2>(true, scripts_str)); } + void SetupActionsForScript(const std::string& path, + ActionsResponseProto actions_response) { + std::string actions_response_str; + actions_response.SerializeToString(&actions_response_str); + EXPECT_CALL(*mock_service_, OnGetActions(StrEq("script"), _, _, _, _, _)) + .WillOnce(RunOnceCallback<5>(true, actions_response_str)); + } + void Start() { Start("http://initialurl.com"); } void Start(const std::string& url) { @@ -851,4 +859,79 @@ EXPECT_THAT(listener.events, IsEmpty()); } +TEST_F(ControllerTest, WaitForNavigationActionTimesOut) { + // A single script, with a wait_for_navigation action + SupportsScriptResponseProto script_response; + AddRunnableScript(&script_response, "script"); + SetupScripts(script_response); + + ActionsResponseProto actions_response; + actions_response.add_actions()->mutable_expect_navigation(); + auto* action = actions_response.add_actions()->mutable_wait_for_navigation(); + action->set_timeout_ms(1000); + SetupActionsForScript("script", actions_response); + + std::vector<ProcessedActionProto> processed_actions_capture; + EXPECT_CALL(*mock_service_, OnGetNextActions(_, _, _, _, _)) + .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), + RunOnceCallback<4>(true, ""))); + + Start("http://a.example.com/path"); + EXPECT_THAT(controller_->GetSuggestions(), SizeIs(1)); + + // Start script, which waits for some navigation event to happen after the + // expect_navigation action has run.. + controller_->SelectSuggestion(0); + + // No navigation event happened within the action timeout and the script ends. + EXPECT_THAT(processed_actions_capture, SizeIs(0)); + thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(1)); + + ASSERT_THAT(processed_actions_capture, SizeIs(2)); + EXPECT_EQ(ACTION_APPLIED, processed_actions_capture[0].status()); + EXPECT_EQ(TIMED_OUT, processed_actions_capture[1].status()); +} + +TEST_F(ControllerTest, WaitForNavigationActionStartWithinTimeout) { + // A single script, with a wait_for_navigation action + SupportsScriptResponseProto script_response; + AddRunnableScript(&script_response, "script"); + SetupScripts(script_response); + + ActionsResponseProto actions_response; + actions_response.add_actions()->mutable_expect_navigation(); + auto* action = actions_response.add_actions()->mutable_wait_for_navigation(); + action->set_timeout_ms(1000); + SetupActionsForScript("script", actions_response); + + std::vector<ProcessedActionProto> processed_actions_capture; + EXPECT_CALL(*mock_service_, OnGetNextActions(_, _, _, _, _)) + .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), + RunOnceCallback<4>(true, ""))); + + Start("http://a.example.com/path"); + EXPECT_THAT(controller_->GetSuggestions(), SizeIs(1)); + + // Start script, which waits for some navigation event to happen after the + // expect_navigation action has run.. + controller_->SelectSuggestion(0); + + // Navigation starts, but does not end, within the timeout. + EXPECT_THAT(processed_actions_capture, SizeIs(0)); + std::unique_ptr<content::NavigationSimulator> simulator = + content::NavigationSimulator::CreateRendererInitiated( + GURL("http://a.example.com/path"), web_contents()->GetMainFrame()); + simulator->SetTransition(ui::PAGE_TRANSITION_LINK); + simulator->Start(); + thread_bundle()->FastForwardBy(base::TimeDelta::FromSeconds(1)); + + // Navigation finishes and the script ends. + EXPECT_THAT(processed_actions_capture, SizeIs(0)); + simulator->Commit(); + + ASSERT_THAT(processed_actions_capture, SizeIs(2)); + EXPECT_EQ(ACTION_APPLIED, processed_actions_capture[0].status()); + EXPECT_EQ(ACTION_APPLIED, processed_actions_capture[1].status()); +} + } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/fake_script_executor_delegate.cc b/components/autofill_assistant/browser/fake_script_executor_delegate.cc index 74d4070..ea56a97 100644 --- a/components/autofill_assistant/browser/fake_script_executor_delegate.cc +++ b/components/autofill_assistant/browser/fake_script_executor_delegate.cc
@@ -100,5 +100,4 @@ void FakeScriptExecutorDelegate::RemoveListener(Listener* listener) { listeners_.erase(listener); } - } // namespace autofill_assistant
diff --git a/components/autofill_assistant/browser/protocol_utils.cc b/components/autofill_assistant/browser/protocol_utils.cc index 2860d9f..c44c78f 100644 --- a/components/autofill_assistant/browser/protocol_utils.cc +++ b/components/autofill_assistant/browser/protocol_utils.cc
@@ -10,6 +10,7 @@ #include "base/logging.h" #include "components/autofill_assistant/browser/actions/autofill_action.h" #include "components/autofill_assistant/browser/actions/click_action.h" +#include "components/autofill_assistant/browser/actions/expect_navigation_action.h" #include "components/autofill_assistant/browser/actions/focus_element_action.h" #include "components/autofill_assistant/browser/actions/get_payment_information_action.h" #include "components/autofill_assistant/browser/actions/highlight_element_action.h" @@ -27,6 +28,7 @@ #include "components/autofill_assistant/browser/actions/unsupported_action.h" #include "components/autofill_assistant/browser/actions/upload_dom_action.h" #include "components/autofill_assistant/browser/actions/wait_for_dom_action.h" +#include "components/autofill_assistant/browser/actions/wait_for_navigation_action.h" #include "components/autofill_assistant/browser/service.pb.h" #include "url/gurl.h" @@ -260,6 +262,14 @@ client_action = std::make_unique<ShowInfoBoxAction>(action); break; } + case ActionProto::ActionInfoCase::kExpectNavigation: { + client_action = std::make_unique<ExpectNavigationAction>(action); + break; + } + case ActionProto::ActionInfoCase::kWaitForNavigation: { + client_action = std::make_unique<WaitForNavigationAction>(action); + break; + } case ActionProto::ActionInfoCase::ACTION_INFO_NOT_SET: { DVLOG(1) << "Encountered action with ACTION_INFO_NOT_SET"; client_action = std::make_unique<UnsupportedAction>(action);
diff --git a/components/autofill_assistant/browser/script_executor.cc b/components/autofill_assistant/browser/script_executor.cc index fe5fb5f..0322217 100644 --- a/components/autofill_assistant/browser/script_executor.cc +++ b/components/autofill_assistant/browser/script_executor.cc
@@ -120,14 +120,41 @@ } void ScriptExecutor::OnNavigationStateChanged() { - if (delegate_->IsNavigatingToNewDocument()) + if (delegate_->IsNavigatingToNewDocument()) { navigation_info_.set_started(true); - else + navigation_info_.set_unexpected(expected_navigation_step_ != + ExpectedNavigationStep::EXPECTED); + } else { navigation_info_.set_ended(true); + } if (delegate_->HasNavigationError()) { navigation_info_.set_has_error(true); } + + switch (expected_navigation_step_) { + case ExpectedNavigationStep::UNEXPECTED: + break; + + case ExpectedNavigationStep::EXPECTED: + if (delegate_->IsNavigatingToNewDocument()) { + expected_navigation_step_ = ExpectedNavigationStep::STARTED; + } + break; + + case ExpectedNavigationStep::STARTED: + if (!delegate_->IsNavigatingToNewDocument()) { + expected_navigation_step_ = ExpectedNavigationStep::DONE; + if (on_expected_navigation_done_) + std::move(on_expected_navigation_done_) + .Run(!delegate_->HasNavigationError()); + } + break; + + case ExpectedNavigationStep::DONE: + // nothing to do + break; + } } void ScriptExecutor::RunElementChecks(BatchElementChecker* checker, @@ -322,11 +349,9 @@ const Selector& selector, const std::string& value, bool simulate_key_presses, - int key_press_delay_in_millisecond, base::OnceCallback<void(const ClientStatus&)> callback) { delegate_->GetWebController()->SetFieldValue( - selector, value, simulate_key_presses, key_press_delay_in_millisecond, - std::move(callback)); + selector, value, simulate_key_presses, std::move(callback)); } void ScriptExecutor::SetAttribute( @@ -341,11 +366,9 @@ void ScriptExecutor::SendKeyboardInput( const Selector& selector, const std::vector<UChar32>& codepoints, - int key_press_delay_in_millisecond, base::OnceCallback<void(const ClientStatus&)> callback) { - delegate_->GetWebController()->SendKeyboardInput( - selector, codepoints, key_press_delay_in_millisecond, - std::move(callback)); + delegate_->GetWebController()->SendKeyboardInput(selector, codepoints, + std::move(callback)); } void ScriptExecutor::GetOuterHtml( @@ -355,6 +378,34 @@ delegate_->GetWebController()->GetOuterHtml(selector, std::move(callback)); } +void ScriptExecutor::ExpectNavigation() { + expected_navigation_step_ = ExpectedNavigationStep::EXPECTED; +} + +bool ScriptExecutor::ExpectedNavigationHasStarted() { + return expected_navigation_step_ != ExpectedNavigationStep::EXPECTED; +} + +bool ScriptExecutor::WaitForNavigation( + base::OnceCallback<void(bool)> callback) { + switch (expected_navigation_step_) { + case ExpectedNavigationStep::UNEXPECTED: + return false; + + case ExpectedNavigationStep::DONE: + std::move(callback).Run(!delegate_->HasNavigationError()); + break; + + case ExpectedNavigationStep::EXPECTED: + case ExpectedNavigationStep::STARTED: + on_expected_navigation_done_ = std::move(callback); + break; + + // No default to make compilation fail if not all cases are covered + } + return true; +} + void ScriptExecutor::LoadURL(const GURL& url) { delegate_->GetWebController()->LoadURL(url); }
diff --git a/components/autofill_assistant/browser/script_executor.h b/components/autofill_assistant/browser/script_executor.h index b11c910b..7aa8813d 100644 --- a/components/autofill_assistant/browser/script_executor.h +++ b/components/autofill_assistant/browser/script_executor.h
@@ -144,7 +144,6 @@ const Selector& selector, const std::string& value, bool simulate_key_presses, - int key_press_delay_in_millisecond, base::OnceCallback<void(const ClientStatus&)> callback) override; void SetAttribute( const Selector& selector, @@ -154,12 +153,14 @@ void SendKeyboardInput( const Selector& selector, const std::vector<UChar32>& codepoints, - int key_press_delay_in_millisecond, base::OnceCallback<void(const ClientStatus&)> callback) override; void GetOuterHtml( const Selector& selector, base::OnceCallback<void(const ClientStatus&, const std::string&)> callback) override; + void ExpectNavigation() override; + bool ExpectedNavigationHasStarted() override; + bool WaitForNavigation(base::OnceCallback<void(bool)> callback) override; void LoadURL(const GURL& url) override; void Shutdown() override; void Close() override; @@ -334,6 +335,24 @@ std::unique_ptr<WaitForDomOperation> wait_for_dom_; + // Steps towards the requirements for calling |on_expected_navigation_done_| + // to be fulfilled. + enum class ExpectedNavigationStep { + // No navigation is expected. + UNEXPECTED = 0, + // Navigation start is expected. + EXPECTED, + // Navigation has started, end is expected. + STARTED, + // Expected navigation has ended. + DONE + }; + ExpectedNavigationStep expected_navigation_step_ = + ExpectedNavigationStep::UNEXPECTED; + + // Callback called the next time |expected_navigation_step_| becomes DONE. + base::OnceCallback<void(bool)> on_expected_navigation_done_; + // Callback set by Prompt(). This is called when the prompt is terminated // without selecting any chips. nullptr unless showing a prompt. base::OnceCallback<void()> on_terminate_prompt_;
diff --git a/components/autofill_assistant/browser/script_executor_unittest.cc b/components/autofill_assistant/browser/script_executor_unittest.cc index 69c9d8b..57239a6a 100644 --- a/components/autofill_assistant/browser/script_executor_unittest.cc +++ b/components/autofill_assistant/browser/script_executor_unittest.cc
@@ -1159,7 +1159,7 @@ EXPECT_TRUE(processed_actions_capture[0].navigation_info().ended()); } -TEST_F(ScriptExecutorTest, ReportNavigationStart) { +TEST_F(ScriptExecutorTest, ReportUnexpectedNavigationStart) { ActionsResponseProto actions_response; auto* wait_for_dom = actions_response.add_actions()->mutable_wait_for_dom(); wait_for_dom->mutable_wait_until()->add_selectors("element"); @@ -1189,6 +1189,169 @@ ASSERT_THAT(processed_actions_capture, SizeIs(1)); EXPECT_EQ(ACTION_APPLIED, processed_actions_capture[0].status()); EXPECT_TRUE(processed_actions_capture[0].navigation_info().started()); + EXPECT_TRUE(processed_actions_capture[0].navigation_info().unexpected()); +} + +TEST_F(ScriptExecutorTest, ReportExpectedNavigationStart) { + ActionsResponseProto actions_response; + actions_response.add_actions()->mutable_expect_navigation(); + auto* wait_for_dom = actions_response.add_actions()->mutable_wait_for_dom(); + wait_for_dom->mutable_wait_until()->add_selectors("element"); + + EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) + .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + std::vector<ProcessedActionProto> processed_actions_capture; + EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _)) + .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), + RunOnceCallback<4>(true, ""))); + + // As the element doesn't exist, WaitForDom returns and waits for 1s. + EXPECT_CALL(mock_web_controller_, + OnElementCheck(Eq(Selector({"element"})), _)) + .WillOnce(RunOnceCallback<1>(false)); + EXPECT_CALL(executor_callback_, Run(_)); + executor_->Run(executor_callback_.Get()); + + delegate_.UpdateNavigationState(/* navigating= */ true, /* error= */ false); + + // Navigation end forces a re-check, which succeeds + EXPECT_CALL(mock_web_controller_, + OnElementCheck(Eq(Selector({"element"})), _)) + .WillRepeatedly(RunOnceCallback<1>(true)); + delegate_.UpdateNavigationState(/* navigating= */ false, /* error= */ false); + + ASSERT_THAT(processed_actions_capture, SizeIs(2)); + EXPECT_EQ(ACTION_APPLIED, processed_actions_capture[0].status()); + EXPECT_EQ(ACTION_APPLIED, processed_actions_capture[0].status()); + EXPECT_TRUE(processed_actions_capture[1].navigation_info().started()); + EXPECT_FALSE(processed_actions_capture[1].navigation_info().unexpected()); +} + +TEST_F(ScriptExecutorTest, WaitForNavigationWithoutExpectation) { + ActionsResponseProto actions_response; + actions_response.add_actions()->mutable_wait_for_navigation(); + + EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) + .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + std::vector<ProcessedActionProto> processed_actions_capture; + EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _)) + .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), + RunOnceCallback<4>(true, ""))); + + // WaitForNavigation returns immediately + EXPECT_CALL(executor_callback_, Run(_)); + executor_->Run(executor_callback_.Get()); + + ASSERT_THAT(processed_actions_capture, SizeIs(1)); + EXPECT_EQ(INVALID_ACTION, processed_actions_capture[0].status()); +} + +TEST_F(ScriptExecutorTest, ExpectNavigation) { + ActionsResponseProto actions_response; + actions_response.add_actions()->mutable_expect_navigation(); + actions_response.add_actions()->mutable_wait_for_navigation(); + + EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) + .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + std::vector<ProcessedActionProto> processed_actions_capture; + EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _)) + .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), + RunOnceCallback<4>(true, ""))); + + // WaitForNavigation waits for navigation to start after expect_navigation + EXPECT_CALL(executor_callback_, Run(_)); + executor_->Run(executor_callback_.Get()); + + delegate_.UpdateNavigationState(/* navigating= */ true, /* error= */ false); + delegate_.UpdateNavigationState(/* navigating= */ false, /* error= */ false); + ASSERT_THAT(processed_actions_capture, SizeIs(2)); + EXPECT_EQ(ACTION_APPLIED, processed_actions_capture[0].status()); + EXPECT_EQ(ACTION_APPLIED, processed_actions_capture[1].status()); +} + +TEST_F(ScriptExecutorTest, MultipleWaitForNavigation) { + ActionsResponseProto actions_response; + actions_response.add_actions()->mutable_expect_navigation(); + actions_response.add_actions()->mutable_wait_for_navigation(); + actions_response.add_actions()->mutable_wait_for_navigation(); + actions_response.add_actions()->mutable_wait_for_navigation(); + + EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) + .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + std::vector<ProcessedActionProto> processed_actions_capture; + EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _)) + .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), + RunOnceCallback<4>(true, ""))); + + // The first wait_for_navigation waits for the navigation to happen. After + // that, the other wait_for_navigation return immediately. + EXPECT_CALL(executor_callback_, Run(_)); + executor_->Run(executor_callback_.Get()); + + delegate_.UpdateNavigationState(/* navigating= */ true, /* error= */ false); + delegate_.UpdateNavigationState(/* navigating= */ false, /* error= */ false); + ASSERT_THAT(processed_actions_capture, SizeIs(4)); + EXPECT_EQ(ACTION_APPLIED, processed_actions_capture[0].status()); + EXPECT_EQ(ACTION_APPLIED, processed_actions_capture[1].status()); + EXPECT_EQ(ACTION_APPLIED, processed_actions_capture[2].status()); + EXPECT_EQ(ACTION_APPLIED, processed_actions_capture[3].status()); +} + +TEST_F(ScriptExecutorTest, ExpectLaterNavigationIgnoringNavigationInProgress) { + ActionsResponseProto actions_response; + actions_response.add_actions()->mutable_expect_navigation(); + actions_response.add_actions()->mutable_wait_for_navigation(); + + EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) + .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + std::vector<ProcessedActionProto> processed_actions_capture; + EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _)) + .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), + RunOnceCallback<4>(true, ""))); + + delegate_.UpdateNavigationState(/* navigating= */ true, /* error= */ false); + + // WaitForNavigation waits for navigation to *start* after expect_navigation + executor_->Run(executor_callback_.Get()); + + // This ends the navigation that was in progress when expect_navigation was + // called. wait_for_navigation should not return, since navigation started + // after expect_navigation was called. + delegate_.UpdateNavigationState(/* navigating= */ false, /* error= */ false); + + // This starts the new navigation. + delegate_.UpdateNavigationState(/* navigating= */ true, /* error= */ false); + + // This ends the new navigation. wait_for_navigation returns. + EXPECT_CALL(executor_callback_, Run(_)); + delegate_.UpdateNavigationState(/* navigating= */ false, /* error= */ false); + + ASSERT_THAT(processed_actions_capture, SizeIs(2)); + EXPECT_EQ(ACTION_APPLIED, processed_actions_capture[0].status()); + EXPECT_EQ(ACTION_APPLIED, processed_actions_capture[1].status()); +} + +TEST_F(ScriptExecutorTest, WaitForNavigationReportsError) { + ActionsResponseProto actions_response; + actions_response.add_actions()->mutable_expect_navigation(); + actions_response.add_actions()->mutable_wait_for_navigation(); + + EXPECT_CALL(mock_service_, OnGetActions(_, _, _, _, _, _)) + .WillOnce(RunOnceCallback<5>(true, Serialize(actions_response))); + std::vector<ProcessedActionProto> processed_actions_capture; + EXPECT_CALL(mock_service_, OnGetNextActions(_, _, _, _, _)) + .WillOnce(DoAll(SaveArg<3>(&processed_actions_capture), + RunOnceCallback<4>(true, ""))); + + // WaitForNavigation waits for navigation to start after expect_navigation + EXPECT_CALL(executor_callback_, Run(_)); + executor_->Run(executor_callback_.Get()); + + delegate_.UpdateNavigationState(/* navigating= */ true, /* error= */ false); + delegate_.UpdateNavigationState(/* navigating= */ false, /* error= */ true); + ASSERT_THAT(processed_actions_capture, SizeIs(2)); + EXPECT_EQ(ACTION_APPLIED, processed_actions_capture[0].status()); + EXPECT_EQ(NAVIGATION_ERROR, processed_actions_capture[1].status()); } } // namespace
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index 62397b9..462bf2d9 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto
@@ -339,6 +339,8 @@ GetPaymentInformationProto get_payment_information = 36; SetAttributeProto set_attribute = 37; ShowInfoBoxProto show_info_box = 39; + ExpectNavigationProto expect_navigation = 40; + WaitForNavigationProto wait_for_navigation = 41; } // Set to true to make the client remove any contextual information if the @@ -403,6 +405,12 @@ // Navigation failed before or during the processing of the current action. optional bool has_error = 3; + + // Unexpected navigation started while processing the current action. This + // will happen during some actions, such as PROMPT action but it should + // normally not happen during scripts that have been updated to use + // expect_navigation. + optional bool unexpected = 4; } // Extra debugging information included in case of unexpected errors. @@ -683,9 +691,6 @@ // Whether we should simulate actual key presses when filling |element| with // its corresponding value. optional bool simulate_key_presses = 3; - - // Delay between two key presses when simlulating. - optional int32 delay_in_millisecond = 4 [default = 20]; } // An optional name to allow to handle multiple addresses selection (for @@ -769,6 +774,31 @@ optional string url = 1; } +// Specify from which point in the script navigation is expected for the next +// call to WaitForNavigation. +message ExpectNavigationProto {} + +// Wait for the browser to have navigated to a new page since the last +// ExpectNavigation or Navigate. This returns as soon as an HTTP response that's +// not a redirect was received for the new page, possibly before even loading +// the page content. +// +// Will return immediately if navigation already happened. +// +// Client errors: +// NAVIGATION_ERROR if navigation failed +// TIMED_OUT if timed out waiting for navigation to start +// INVALID_ACTION no ExpectNavigation or Navigate action was executed in the +// current script. +message WaitForNavigationProto { + // How long to wait for navigation to start before failing with client status + // TIMED_OUT. The action waits 20s by default. + // + // This is usually used to track cases where expected navigation doesn't + // happen, because, for example, a click wasn't registered. + optional int32 timeout_ms = 1; +} + // Allow choosing one or more possibility. If FocusElement was called just // before, allow interaction with the touchable element area, otherwise don't // allow any interactions. @@ -997,9 +1027,6 @@ // Whether to send key press events when setting values to HTML fields. optional bool simulate_key_presses = 5; - - // Delay between two key presses when simlulating. - optional int32 delay_in_millisecond = 6 [default = 20]; } // Set an element attribute to a specific value.
diff --git a/components/autofill_assistant/browser/web_controller.cc b/components/autofill_assistant/browser/web_controller.cc index e89292d..c93c709 100644 --- a/components/autofill_assistant/browser/web_controller.cc +++ b/components/autofill_assistant/browser/web_controller.cc
@@ -1450,7 +1450,6 @@ const Selector& selector, const std::string& value, bool simulate_key_presses, - int key_press_delay_in_millisecond, base::OnceCallback<void(const ClientStatus&)> callback) { DVLOG(3) << __func__ << " " << selector << ", value=" << value << ", simulate_key_presses=" << simulate_key_presses; @@ -1462,8 +1461,7 @@ selector, "", base::BindOnce(&WebController::OnClearFieldForSendKeyboardInput, weak_ptr_factory_.GetWeakPtr(), selector, - UTF8ToUnicode(value), key_press_delay_in_millisecond, - std::move(callback))); + UTF8ToUnicode(value), std::move(callback))); return; } InternalSetFieldValue(selector, value, std::move(callback)); @@ -1483,65 +1481,47 @@ void WebController::OnClearFieldForSendKeyboardInput( const Selector& selector, const std::vector<UChar32>& codepoints, - int key_press_delay_in_millisecond, base::OnceCallback<void(const ClientStatus&)> callback, const ClientStatus& clear_status) { if (!clear_status.ok()) { std::move(callback).Run(clear_status); return; } - SendKeyboardInput(selector, codepoints, key_press_delay_in_millisecond, - std::move(callback)); + SendKeyboardInput(selector, codepoints, std::move(callback)); } void WebController::OnClickElementForSendKeyboardInput( const std::vector<UChar32>& codepoints, - int delay_in_millisecond, base::OnceCallback<void(const ClientStatus&)> callback, const ClientStatus& click_status) { if (!click_status.ok()) { std::move(callback).Run(click_status); return; } - DispatchKeyboardTextDownEvent(codepoints, 0, /*delay=*/false, - delay_in_millisecond, std::move(callback)); + DispatchKeyboardTextDownEvent(codepoints, 0, std::move(callback)); } void WebController::DispatchKeyboardTextDownEvent( const std::vector<UChar32>& codepoints, size_t index, - bool delay, - int delay_in_millisecond, base::OnceCallback<void(const ClientStatus&)> callback) { if (index >= codepoints.size()) { std::move(callback).Run(OkClientStatus()); return; } - if (delay && delay_in_millisecond > 0) { - base::PostDelayedTaskWithTraits( - FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&WebController::DispatchKeyboardTextDownEvent, - weak_ptr_factory_.GetWeakPtr(), codepoints, index, - /*delay=*/false, delay_in_millisecond, - std::move(callback)), - base::TimeDelta::FromMilliseconds(delay_in_millisecond)); - return; - } - devtools_client_->GetInput()->DispatchKeyEvent( CreateKeyEventParamsForCharacter( autofill_assistant::input::DispatchKeyEventType::KEY_DOWN, codepoints[index]), base::BindOnce(&WebController::DispatchKeyboardTextUpEvent, weak_ptr_factory_.GetWeakPtr(), codepoints, index, - delay_in_millisecond, std::move(callback))); + std::move(callback))); } void WebController::DispatchKeyboardTextUpEvent( const std::vector<UChar32>& codepoints, size_t index, - int delay_in_millisecond, base::OnceCallback<void(const ClientStatus&)> callback) { DCHECK_LT(index, codepoints.size()); devtools_client_->GetInput()->DispatchKeyEvent( @@ -1550,7 +1530,6 @@ codepoints[index]), base::BindOnce(&WebController::DispatchKeyboardTextDownEvent, weak_ptr_factory_.GetWeakPtr(), codepoints, index + 1, - /*delay=*/true, delay_in_millisecond, std::move(callback))); } @@ -1672,7 +1651,6 @@ void WebController::SendKeyboardInput( const Selector& selector, const std::vector<UChar32>& codepoints, - const int delay_in_millisecond, base::OnceCallback<void(const ClientStatus&)> callback) { if (VLOG_IS_ON(3)) { std::string input_str; @@ -1683,18 +1661,16 @@ } DCHECK(!selector.empty()); - FindElement( - selector, - /* strict_mode= */ true, - base::BindOnce(&WebController::OnFindElementForSendKeyboardInput, - weak_ptr_factory_.GetWeakPtr(), selector, codepoints, - delay_in_millisecond, std::move(callback))); + FindElement(selector, + /* strict_mode= */ true, + base::BindOnce(&WebController::OnFindElementForSendKeyboardInput, + weak_ptr_factory_.GetWeakPtr(), selector, + codepoints, std::move(callback))); } void WebController::OnFindElementForSendKeyboardInput( const Selector& selector, const std::vector<UChar32>& codepoints, - const int delay_in_millisecond, base::OnceCallback<void(const ClientStatus&)> callback, const ClientStatus& status, std::unique_ptr<FindElementResult> element_result) { @@ -1705,7 +1681,7 @@ ClickElement(selector, base::BindOnce( &WebController::OnClickElementForSendKeyboardInput, weak_ptr_factory_.GetWeakPtr(), codepoints, - delay_in_millisecond, std::move(callback))); + std::move(callback))); } void WebController::GetOuterHtml(
diff --git a/components/autofill_assistant/browser/web_controller.h b/components/autofill_assistant/browser/web_controller.h index e72cb6ea..94ce15dfa 100644 --- a/components/autofill_assistant/browser/web_controller.h +++ b/components/autofill_assistant/browser/web_controller.h
@@ -121,7 +121,6 @@ const Selector& selector, const std::string& value, bool simulate_key_presses, - int key_press_delay_in_millisecond, base::OnceCallback<void(const ClientStatus&)> callback); // Set the |value| of the |attribute| of the element given by |selector|. @@ -132,13 +131,11 @@ base::OnceCallback<void(const ClientStatus&)> callback); // Sets the keyboard focus to |selector| and inputs |codepoints|, one - // character at a time. Key presses will have a delay of |delay_in_milli| - // between them. + // character at a time. // Returns the result through |callback|. virtual void SendKeyboardInput( const Selector& selector, const std::vector<UChar32>& codepoints, - int delay_in_milli, base::OnceCallback<void(const ClientStatus&)> callback); // Return the outerHTML of |selector|. @@ -348,24 +345,19 @@ void OnClearFieldForSendKeyboardInput( const Selector& selector, const std::vector<UChar32>& codepoints, - int key_press_delay_in_millisecond, base::OnceCallback<void(const ClientStatus&)> callback, const ClientStatus& status); void OnClickElementForSendKeyboardInput( const std::vector<UChar32>& codepoints, - int delay_in_milli, base::OnceCallback<void(const ClientStatus&)> callback, const ClientStatus& click_status); void DispatchKeyboardTextDownEvent( const std::vector<UChar32>& codepoints, size_t index, - bool delay, - int delay_in_milli, base::OnceCallback<void(const ClientStatus&)> callback); void DispatchKeyboardTextUpEvent( const std::vector<UChar32>& codepoints, size_t index, - int delay_in_milli, base::OnceCallback<void(const ClientStatus&)> callback); void OnFindElementForSetAttribute( const std::vector<std::string>& attribute, @@ -378,7 +370,6 @@ void OnFindElementForSendKeyboardInput( const Selector& selector, const std::vector<UChar32>& codepoints, - int delay_in_milli, base::OnceCallback<void(const ClientStatus&)> callback, const ClientStatus& status, std::unique_ptr<FindElementResult> element_result);
diff --git a/components/autofill_assistant/browser/web_controller_browsertest.cc b/components/autofill_assistant/browser/web_controller_browsertest.cc index 1dc68f4..67d139f 100644 --- a/components/autofill_assistant/browser/web_controller_browsertest.cc +++ b/components/autofill_assistant/browser/web_controller_browsertest.cc
@@ -298,8 +298,7 @@ } void GetFieldsValue(const std::vector<Selector>& selectors, - const std::vector<std::string>& expected_values, - bool expect_eq) { + const std::vector<std::string>& expected_values) { base::RunLoop run_loop; ASSERT_EQ(selectors.size(), expected_values.size()); size_t pending_number_of_checks = selectors.size(); @@ -308,30 +307,19 @@ selectors[i], base::BindOnce(&WebControllerBrowserTest::OnGetFieldValue, base::Unretained(this), run_loop.QuitClosure(), - &pending_number_of_checks, expected_values[i], - expect_eq)); + &pending_number_of_checks, expected_values[i])); } run_loop.Run(); } - void GetFieldsValue(const std::vector<Selector>& selectors, - const std::vector<std::string>& expected_values) { - GetFieldsValue(selectors, expected_values, true); - } - void OnGetFieldValue(const base::Closure& done_callback, size_t* pending_number_of_checks_output, const std::string& expected_value, - bool expect_eq, bool exists, const std::string& value) { // Don't use ASSERT_EQ here: if the check fails, this would result in // an endless loop without meaningful test results. - if (expect_eq) { - EXPECT_EQ(expected_value, value); - } else { - EXPECT_NE(expected_value, value); - } + EXPECT_EQ(expected_value, value); *pending_number_of_checks_output -= 1; if (*pending_number_of_checks_output == 0) { std::move(done_callback).Run(); @@ -344,7 +332,7 @@ base::RunLoop run_loop; ClientStatus result; web_controller_->SetFieldValue( - selector, value, simulate_key_presses, 0, + selector, value, simulate_key_presses, base::BindOnce(&WebControllerBrowserTest::OnSetFieldValue, base::Unretained(this), run_loop.QuitClosure(), &result)); @@ -360,12 +348,11 @@ } ClientStatus SendKeyboardInput(const Selector& selector, - const std::vector<UChar32>& codepoints, - int delay_in_milli) { + const std::vector<UChar32>& codepoints) { base::RunLoop run_loop; ClientStatus result; web_controller_->SendKeyboardInput( - selector, codepoints, delay_in_milli, + selector, codepoints, base::BindOnce(&WebControllerBrowserTest::OnSendKeyboardInput, base::Unretained(this), run_loop.QuitClosure(), &result)); @@ -373,11 +360,6 @@ return result; } - ClientStatus SendKeyboardInput(const Selector& selector, - const std::vector<UChar32>& codepoints) { - return SendKeyboardInput(selector, codepoints, -1); - } - void OnSendKeyboardInput(const base::Closure& done_callback, ClientStatus* result_output, const ClientStatus& status) { @@ -946,43 +928,6 @@ GetFieldsValue(selectors, {expected_output}); } -IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, - SendKeyboardInputSetsKeyPropertyWithTimeout) { - // Sends input keys to a field where JS will intercept KeyDown and - // at index 3 it will set a timeout whick inserts an space after the - // timeout. If key press delay is enabled, it should handle this - // correctly. - auto input = UTF8ToUnicode("012345"); - std::string expected_output = "012 345"; - - std::vector<Selector> selectors; - Selector a_selector; - a_selector.selectors.emplace_back("#input_js_event_with_timeout"); - selectors.emplace_back(a_selector); - EXPECT_EQ(ACTION_APPLIED, - SendKeyboardInput(a_selector, input, /*delay_in_milli*/ 100) - .proto_status()); - GetFieldsValue(selectors, {expected_output}); -} - -IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, - SendKeyboardInputWithoutDelayFailsWithJSFields) { - // Sends input keys to a field where JS will intercept KeyDown and - // at index 3 it will set a timeout whick inserts an space after the - // timeout. If key press delay is disabled, it should insert one of - // 3/4/5 at insertion point. - auto input = UTF8ToUnicode("012345"); - std::string expected_output = "012 345"; - - std::vector<Selector> selectors; - Selector a_selector; - a_selector.selectors.emplace_back("#input_js_event_with_timeout"); - selectors.emplace_back(a_selector); - EXPECT_EQ(ACTION_APPLIED, - SendKeyboardInput(a_selector, input).proto_status()); - GetFieldsValue(selectors, {expected_output}, /*expect_eq*/ false); -} - IN_PROC_BROWSER_TEST_F(WebControllerBrowserTest, SetAttribute) { Selector selector; std::vector<std::string> attribute;
diff --git a/components/components_strings.grd b/components/components_strings.grd index 71e8f629..2bf0c34 100644 --- a/components/components_strings.grd +++ b/components/components_strings.grd
@@ -363,5 +363,9 @@ Privacy </message> </messages> + <includes> + <!-- This part includes resources that do not require translation or further processing because they are already handled by a separate localization process. --> + <part file="omnibox/resources/omnibox_resources.grdp" /> + </includes> </release> </grit>
diff --git a/components/cronet/native/test/test_upload_data_provider.cc b/components/cronet/native/test/test_upload_data_provider.cc index 590fbc4f..21e910b 100644 --- a/components/cronet/native/test/test_upload_data_provider.cc +++ b/components/cronet/native/test/test_upload_data_provider.cc
@@ -87,6 +87,16 @@ rewind_fail_mode_ = rewind_fail_mode; } +void TestUploadDataProvider::SetReadCancel(int read_cancel_index, + CancelMode read_cancel_mode) { + read_cancel_index_ = read_cancel_index; + read_cancel_mode_ = read_cancel_mode; +} + +void TestUploadDataProvider::SetRewindCancel(CancelMode rewind_cancel_mode) { + rewind_cancel_mode_ = rewind_cancel_mode; +} + int64_t TestUploadDataProvider::GetLength() const { EXPECT_TRUE(!closed_.IsSet()) << "Data Provider is closed"; if (bad_length_ != -1) @@ -114,6 +124,9 @@ AssertIdle(); + if (current_read_call == read_cancel_index_) + MaybeCancelRequest(read_cancel_mode_); + if (MaybeFailRead(current_read_call, upload_data_sink)) { failed_ = true; return; @@ -152,6 +165,8 @@ EXPECT_TRUE(!closed_.IsSet()) << "Data Provider is closed"; AssertIdle(); + MaybeCancelRequest(rewind_cancel_mode_); + if (MaybeFailRewind(upload_data_sink)) { failed_ = true; return; @@ -194,10 +209,10 @@ bool TestUploadDataProvider::MaybeFailRead( int read_index, Cronet_UploadDataSinkPtr upload_data_sink) { - if (read_index != read_fail_index_) - return false; if (read_fail_mode_ == NONE) return false; + if (read_index != read_fail_index_) + return false; if (read_fail_mode_ == CALLBACK_SYNC) { Cronet_UploadDataSink_OnReadError(upload_data_sink, "Sync read failure"); @@ -235,6 +250,25 @@ return true; } +void TestUploadDataProvider::MaybeCancelRequest(CancelMode cancel_mode) { + if (cancel_mode == CANCEL_NONE) + return; + + CHECK(url_request_); + + if (cancel_mode == CANCEL_SYNC) { + Cronet_UrlRequest_Cancel(url_request_); + return; + } + + EXPECT_EQ(cancel_mode, CANCEL_ASYNC); + PostTaskToExecutor(base::BindOnce( + [](Cronet_UrlRequestPtr url_request) { + Cronet_UrlRequest_Cancel(url_request); + }, + url_request_)); +} + void TestUploadDataProvider::Close() { EXPECT_TRUE(!closed_.IsSet()) << "Closed twice"; closed_.Set();
diff --git a/components/cronet/native/test/test_upload_data_provider.h b/components/cronet/native/test/test_upload_data_provider.h index 4d8693b..6f93e79 100644 --- a/components/cronet/native/test/test_upload_data_provider.h +++ b/components/cronet/native/test/test_upload_data_provider.h
@@ -37,6 +37,10 @@ // invoke callback asynchronously. enum FailMode { NONE, CALLBACK_SYNC, CALLBACK_ASYNC }; + // Indicates whether request should be canceled synchronously before + // the callback or asynchronously after. + enum CancelMode { CANCEL_NONE, CANCEL_SYNC, CANCEL_ASYNC }; + TestUploadDataProvider(SuccessCallbackMode success_callback_mode, Cronet_ExecutorPtr executor); @@ -53,10 +57,18 @@ void SetRewindFailure(FailMode rewind_fail_mode); + void SetReadCancel(int read_cancel_index, CancelMode read_cancel_mode); + + void SetRewindCancel(CancelMode rewind_cancel_mode); + void set_bad_length(int64_t bad_length) { bad_length_ = bad_length; } void set_chunked(bool chunked) { chunked_ = chunked; } + void set_url_request(Cronet_UrlRequestPtr request) { url_request_ = request; } + + Cronet_ExecutorPtr executor() const { return executor_; } + int num_read_calls() const { return num_read_calls_; } int num_rewind_calls() const { return num_rewind_calls_; } @@ -84,6 +96,8 @@ bool MaybeFailRewind(Cronet_UploadDataSinkPtr upload_data_sink); + void MaybeCancelRequest(CancelMode cancel_mode); + void Close(); // Implementation of Cronet_UploadDataProvider methods. @@ -101,6 +115,8 @@ const SuccessCallbackMode success_callback_mode_ = SYNC; const Cronet_ExecutorPtr executor_; + Cronet_UrlRequestPtr url_request_; + bool chunked_ = false; // Index of read to fail on. @@ -108,6 +124,13 @@ // Indicates how to fail on a read. FailMode read_fail_mode_ = NONE; FailMode rewind_fail_mode_ = NONE; + + // Index of read to cancel on. + int read_cancel_index_ = -1; + // Indicates how to cancel on a read. + CancelMode read_cancel_mode_ = CANCEL_NONE; + CancelMode rewind_cancel_mode_ = CANCEL_NONE; + // Report bad length if not set to -1. int64_t bad_length_ = -1;
diff --git a/components/cronet/native/test/url_request_test.cc b/components/cronet/native/test/url_request_test.cc index 7167839..56e0b08 100644 --- a/components/cronet/native/test/url_request_test.cc +++ b/components/cronet/native/test/url_request_test.cc
@@ -120,10 +120,13 @@ // Add upload data provider and set content type required for upload. if (test_upload_data_provider != nullptr) { + test_upload_data_provider->set_url_request(request); upload_data_provider = test_upload_data_provider->CreateUploadDataProvider(); Cronet_UrlRequestParams_upload_data_provider_set(request_params, upload_data_provider); + Cronet_UrlRequestParams_upload_data_provider_executor_set( + request_params, test_upload_data_provider->executor()); Cronet_HttpHeaderPtr header = Cronet_HttpHeader_Create(); Cronet_HttpHeader_name_set(header, "Content-Type"); Cronet_HttpHeader_value_set(header, "Useless/string"); @@ -741,6 +744,78 @@ EXPECT_TRUE(callback->on_error_called_); } +TEST_P(UrlRequestTest, UploadCancelReadSync) { + auto callback = std::make_unique<TestUrlRequestCallback>(GetParam()); + const std::string url = cronet::TestServer::GetEchoRequestBodyURL(); + TestUploadDataProvider data_provider(TestUploadDataProvider::ASYNC, + callback->GetExecutor()); + data_provider.AddRead("One"); + data_provider.AddRead("Two"); + data_provider.AddRead("Three"); + data_provider.SetReadCancel(1, TestUploadDataProvider::CANCEL_SYNC); + data_provider.SetReadFailure(1, TestUploadDataProvider::CALLBACK_ASYNC); + + callback = StartAndWaitForComplete(url, std::move(callback), std::string(), + &data_provider); + data_provider.AssertClosed(); + + EXPECT_EQ(11, data_provider.GetUploadedLength()); + EXPECT_EQ(2, data_provider.num_read_calls()); + EXPECT_TRUE(callback->on_canceled_called_); +} + +TEST_P(UrlRequestTest, UploadCancelReadAsync) { + auto callback = std::make_unique<TestUrlRequestCallback>(GetParam()); + const std::string url = cronet::TestServer::GetEchoRequestBodyURL(); + TestUploadDataProvider data_provider(TestUploadDataProvider::ASYNC, + callback->GetExecutor()); + data_provider.AddRead("One"); + data_provider.AddRead("Two"); + data_provider.AddRead("Three"); + data_provider.SetReadCancel(2, TestUploadDataProvider::CANCEL_ASYNC); + + callback = StartAndWaitForComplete(url, std::move(callback), std::string(), + &data_provider); + data_provider.AssertClosed(); + + EXPECT_EQ(11, data_provider.GetUploadedLength()); + EXPECT_EQ(3, data_provider.num_read_calls()); + EXPECT_TRUE(callback->on_canceled_called_); +} + +TEST_P(UrlRequestTest, UploadCancelRewindSync) { + auto callback = std::make_unique<TestUrlRequestCallback>(GetParam()); + const std::string url = cronet::TestServer::GetRedirectToEchoBodyURL(); + TestUploadDataProvider data_provider(TestUploadDataProvider::ASYNC, + callback->GetExecutor()); + data_provider.SetRewindCancel(TestUploadDataProvider::CANCEL_SYNC); + data_provider.SetRewindFailure(TestUploadDataProvider::CALLBACK_ASYNC); + data_provider.AddRead("Test"); + callback = StartAndWaitForComplete(url, std::move(callback), std::string(), + &data_provider); + data_provider.AssertClosed(); + EXPECT_EQ(4, data_provider.GetUploadedLength()); + EXPECT_EQ(1, data_provider.num_read_calls()); + EXPECT_EQ(1, data_provider.num_rewind_calls()); + EXPECT_TRUE(callback->on_canceled_called_); +} + +TEST_P(UrlRequestTest, UploadCancelRewindAsync) { + auto callback = std::make_unique<TestUrlRequestCallback>(GetParam()); + const std::string url = cronet::TestServer::GetRedirectToEchoBodyURL(); + TestUploadDataProvider data_provider(TestUploadDataProvider::ASYNC, + callback->GetExecutor()); + data_provider.SetRewindCancel(TestUploadDataProvider::CANCEL_ASYNC); + data_provider.AddRead("Test"); + callback = StartAndWaitForComplete(url, std::move(callback), std::string(), + &data_provider); + data_provider.AssertClosed(); + EXPECT_EQ(4, data_provider.GetUploadedLength()); + EXPECT_EQ(1, data_provider.num_read_calls()); + EXPECT_EQ(1, data_provider.num_rewind_calls()); + EXPECT_TRUE(callback->on_canceled_called_); +} + TEST_P(UrlRequestTest, SimpleRequest) { Cronet_EnginePtr engine = cronet::test::CreateTestEngine(0); Cronet_UrlRequestPtr request = Cronet_UrlRequest_Create();
diff --git a/components/domain_reliability/quic_error_mapping.cc b/components/domain_reliability/quic_error_mapping.cc index 7ac1bfc5..b52e30b 100644 --- a/components/domain_reliability/quic_error_mapping.cc +++ b/components/domain_reliability/quic_error_mapping.cc
@@ -265,9 +265,6 @@ {quic::QUIC_DECOMPRESSION_FAILURE, "quic.decompression_failure"}, // Receive a RST_STREAM with offset larger than kMaxStreamLength. {quic::QUIC_STREAM_LENGTH_OVERFLOW, "quic.stream_length_overflow"}, - // APPLICATION_CLOSE frame data is malformed. - {quic::QUIC_INVALID_APPLICATION_CLOSE_DATA, - "quic.invalid.application_close_data"}, // Received a MAX DATA frame with errors. {quic::QUIC_INVALID_MAX_DATA_FRAME_DATA, "quic.invalid.max_data_frame_data"}, @@ -306,6 +303,11 @@ {quic::QUIC_HTTP_DECODER_ERROR, "quic.http.decoder.error"}, {quic::QUIC_STALE_CONNECTION_CANCELLED, "quic.stale.connection.cancelled"}, {quic::QUIC_IETF_GQUIC_ERROR_MISSING, "quic.ietf.gquic.error_missing"}, + // QUIC_INVALID_APPLICATION_CLOSE_DATA was code 101. The code has been + // deprecated, but to keep the assert below happy, there needs to be + // an entry for it, but the symbol is gone. + {static_cast<quic::QuicErrorCode>(101), + "quic.invalid.application_close_data"}, // No error. Used as bound while iterating. {quic::QUIC_LAST_ERROR, "quic.last_error"}};
diff --git a/components/gwp_asan/client/gwp_asan.cc b/components/gwp_asan/client/gwp_asan.cc index aefd656..69084aa 100644 --- a/components/gwp_asan/client/gwp_asan.cc +++ b/components/gwp_asan/client/gwp_asan.cc
@@ -5,6 +5,7 @@ #include "components/gwp_asan/client/gwp_asan.h" #include <algorithm> +#include <cmath> #include <limits> #include "base/debug/crash_logging.h" @@ -35,7 +36,8 @@ constexpr int kDefaultTotalPages = kDefaultMaxMetadata * 2; #endif -constexpr int kDefaultAllocationSamplingFrequency = 1000; +constexpr int kDefaultAllocationSamplingMultiplier = 1000; +constexpr int kDefaultAllocationSamplingRange = 64; constexpr double kDefaultProcessSamplingProbability = 0.2; constexpr int kDefaultProcessSamplingBoost = 4; @@ -50,9 +52,15 @@ const base::FeatureParam<int> kTotalPagesParam{&kGwpAsan, "TotalPages", kDefaultTotalPages}; -const base::FeatureParam<int> kAllocationSamplingParam{ - &kGwpAsan, "AllocationSamplingFrequency", - kDefaultAllocationSamplingFrequency}; +// The allocation sampling frequency is calculated using the formula: +// multiplier * range**rand +// where rand is a random real number in the range [0,1). +const base::FeatureParam<int> kAllocationSamplingMultiplierParam{ + &kGwpAsan, "AllocationSamplingMultiplier", + kDefaultAllocationSamplingMultiplier}; + +const base::FeatureParam<int> kAllocationSamplingRangeParam{ + &kGwpAsan, "AllocationSamplingRange", kDefaultAllocationSamplingRange}; const base::FeatureParam<double> kProcessSamplingParam{ &kGwpAsan, "ProcessSamplingProbability", @@ -99,6 +107,32 @@ return (base::RandDouble() < process_sampling_probability); } +// Returns the allocation sampling frequency, or 0 on error. +size_t AllocationSamplingFrequency() { + int multiplier = kAllocationSamplingMultiplierParam.Get(); + if (multiplier < 1) { + DLOG(ERROR) << "GWP-ASan AllocationSamplingMultiplier is out-of-range: " + << multiplier; + return 0; + } + + int range = kAllocationSamplingRangeParam.Get(); + if (range < 1) { + DLOG(ERROR) << "GWP-ASan AllocationSamplingRange is out-of-range: " + << range; + return 0; + } + + base::CheckedNumeric<size_t> frequency = multiplier; + frequency *= std::pow(range, base::RandDouble()); + if (!frequency.IsValid()) { + DLOG(ERROR) << "Out-of-range multiply " << multiplier << " " << range; + return 0; + } + + return frequency.ValueOrDie(); +} + bool EnableForMalloc(bool is_canary_dev, bool is_browser_process) { if (!base::FeatureList::IsEnabled(kGwpAsan)) return false; @@ -131,12 +165,9 @@ return false; } - int alloc_sampling_freq = kAllocationSamplingParam.Get(); - if (alloc_sampling_freq < 1) { - DLOG(ERROR) << "GWP-ASan AllocationSamplingFrequency is out-of-range: " - << alloc_sampling_freq; + size_t alloc_sampling_freq = AllocationSamplingFrequency(); + if (!alloc_sampling_freq) return false; - } if (!SampleProcess(is_canary_dev, is_browser_process)) return false;
diff --git a/components/history/core/browser/sync/OWNERS b/components/history/core/browser/sync/OWNERS index 261ab18..ef97383 100644 --- a/components/history/core/browser/sync/OWNERS +++ b/components/history/core/browser/sync/OWNERS
@@ -1 +1,3 @@ file://components/sync/OWNERS + +# COMPONENT: Services>Sync
diff --git a/components/management_strings.grdp b/components/management_strings.grdp index eb247bb..d3dd19d 100644 --- a/components/management_strings.grdp +++ b/components/management_strings.grdp
@@ -19,18 +19,20 @@ Settings </message> - <!-- Subtitle of the page --> + <!-- Subtitles of the Chrome OS version of the management page --> <if expr="chromeos"> <message name="IDS_MANAGEMENT_SUBTITLE_MANAGED" desc="Title of chrome://management page, shows when device is managed by unknown organization"> Your <ph name="DEVICE_NAME">$1<ex>Chromebook</ex></ph> is managed </message> <message name="IDS_MANAGEMENT_SUBTITLE_MANAGED_BY" desc="Title of chrome://management page, shows when device managed by known organization"> - <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> managed by <ph name="ENROLLMENT_DOMAIN">$2<ex>example.com</ex></ph> + Your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> is managed by <ph name="ENROLLMENT_DOMAIN">$2<ex>example.com</ex></ph> </message> <message name="IDS_MANAGEMENT_NOT_MANAGED_SUBTITLE" desc="Message indicating that the device is not managed"> Your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> is not managed </message> </if> + + <!-- Subtitles of the browser version of the management page --> <if expr="not chromeos"> <message name="IDS_MANAGEMENT_SUBTITLE" desc="Title of chrome://management page, which shows the administrator's capabilities in a managed environment"> Your browser is managed @@ -143,6 +145,7 @@ </message> </if> + <!-- Strings related to extension reporting section of the management page --> <message name="IDS_MANAGEMENT_EXTENSION_REPORTING" desc="Title of the force installed extensions section of the page"> Extensions </message> @@ -159,6 +162,7 @@ Permissions </message> + <!-- Strings related to browser reporting section of the management page --> <message name="IDS_MANAGEMENT_BROWSER_REPORTING" desc="Title of the types of browser reporting section of the page"> Browser </message>
diff --git a/components/metrics/call_stack_profile_builder.cc b/components/metrics/call_stack_profile_builder.cc index 3505f118..2adbe53 100644 --- a/components/metrics/call_stack_profile_builder.cc +++ b/components/metrics/call_stack_profile_builder.cc
@@ -200,6 +200,13 @@ std::move(browser_interface)); } +// static +MetadataRecorder& +CallStackProfileBuilder::GetStackSamplingProfilerMetadataRecorder() { + static base::NoDestructor<MetadataRecorder> instance; + return *instance; +} + void CallStackProfileBuilder::PassProfilesToMetricsProvider( SampledProfile sampled_profile) { if (sampled_profile.process() == BROWSER_PROCESS) {
diff --git a/components/metrics/call_stack_profile_builder.h b/components/metrics/call_stack_profile_builder.h index 877944c..23341fc 100644 --- a/components/metrics/call_stack_profile_builder.h +++ b/components/metrics/call_stack_profile_builder.h
@@ -81,6 +81,10 @@ static void SetParentProfileCollectorForChildProcess( metrics::mojom::CallStackProfileCollectorPtr browser_interface); + // Returns the process-global metadata recorder instance used for tracking + // sampling profiler metadata. + static MetadataRecorder& GetStackSamplingProfilerMetadataRecorder(); + protected: // Test seam. virtual void PassProfilesToMetricsProvider(SampledProfile sampled_profile);
diff --git a/components/omnibox/browser/omnibox_pedal_concepts.h b/components/omnibox/browser/omnibox_pedal_concepts.h index cff4d04..e65f241 100644 --- a/components/omnibox/browser/omnibox_pedal_concepts.h +++ b/components/omnibox/browser/omnibox_pedal_concepts.h
@@ -8,7 +8,7 @@ #define COMPONENTS_OMNIBOX_BROWSER_OMNIBOX_PEDAL_CONCEPTS_H_ // The runtime loaded data must match this version exactly. -constexpr int OMNIBOX_PEDAL_CONCEPTS_DATA_VERSION = 14729733; +constexpr int OMNIBOX_PEDAL_CONCEPTS_DATA_VERSION = 14769790; // Unique identifiers for Pedals, used to bind loaded data to implementations. enum class OmniboxPedalId {
diff --git a/components/omnibox/browser/omnibox_pedal_implementations_unittest.cc b/components/omnibox/browser/omnibox_pedal_implementations_unittest.cc index 0b3fa75..777c470 100644 --- a/components/omnibox/browser/omnibox_pedal_implementations_unittest.cc +++ b/components/omnibox/browser/omnibox_pedal_implementations_unittest.cc
@@ -64,7 +64,7 @@ const std::vector<std::vector<const char*>> literal_concept_expressions = { // Note: The lists below are auto-generated from raw synonym group data. - // Clear Browsing Data + // CLEAR_BROWSING_DATA { "browser cache clear", "browser cache delete", @@ -96,11 +96,46 @@ "browser wipe cache", "browser wipe data", "browser wipe history", + "browsing cache clear", + "browsing cache delete", + "browsing cache erase", + "browsing cache remove", + "browsing cache wipe", + "browsing clear cache", + "browsing clear data", + "browsing clear history", + "browsing data clear", + "browsing data delete", + "browsing data erase", + "browsing data remove", + "browsing data wipe", + "browsing delete cache", + "browsing delete data", + "browsing delete history", + "browsing erase cache", + "browsing erase data", + "browsing erase history", + "browsing history clear", + "browsing history delete", + "browsing history erase", + "browsing history remove", + "browsing history wipe", + "browsing remove cache", + "browsing remove data", + "browsing remove history", + "browsing wipe cache", + "browsing wipe data", + "browsing wipe history", "cache browser clear", "cache browser delete", "cache browser erase", "cache browser remove", "cache browser wipe", + "cache browsing clear", + "cache browsing delete", + "cache browsing erase", + "cache browsing remove", + "cache browsing wipe", "cache chrome clear", "cache chrome delete", "cache chrome erase", @@ -108,14 +143,17 @@ "cache chrome wipe", "cache clear", "cache clear browser", + "cache clear browsing", "cache clear chrome", "cache clear google chrome", "cache delete", "cache delete browser", + "cache delete browsing", "cache delete chrome", "cache delete google chrome", "cache erase", "cache erase browser", + "cache erase browsing", "cache erase chrome", "cache erase google chrome", "cache google chrome clear", @@ -125,10 +163,12 @@ "cache google chrome wipe", "cache remove", "cache remove browser", + "cache remove browsing", "cache remove chrome", "cache remove google chrome", "cache wipe", "cache wipe browser", + "cache wipe browsing", "cache wipe chrome", "cache wipe google chrome", "chrome cache clear", @@ -164,8 +204,12 @@ "clear browser cache", "clear browser data", "clear browser history", + "clear browsing cache", + "clear browsing data", + "clear browsing history", "clear cache", "clear cache browser", + "clear cache browsing", "clear cache chrome", "clear cache google chrome", "clear chrome cache", @@ -173,6 +217,7 @@ "clear chrome history", "clear data", "clear data browser", + "clear data browsing", "clear data chrome", "clear data google chrome", "clear google chrome cache", @@ -180,6 +225,7 @@ "clear google chrome history", "clear history", "clear history browser", + "clear history browsing", "clear history chrome", "clear history google chrome", "data browser clear", @@ -187,6 +233,11 @@ "data browser erase", "data browser remove", "data browser wipe", + "data browsing clear", + "data browsing delete", + "data browsing erase", + "data browsing remove", + "data browsing wipe", "data chrome clear", "data chrome delete", "data chrome erase", @@ -194,14 +245,17 @@ "data chrome wipe", "data clear", "data clear browser", + "data clear browsing", "data clear chrome", "data clear google chrome", "data delete", "data delete browser", + "data delete browsing", "data delete chrome", "data delete google chrome", "data erase", "data erase browser", + "data erase browsing", "data erase chrome", "data erase google chrome", "data google chrome clear", @@ -211,17 +265,23 @@ "data google chrome wipe", "data remove", "data remove browser", + "data remove browsing", "data remove chrome", "data remove google chrome", "data wipe", "data wipe browser", + "data wipe browsing", "data wipe chrome", "data wipe google chrome", "delete browser cache", "delete browser data", "delete browser history", + "delete browsing cache", + "delete browsing data", + "delete browsing history", "delete cache", "delete cache browser", + "delete cache browsing", "delete cache chrome", "delete cache google chrome", "delete chrome cache", @@ -229,6 +289,7 @@ "delete chrome history", "delete data", "delete data browser", + "delete data browsing", "delete data chrome", "delete data google chrome", "delete google chrome cache", @@ -236,13 +297,18 @@ "delete google chrome history", "delete history", "delete history browser", + "delete history browsing", "delete history chrome", "delete history google chrome", "erase browser cache", "erase browser data", "erase browser history", + "erase browsing cache", + "erase browsing data", + "erase browsing history", "erase cache", "erase cache browser", + "erase cache browsing", "erase cache chrome", "erase cache google chrome", "erase chrome cache", @@ -250,6 +316,7 @@ "erase chrome history", "erase data", "erase data browser", + "erase data browsing", "erase data chrome", "erase data google chrome", "erase google chrome cache", @@ -257,6 +324,7 @@ "erase google chrome history", "erase history", "erase history browser", + "erase history browsing", "erase history chrome", "erase history google chrome", "google chrome cache clear", @@ -294,6 +362,11 @@ "history browser erase", "history browser remove", "history browser wipe", + "history browsing clear", + "history browsing delete", + "history browsing erase", + "history browsing remove", + "history browsing wipe", "history chrome clear", "history chrome delete", "history chrome erase", @@ -301,14 +374,17 @@ "history chrome wipe", "history clear", "history clear browser", + "history clear browsing", "history clear chrome", "history clear google chrome", "history delete", "history delete browser", + "history delete browsing", "history delete chrome", "history delete google chrome", "history erase", "history erase browser", + "history erase browsing", "history erase chrome", "history erase google chrome", "history google chrome clear", @@ -318,17 +394,23 @@ "history google chrome wipe", "history remove", "history remove browser", + "history remove browsing", "history remove chrome", "history remove google chrome", "history wipe", "history wipe browser", + "history wipe browsing", "history wipe chrome", "history wipe google chrome", "remove browser cache", "remove browser data", "remove browser history", + "remove browsing cache", + "remove browsing data", + "remove browsing history", "remove cache", "remove cache browser", + "remove cache browsing", "remove cache chrome", "remove cache google chrome", "remove chrome cache", @@ -336,6 +418,7 @@ "remove chrome history", "remove data", "remove data browser", + "remove data browsing", "remove data chrome", "remove data google chrome", "remove google chrome cache", @@ -343,13 +426,18 @@ "remove google chrome history", "remove history", "remove history browser", + "remove history browsing", "remove history chrome", "remove history google chrome", "wipe browser cache", "wipe browser data", "wipe browser history", + "wipe browsing cache", + "wipe browsing data", + "wipe browsing history", "wipe cache", "wipe cache browser", + "wipe cache browsing", "wipe cache chrome", "wipe cache google chrome", "wipe chrome cache", @@ -357,6 +445,7 @@ "wipe chrome history", "wipe data", "wipe data browser", + "wipe data browsing", "wipe data chrome", "wipe data google chrome", "wipe google chrome cache", @@ -364,11 +453,12 @@ "wipe google chrome history", "wipe history", "wipe history browser", + "wipe history browsing", "wipe history chrome", "wipe history google chrome", }, - // Change Search Engine + // CHANGE_SEARCH_ENGINE { "browser change default search engine", "browser change search", @@ -692,7 +782,7 @@ "switch standard search engine google chrome", }, - // Manage Passwords + // MANAGE_PASSWORDS { "browser change passwords", "browser manage passwords", @@ -776,7 +866,7 @@ "update passwords google chrome", }, - // Change Home Page + // CHANGE_HOME_PAGE { "browser change home page", "browser change homepage", @@ -900,7 +990,7 @@ "set homepage google chrome", }, - // Update Credit Card + // UPDATE_CREDIT_CARD { "browser card info edit", "browser card info update", @@ -1104,7 +1194,7 @@ "update google chrome credit cards", }, - // Launch Incognito + // LAUNCH_INCOGNITO { "browser enter incognito", "browser enter incognito mode", @@ -1668,7 +1758,7 @@ "start private window google chrome", }, - // Translate + // TRANSLATE { "browser change language page", "browser change language this", @@ -1792,7 +1882,7 @@ "translate this page google chrome", }, - // Update Chrome + // UPDATE_CHROME { "browser install", "browser update",
diff --git a/components/omnibox/browser/omnibox_pedal_provider.cc b/components/omnibox/browser/omnibox_pedal_provider.cc index 59e466ac..2e6916158 100644 --- a/components/omnibox/browser/omnibox_pedal_provider.cc +++ b/components/omnibox/browser/omnibox_pedal_provider.cc
@@ -10,10 +10,10 @@ #include "base/strings/string_tokenizer.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" -#include "components/grit/components_resources.h" #include "components/omnibox/browser/autocomplete_provider_client.h" #include "components/omnibox/browser/omnibox_pedal.h" #include "components/omnibox/browser/omnibox_pedal_implementations.h" +#include "components/strings/grit/components_strings.h" #include "third_party/zlib/google/compression_utils.h" #include "ui/base/resource/resource_bundle.h" @@ -96,9 +96,11 @@ void OmniboxPedalProvider::LoadPedalConcepts() { // Get raw gzipped data, uncompress it, then parse to base::Value for loading. - base::StringPiece compressed_data = - ui::ResourceBundle::GetSharedInstance().GetRawDataResource( + scoped_refptr<base::RefCountedMemory> bytes = + ui::ResourceBundle::GetSharedInstance().LoadLocalizedResourceBytes( IDR_OMNIBOX_PEDAL_CONCEPTS); + DCHECK(bool{bytes}); + base::StringPiece compressed_data(bytes->front_as<char>(), bytes->size()); std::string uncompressed_data; uncompressed_data.resize(compression::GetUncompressedSize(compressed_data)); CHECK(compression::GzipUncompress(compressed_data, uncompressed_data));
diff --git a/components/omnibox/resources/omnibox_pedal_concepts.json b/components/omnibox/resources/omnibox_pedal_concepts.json deleted file mode 100644 index 279038c..0000000 --- a/components/omnibox/resources/omnibox_pedal_concepts.json +++ /dev/null
@@ -1 +0,0 @@ -{"schema":"pedal_concepts_runtime","schema_version":1,"data_version":14729733,"tokenize_characters":" ","dictionary":["a","an","browser","cache","card","cards","change","choose","chrome","clear","credit","data","default","delete","do","edit","engine","enter","erase","for","google","history","home","homepage","how","i","in","incognito","info","inside","install","language","launch","manage","manager","mode","my","on","open","page","passwords","private","remove","search","select","set","standard","start","switch","tab","the","this","to","translate","update","upgrade","window","wipe","within"],"pedals":[{"name":"CLEAR_BROWSING_DATA","id":1,"groups":[{"required":false,"single":true,"synonyms":[[20,8],[2],[8]]},{"required":true,"single":true,"synonyms":[[13],[42],[18],[9],[57]]},{"required":true,"single":true,"synonyms":[[21],[3],[11]]}]},{"name":"CHANGE_SEARCH_ENGINE","id":2,"groups":[{"required":false,"single":true,"synonyms":[[20,8],[2],[8]]},{"required":true,"single":true,"synonyms":[[7],[6],[48],[44]]},{"required":true,"single":true,"synonyms":[[46,43,16],[12,43,16],[43,16],[43]]}]},{"name":"MANAGE_PASSWORDS","id":3,"groups":[{"required":false,"single":true,"synonyms":[[20,8],[2],[8]]},{"required":true,"single":true,"synonyms":[[34],[33],[54],[6]]},{"required":true,"single":true,"synonyms":[[40]]}]},{"name":"CHANGE_HOME_PAGE","id":4,"groups":[{"required":false,"single":true,"synonyms":[[20,8],[2],[8]]},{"required":true,"single":true,"synonyms":[[6],[7],[45]]},{"required":true,"single":true,"synonyms":[[22,39],[23]]}]},{"name":"UPDATE_CREDIT_CARD","id":5,"groups":[{"required":false,"single":true,"synonyms":[[20,8],[2],[8]]},{"required":true,"single":true,"synonyms":[[54],[15]]},{"required":true,"single":true,"synonyms":[[10,4,28],[10,5],[10,4],[4,28],[5]]}]},{"name":"LAUNCH_INCOGNITO","id":6,"groups":[{"required":false,"single":true,"synonyms":[[20,8],[2],[8]]},{"required":true,"single":true,"synonyms":[[32],[47],[17],[38]]},{"required":true,"single":true,"synonyms":[[27,56],[27,35],[41,56],[27,49],[41,35],[41,49],[27]]}]},{"name":"TRANSLATE","id":7,"groups":[{"required":false,"single":true,"synonyms":[[20,8],[2],[8]]},{"required":true,"single":true,"synonyms":[[6,31],[53]]},{"required":true,"single":true,"synonyms":[[51,39],[39],[51]]}]},{"name":"UPDATE_CHROME","id":8,"groups":[{"required":true,"single":true,"synonyms":[[20,8],[2],[8]]},{"required":true,"single":true,"synonyms":[[55],[30],[54]]}]}],"ignore_group":{"required":false,"single":false,"synonyms":[[29],[58],[19],[24],[50],[1],[14],[26],[36],[37],[52],[0],[25]]},"max_tokens":32} \ No newline at end of file
diff --git a/components/omnibox/resources/omnibox_pedal_concepts_de.json b/components/omnibox/resources/omnibox_pedal_concepts_de.json new file mode 100644 index 0000000..2c61205 --- /dev/null +++ b/components/omnibox/resources/omnibox_pedal_concepts_de.json
@@ -0,0 +1 @@ +{"schema":"pedal_concepts_runtime","schema_version":1,"data_version":14769790,"tokenize_characters":" -","dictionary":["aktualisieren","anschauen","anzeigen","arbeiten","aus","bearbeiten","browser","browserdaten","browserverlauf","cache","chrome","daten","den","die","diese","ein","einstellen","einstellungen","entfernen","fenster","google","ich","im","in","inkognito","inkognitofenster","inkognitomodus","installieren","kann","karte","kartendaten","kredit","kreditkarte","kreditkartendaten","leeren","löschen","man","mein","meine","meinem","meinen","mit","modus","passwort","passwörter","privat","privatmodus","sein","seine","seinem","seinen","seite","sprache","standard","standardeinstellung","standardsuche","standardsuchmaschine","start","starten","startseite","suche","sucheinstellung","suchmaschine","suchverlauf","surfen","umstellen","update","upgrade","upgraden","verlauf","verwalten","webseite","website","wechseln","wie","wo","ändern","öffnen","übersetzen"],"pedals":[{"name":"CLEAR_BROWSING_DATA","id":1,"groups":[{"required":false,"single":true,"synonyms":[[20,10],[6],[10]]},{"required":true,"single":true,"synonyms":[[18],[35],[34]]},{"required":true,"single":true,"synonyms":[[8],[7],[63],[69],[9],[11]]}]},{"name":"CHANGE_SEARCH_ENGINE","id":2,"groups":[{"required":false,"single":true,"synonyms":[[20,10],[6],[10],[20]]},{"required":true,"single":true,"synonyms":[[16],[65],[73],[76]]},{"required":true,"single":true,"synonyms":[[54,60],[53,62],[53,62],[56],[17,60],[61],[53,60],[55],[62]]}]},{"name":"MANAGE_PASSWORDS","id":3,"groups":[{"required":false,"single":true,"synonyms":[[20,10],[6],[10]]},{"required":true,"single":true,"synonyms":[[70],[1],[2],[76]]},{"required":true,"single":true,"synonyms":[[44],[43]]}]},{"name":"CHANGE_HOME_PAGE","id":4,"groups":[{"required":false,"single":true,"synonyms":[[20,10],[6],[10]]},{"required":true,"single":true,"synonyms":[[16],[65],[73],[76]]},{"required":true,"single":true,"synonyms":[[57,51],[59]]}]},{"name":"UPDATE_CREDIT_CARD","id":5,"groups":[{"required":false,"single":true,"synonyms":[[20,10],[6],[10]]},{"required":true,"single":true,"synonyms":[[0],[5],[76]]},{"required":true,"single":true,"synonyms":[[33],[31,29],[32],[30]]}]},{"name":"LAUNCH_INCOGNITO","id":6,"groups":[{"required":false,"single":true,"synonyms":[[20,10],[6],[10]]},{"required":true,"single":true,"synonyms":[[3],[58],[77],[64]]},{"required":true,"single":true,"synonyms":[[24,19],[25],[24,42],[26],[45,42],[46],[24],[45]]}]},{"name":"TRANSLATE","id":7,"groups":[{"required":false,"single":true,"synonyms":[[20,10],[6],[10]]},{"required":true,"single":true,"synonyms":[[52,76],[78]]},{"required":true,"single":true,"synonyms":[[14,71],[14,72],[14,51],[71],[72],[51]]},{"required":true,"single":true,"synonyms":[[14]]}]},{"name":"UPDATE_CHROME","id":8,"groups":[{"required":true,"single":true,"synonyms":[[20,10],[6],[10]]},{"required":true,"single":true,"synonyms":[[0],[27],[68],[67],[66]]}]}],"ignore_group":{"required":false,"single":false,"synonyms":[[39],[49],[50],[40],[38],[48],[28],[37],[47],[74],[21],[36],[13],[4],[41],[12],[15],[75],[23],[22]]},"max_tokens":32} \ No newline at end of file
diff --git a/components/omnibox/resources/omnibox_pedal_concepts_en.json b/components/omnibox/resources/omnibox_pedal_concepts_en.json new file mode 100644 index 0000000..21c4e1e --- /dev/null +++ b/components/omnibox/resources/omnibox_pedal_concepts_en.json
@@ -0,0 +1 @@ +{"schema":"pedal_concepts_runtime","schema_version":1,"data_version":14769790,"tokenize_characters":" -","dictionary":["a","an","browser","browsing","cache","card","cards","change","choose","chrome","clear","credit","data","default","delete","do","edit","engine","enter","erase","for","google","history","home","homepage","how","i","in","incognito","info","inside","install","language","launch","manage","manager","mode","my","on","open","page","passwords","private","remove","search","select","set","standard","start","switch","tab","the","this","to","translate","update","upgrade","window","wipe","within"],"pedals":[{"name":"CLEAR_BROWSING_DATA","id":1,"groups":[{"required":false,"single":true,"synonyms":[[21,9],[3],[2],[9]]},{"required":true,"single":true,"synonyms":[[14],[43],[19],[10],[58]]},{"required":true,"single":true,"synonyms":[[22],[4],[12]]}]},{"name":"CHANGE_SEARCH_ENGINE","id":2,"groups":[{"required":false,"single":true,"synonyms":[[21,9],[2],[9]]},{"required":true,"single":true,"synonyms":[[8],[7],[49],[45]]},{"required":true,"single":true,"synonyms":[[47,44,17],[13,44,17],[44,17],[44]]}]},{"name":"MANAGE_PASSWORDS","id":3,"groups":[{"required":false,"single":true,"synonyms":[[21,9],[2],[9]]},{"required":true,"single":true,"synonyms":[[35],[34],[55],[7]]},{"required":true,"single":true,"synonyms":[[41]]}]},{"name":"CHANGE_HOME_PAGE","id":4,"groups":[{"required":false,"single":true,"synonyms":[[21,9],[2],[9]]},{"required":true,"single":true,"synonyms":[[7],[8],[46]]},{"required":true,"single":true,"synonyms":[[23,40],[24]]}]},{"name":"UPDATE_CREDIT_CARD","id":5,"groups":[{"required":false,"single":true,"synonyms":[[21,9],[2],[9]]},{"required":true,"single":true,"synonyms":[[55],[16]]},{"required":true,"single":true,"synonyms":[[11,5,29],[11,6],[11,5],[5,29],[6]]}]},{"name":"LAUNCH_INCOGNITO","id":6,"groups":[{"required":false,"single":true,"synonyms":[[21,9],[2],[9]]},{"required":true,"single":true,"synonyms":[[33],[48],[18],[39]]},{"required":true,"single":true,"synonyms":[[28,57],[28,36],[42,57],[28,50],[42,36],[42,50],[28]]}]},{"name":"TRANSLATE","id":7,"groups":[{"required":false,"single":true,"synonyms":[[21,9],[2],[9]]},{"required":true,"single":true,"synonyms":[[7,32],[54]]},{"required":true,"single":true,"synonyms":[[52,40],[40],[52]]}]},{"name":"UPDATE_CHROME","id":8,"groups":[{"required":true,"single":true,"synonyms":[[21,9],[2],[9]]},{"required":true,"single":true,"synonyms":[[56],[31],[55]]}]}],"ignore_group":{"required":false,"single":false,"synonyms":[[30],[59],[20],[25],[51],[1],[15],[27],[37],[38],[53],[0],[26]]},"max_tokens":32} \ No newline at end of file
diff --git a/components/omnibox/resources/omnibox_pedal_concepts_fr.json b/components/omnibox/resources/omnibox_pedal_concepts_fr.json new file mode 100644 index 0000000..e6e0a0f --- /dev/null +++ b/components/omnibox/resources/omnibox_pedal_concepts_fr.json
@@ -0,0 +1 @@ +{"schema":"pedal_concepts_runtime","schema_version":1,"data_version":14769790,"tokenize_characters":" -","dictionary":["accueil","actualise","actualiser","autre","bancaire","bancaires","cache","carte","cartes","cette","change","changer","choisir","choisis","choisit","chrome","confidentialité","confidentielle","crédit","d'accueil","dans","de","dernière","des","données","défaut","définir","définis","définit","démarre","démarrer","efface","effacer","enlever","enlève","fenetre","fenêtre","gestionnaire","google","gère","gérer","historique","homepage","incognito","informations","infos","installe","installer","jour","la","lance","lancer","langue","le","les","met","mets","mettre","mode","modifie","modifier","mot","moteur","mots","navigateur","navigation","naviguer","niveau","onglet","ouvre","ouvrir","page","paiement","par","passe","passer","privé","privée","recherche","sans","standard","supprime","supprimer","sélectionne","sélectionner","traces","traduire","traduis","traduit","un","une","version","vide","vider","à"],"pedals":[{"name":"CLEAR_BROWSING_DATA","id":1,"groups":[{"required":true,"single":true,"synonyms":[[38,15],[64],[15]]},{"required":true,"single":true,"synonyms":[[82],[81],[32],[33],[34],[31],[93],[92]]},{"required":true,"single":true,"synonyms":[[44],[41],[65],[24],[85],[6],[45]]}]},{"name":"CHANGE_SEARCH_ENGINE","id":2,"groups":[{"required":true,"single":true,"synonyms":[[38,15],[64],[15]]},{"required":true,"single":true,"synonyms":[[84],[83],[2],[1],[60],[12],[11],[13],[14],[59],[75],[10],[74]]},{"required":true,"single":true,"synonyms":[[62,21,78,73,25],[62,21,78,80],[3,62,21,78],[62,21,78],[78]]}]},{"name":"MANAGE_PASSWORDS","id":3,"groups":[{"required":true,"single":true,"synonyms":[[38,15],[64],[15]]},{"required":true,"single":true,"synonyms":[[57,94,48],[37],[56,94,48],[55,94,48],[55,94,48],[2],[1],[60],[11],[59],[40],[10],[39]]},{"required":true,"single":true,"synonyms":[[63,21,74],[61,21,74]]}]},{"name":"CHANGE_HOME_PAGE","id":4,"groups":[{"required":true,"single":true,"synonyms":[[38,15],[64],[15]]},{"required":true,"single":true,"synonyms":[[2],[1],[26],[60],[27],[28],[11],[12],[13],[14],[59]]},{"required":true,"single":true,"synonyms":[[71,19],[71,0],[42]]}]},{"name":"UPDATE_CREDIT_CARD","id":5,"groups":[{"required":true,"single":true,"synonyms":[[38,15],[64],[15]]},{"required":true,"single":true,"synonyms":[[57,94,48],[56,94,48],[55,94,48],[2],[1],[60],[11],[59],[10]]},{"required":true,"single":true,"synonyms":[[45,7,21,18],[44,5],[44,21,7],[8,21,72],[8,21,18],[7,21,72],[58,21,72],[8,5],[45,5],[7,4],[8]]}]},{"name":"LAUNCH_INCOGNITO","id":6,"groups":[{"required":true,"single":true,"synonyms":[[38,15],[64],[15]]},{"required":true,"single":true,"synonyms":[[84],[83],[30],[66],[29],[12],[13],[14],[51],[75],[70],[50],[74],[69]]},{"required":true,"single":true,"synonyms":[[65,17],[36,17],[58,16],[65,77],[36,77],[16],[68,43],[35,77],[58,43],[68,76],[58,76],[79,85],[43]]}]},{"name":"TRANSLATE","id":7,"groups":[{"required":true,"single":true,"synonyms":[[38,15],[64],[15]]},{"required":true,"single":true,"synonyms":[[84,49,52],[83,49,52],[11,52],[10,52],[86],[87],[88]]},{"required":true,"single":true,"synonyms":[[9,71],[9,71],[71]]}]},{"name":"UPDATE_CHROME","id":8,"groups":[{"required":true,"single":true,"synonyms":[[38,15],[64],[15]]},{"required":true,"single":true,"synonyms":[[57,94,67],[57,94,48],[56,94,67],[55,94,67],[56,94,48],[55,94,48],[2],[47],[1],[46]]},{"required":true,"single":true,"synonyms":[[22,91]]}]}],"ignore_group":{"required":false,"single":false,"synonyms":[[20],[90],[23],[54],[89],[21],[53],[49]]},"max_tokens":32} \ No newline at end of file
diff --git a/components/omnibox/resources/omnibox_pedal_concepts_ja.json b/components/omnibox/resources/omnibox_pedal_concepts_ja.json new file mode 100644 index 0000000..a33f880 --- /dev/null +++ b/components/omnibox/resources/omnibox_pedal_concepts_ja.json
@@ -0,0 +1 @@ +{"schema":"pedal_concepts_runtime","schema_version":1,"data_version":14769790,"tokenize_characters":"","dictionary":[" ","c","e","g","h","l","m","o","p","r","い","う","え","お","く","こ","す","で","の","ぶ","や","り","る","れ","を","ア","ィ","イ","ウ","エ","ォ","オ","カ","キ","ク","グ","サ","ザ","シ","ジ","ス","タ","ダ","チ","ッ","デ","ト","ド","パ","フ","ブ","プ","ベ","ペ","ホ","ム","モ","ャ","ュ","ラ","リ","ル","レ","ロ","ワ","ン","ー","仕","使","再","切","削","効","動","去","報","変","始","定","履","情","払","択","支","新","方","既","更","替","有","検","歴","法","消","理","管","索","編","翻","覧","言","設","訳","語","起","選","開","閲","除","集"],"pedals":[{"name":"CLEAR_BROWSING_DATA","id":1,"groups":[{"required":false,"single":true,"synonyms":[[35,66,35,61,34,63,66,55],[50,59,28,39,65,35],[50,59,28,37,66],[3,7,7,3,5,2,0,1,4,9,7,6,2],[50,59,28,37],[34,63,66,55],[1,4,9,7,6,2]]},{"required":true,"single":true,"synonyms":[[34,60,25],[93,16],[71,108],[93,74]]},{"required":true,"single":true,"synonyms":[[33,57,44,38,58],[107,99,79,91],[45,66,41],[79,91]]}]},{"name":"CHANGE_SEARCH_ENGINE","id":2,"groups":[{"required":false,"single":true,"synonyms":[[35,66,35,61,34,63,66,55],[50,59,28,37,66],[3,7,7,3,5,2,0,1,4,9,7,6,2],[50,59,28,37],[34,63,66,55],[1,4,9,7,6,2]]},{"required":true,"single":true,"synonyms":[[70,21,88,12],[76,12,22],[105,82],[76,87],[70,88],[95,94],[101,78]]},{"required":true,"single":true,"synonyms":[[45,49,30,61,46,90,96,29,65,39,65],[86,78,90,96,29,65,39,65],[36,66,43,29,65,39,65],[90,96,29,65,39,65]]}]},{"name":"MANAGE_PASSWORDS","id":3,"groups":[{"required":false,"single":true,"synonyms":[[35,66,35,61,34,63,66,55],[50,59,28,37,66],[3,7,7,3,5,2,0,1,4,9,7,6,2],[50,59,28,37],[34,63,66,55],[1,4,9,7,6,2]]},{"required":true,"single":true,"synonyms":[[25,44,51,45,66,46],[69,101,78],[76,12,22],[95,94],[87,84],[76,87]]},{"required":true,"single":true,"synonyms":[[48,40,64,66,47]]}]},{"name":"CHANGE_HOME_PAGE","id":4,"groups":[{"required":false,"single":true,"synonyms":[[35,66,35,61,34,63,66,55],[50,59,28,37,66],[3,7,7,3,5,2,0,1,4,9,7,6,2],[50,59,28,37],[34,63,66,55],[1,4,9,7,6,2]]},{"required":true,"single":true,"synonyms":[[76,12,22],[76,87],[105,82],[105,19],[101,78]]},{"required":true,"single":true,"synonyms":[[54,66,55,53,66,39],[4,8]]}]},{"name":"UPDATE_CREDIT_CARD","id":5,"groups":[{"required":false,"single":true,"synonyms":[[35,66,35,61,34,63,66,55],[50,59,28,37,66],[3,7,7,3,5,2,0,1,4,9,7,6,2],[50,59,28,37],[34,63,66,55],[1,4,9,7,6,2]]},{"required":true,"single":true,"synonyms":[[25,44,51,45,66,46],[76,12,22],[87,84],[97,109],[76,87]]},{"required":true,"single":true,"synonyms":[[34,62,39,44,46,32,66,47,80,75],[34,62,39,44,46,32,66,47],[13,83,81,10,80,75],[32,66,47,80,75],[83,81,10,80,75],[13,83,81,10],[32,66,47],[83,81,10]]}]},{"name":"LAUNCH_INCOGNITO","id":6,"groups":[{"required":false,"single":true,"synonyms":[[35,66,35,61,34,63,66,55],[50,59,28,37,66],[3,7,7,3,5,2,0,1,4,9,7,6,2],[50,59,28,37],[34,63,66,55],[1,4,9,7,6,2]]},{"required":true,"single":true,"synonyms":[[68,10,85],[104,73],[106,77],[106,14],[31,65],[89,72],[68,11]]},{"required":true,"single":true,"synonyms":[[51,59,27,52,66,46,50,59,28,39,65,35],[38,66,34,62,44,46,28,26,65,47,28],[38,66,34,62,44,46,56,66,47],[51,59,27,52,66,46,56,66,47],[38,66,34,62,44,46,41,50],[51,59,27,52,66,46,41,50],[38,66,34,62,44,46]]}]},{"name":"TRANSLATE","id":7,"groups":[{"required":false,"single":true,"synonyms":[[35,66,35,61,34,63,66,55],[50,59,28,37,66],[3,7,7,3,5,2,0,1,4,9,7,6,2],[50,59,28,37],[34,63,66,55],[1,4,9,7,6,2]]},{"required":true,"single":true,"synonyms":[[100,103,101,78],[100,103,70,88],[100,103,76,87],[98,102]]},{"required":true,"single":true,"synonyms":[[15,18,53,66,39],[53,66,39],[15,23],[15,18]]}]},{"name":"UPDATE_CHROME","id":8,"groups":[{"required":true,"single":true,"synonyms":[[35,66,35,61,34,63,66,55],[50,59,28,37,66],[3,7,7,3,5,2,0,1,4,9,7,6,2],[50,59,28,37],[34,63,66,55],[1,4,9,7,6,2]]},{"required":true,"single":true,"synonyms":[[25,44,51,35,62,66,47],[27,65,40,46,66,61],[25,44,51,45,66,46],[42,28,65,63,66,47],[87,84]]}]}],"ignore_group":{"required":false,"single":false,"synonyms":[[20,21,85],[16,22],[85,92],[67,85],[18],[17],[24]]},"max_tokens":32} \ No newline at end of file
diff --git a/components/omnibox/resources/omnibox_pedal_concepts_zh-CN.json b/components/omnibox/resources/omnibox_pedal_concepts_zh-CN.json new file mode 100644 index 0000000..71b3ed6c --- /dev/null +++ b/components/omnibox/resources/omnibox_pedal_concepts_zh-CN.json
@@ -0,0 +1 @@ +{"schema":"pedal_concepts_runtime","schema_version":1,"data_version":14769790,"tokenize_characters":"","dictionary":[" ","c","e","g","h","l","m","o","r","主","付","信","修","入","内","切","删","动","化","升","卡","历","去","变","口","句","史","启","器","始","存","安","容","密","开","式","引","录","打","换","据","搜","擎","擦","支","改","数","新","无","更","本","模","此","段","浏","清","理","用","痕","码","私","移","窗","管","索","级","缓","置","翻","行","装","览","言","认","记","设","访","译","话","语","身","转","这","进","银","问","除","隐","面","页","首","默"],"pedals":[{"name":"CLEAR_BROWSING_DATA","id":1,"groups":[{"required":false,"single":true,"synonyms":[[3,7,7,3,5,2,0,1,4,8,7,6,2],[54,71,28],[54,71],[1,4,8,7,6,2]]},{"required":true,"single":true,"synonyms":[[55,86],[16,86],[61,86],[22,86],[55,56],[43,86]]},{"required":true,"single":true,"synonyms":[[54,71,46,40],[54,71,21,26],[54,71,74,37],[76,85,74,37],[76,85,21,26],[46,40],[21,26],[74,37],[66,30]]}]},{"name":"CHANGE_SEARCH_ENGINE","id":2,"groups":[{"required":false,"single":true,"synonyms":[[3,7,7,3,5,2,0,1,4,8,7,6,2],[54,71,28],[1,4,8,7,6,2]]},{"required":true,"single":true,"synonyms":[[49,45],[49,39],[45,23],[15,39],[75,67],[39]]},{"required":true,"single":true,"synonyms":[[41,64,36,42],[91,73,41,64],[41,64,28],[41,64]]}]},{"name":"MANAGE_PASSWORDS","id":3,"groups":[{"required":false,"single":true,"synonyms":[[3,7,7,3,5,2,0,1,4,8,7,6,2],[54,71,28],[1,4,8,7,6,2]]},{"required":true,"single":true,"synonyms":[[63,56],[12,45],[49,47],[49,39],[49,45],[75,67]]},{"required":true,"single":true,"synonyms":[[33,59]]}]},{"name":"CHANGE_HOME_PAGE","id":4,"groups":[{"required":false,"single":true,"synonyms":[[3,7,7,3,5,2,0,1,4,8,7,6,2],[54,71,28],[1,4,8,7,6,2]]},{"required":true,"single":true,"synonyms":[[49,45],[49,39],[45,23],[15,39],[75,67],[12,45],[39]]},{"required":true,"single":true,"synonyms":[[9,89],[90,89]]}]},{"name":"UPDATE_CREDIT_CARD","id":5,"groups":[{"required":false,"single":true,"synonyms":[[3,7,7,3,5,2,0,1,4,8,7,6,2],[54,71,28],[1,4,8,7,6,2]]},{"required":true,"single":true,"synonyms":[[49,47],[49,45],[49,39],[12,45],[75,67]]},{"required":true,"single":true,"synonyms":[[11,57,20],[84,69,20],[44,10,20]]}]},{"name":"LAUNCH_INCOGNITO","id":6,"groups":[{"required":false,"single":true,"synonyms":[[3,7,7,3,5,2,0,1,4,8,7,6,2],[54,71,28],[54,71],[1,4,8,7,6,2]]},{"required":true,"single":true,"synonyms":[[27,17],[34,27],[38,34],[34,29],[27,57],[83,13]]},{"required":true,"single":true,"synonyms":[[48,58,51,35],[48,58,62,24],[60,33,51,35],[60,33,62,24],[87,80,51,35]]}]},{"name":"TRANSLATE","id":7,"groups":[{"required":false,"single":true,"synonyms":[[3,7,7,3,5,2,0,1,4,8,7,6,2],[54,71,28],[1,4,8,7,6,2]]},{"required":true,"single":true,"synonyms":[[15,39,79,72],[68,77],[81,39],[15,39],[81,18]]},{"required":false,"single":true,"synonyms":[[82,25,78],[82,53,78],[52,14,32],[50,89,88]]}]},{"name":"UPDATE_CHROME","id":8,"groups":[{"required":true,"single":true,"synonyms":[[3,7,7,3,5,2,0,1,4,8,7,6,2],[54,71,28],[1,4,8,7,6,2]]},{"required":true,"single":true,"synonyms":[[49,47],[19,65],[31,70]]}]}],"ignore_group":{"required":false,"single":false,"synonyms":[]},"max_tokens":32} \ No newline at end of file
diff --git a/components/omnibox/resources/omnibox_resources.grdp b/components/omnibox/resources/omnibox_resources.grdp new file mode 100644 index 0000000..672d2b31 --- /dev/null +++ b/components/omnibox/resources/omnibox_resources.grdp
@@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- This part is included by /components/omnibox_strings.grdp so its resources can be per-language. --> +<grit-part> + <if expr="lang == 'de'"> + <include name="IDR_OMNIBOX_PEDAL_CONCEPTS" file="omnibox/resources/omnibox_pedal_concepts_de.json" type="BINDATA" compress="gzip" /> + </if> + <if expr="lang == 'en'"> + <include name="IDR_OMNIBOX_PEDAL_CONCEPTS" file="omnibox/resources/omnibox_pedal_concepts_en.json" type="BINDATA" compress="gzip" /> + </if> + <if expr="lang == 'fr'"> + <include name="IDR_OMNIBOX_PEDAL_CONCEPTS" file="omnibox/resources/omnibox_pedal_concepts_fr.json" type="BINDATA" compress="gzip" /> + </if> + <if expr="lang == 'ja'"> + <include name="IDR_OMNIBOX_PEDAL_CONCEPTS" file="omnibox/resources/omnibox_pedal_concepts_ja.json" type="BINDATA" compress="gzip" /> + </if> + <if expr="lang == 'zh-CN'"> + <include name="IDR_OMNIBOX_PEDAL_CONCEPTS" file="omnibox/resources/omnibox_pedal_concepts_zh-CN.json" type="BINDATA" compress="gzip" /> + </if> + <if expr="not lang in ['de', 'en', 'fr', 'ja', 'zh-CN']"> + <!-- Fall back to English for unsupported languages. --> + <include name="IDR_OMNIBOX_PEDAL_CONCEPTS" file="omnibox/resources/omnibox_pedal_concepts_en.json" type="BINDATA" compress="gzip" /> + </if> +</grit-part>
diff --git a/components/password_manager/core/browser/password_store_factory_util.cc b/components/password_manager/core/browser/password_store_factory_util.cc index cc26face..38b009d 100644 --- a/components/password_manager/core/browser/password_store_factory_util.cc +++ b/components/password_manager/core/browser/password_store_factory_util.cc
@@ -12,6 +12,7 @@ #include "components/password_manager/core/browser/android_affiliation/affiliation_service.h" #include "components/password_manager/core/browser/android_affiliation/affiliation_utils.h" #include "components/password_manager/core/browser/password_manager_constants.h" +#include "components/sync/base/user_selectable_type.h" #include "components/sync/driver/sync_service.h" #include "components/sync/driver/sync_user_settings.h" #include "services/network/public/cpp/shared_url_loader_factory.h" @@ -22,8 +23,8 @@ bool ShouldAffiliationBasedMatchingBeActive(syncer::SyncService* sync_service) { return sync_service && sync_service->IsSyncFeatureActive() && - sync_service->GetUserSettings()->GetChosenDataTypes().Has( - syncer::PASSWORDS) && + sync_service->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kPasswords) && !sync_service->GetUserSettings()->IsUsingSecondaryPassphrase(); }
diff --git a/components/password_manager/core/browser/password_sync_util.cc b/components/password_manager/core/browser/password_sync_util.cc index 40ae6578..20a606a 100644 --- a/components/password_manager/core/browser/password_sync_util.cc +++ b/components/password_manager/core/browser/password_sync_util.cc
@@ -7,7 +7,7 @@ #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "components/autofill/core/common/password_form.h" -#include "components/sync/base/model_type.h" +#include "components/sync/base/user_selectable_type.h" #include "components/sync/driver/sync_user_settings.h" #include "google_apis/gaia/gaia_auth_util.h" #include "google_apis/gaia/gaia_urls.h" @@ -39,9 +39,8 @@ // Return early if the user has explicitly disabled password sync. Note that // this does not cover the case when sync as a whole is turned off. - if (sync_service && - !sync_service->GetUserSettings()->GetChosenDataTypes().Has( - syncer::PASSWORDS)) { + if (sync_service && !sync_service->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kPasswords)) { return std::string(); }
diff --git a/components/policy/core/common/cloud/machine_level_user_cloud_policy_manager.cc b/components/policy/core/common/cloud/machine_level_user_cloud_policy_manager.cc index ad6936e4c..e24d293 100644 --- a/components/policy/core/common/cloud/machine_level_user_cloud_policy_manager.cc +++ b/components/policy/core/common/cloud/machine_level_user_cloud_policy_manager.cc
@@ -51,11 +51,8 @@ CreateComponentCloudPolicyService( dm_protocol::kChromeMachineLevelExtensionCloudPolicyType, policy_dir_.Append(kComponentPolicyCache), - (local_state->GetBoolean( - policy_prefs::kCloudPolicyOverridesPlatformPolicy) - ? POLICY_SOURCE_PRIORITY_CLOUD - : POLICY_SOURCE_CLOUD), - client.get(), schema_registry()); + // Component cloud policies use the same source of Chrome ones. + store()->source(), client.get(), schema_registry()); core()->Connect(std::move(client)); core()->StartRefreshScheduler(); core()->TrackRefreshDelayPref(local_state,
diff --git a/components/policy/core/common/cloud/machine_level_user_cloud_policy_manager_unittest.cc b/components/policy/core/common/cloud/machine_level_user_cloud_policy_manager_unittest.cc index bc7ceb4..4a714cc9 100644 --- a/components/policy/core/common/cloud/machine_level_user_cloud_policy_manager_unittest.cc +++ b/components/policy/core/common/cloud/machine_level_user_cloud_policy_manager_unittest.cc
@@ -26,6 +26,7 @@ std::string(), base::FilePath(), base::FilePath(), + /* cloud_policy_has_priority= */false, scoped_refptr<base::SequencedTaskRunner>()) {} MOCK_METHOD0(LoadImmediately, void(void));
diff --git a/components/policy/core/common/cloud/machine_level_user_cloud_policy_store.cc b/components/policy/core/common/cloud/machine_level_user_cloud_policy_store.cc index 40d6f7aa5..bab58daa 100644 --- a/components/policy/core/common/cloud/machine_level_user_cloud_policy_store.cc +++ b/components/policy/core/common/cloud/machine_level_user_cloud_policy_store.cc
@@ -24,11 +24,15 @@ const std::string& machine_client_id, const base::FilePath& policy_path, const base::FilePath& key_path, + bool cloud_policy_has_priority, scoped_refptr<base::SequencedTaskRunner> background_task_runner) : DesktopCloudPolicyStore(policy_path, key_path, background_task_runner, - PolicyScope::POLICY_SCOPE_MACHINE), + PolicyScope::POLICY_SCOPE_MACHINE, + cloud_policy_has_priority + ? PolicySource::POLICY_SOURCE_PRIORITY_CLOUD + : PolicySource::POLICY_SOURCE_CLOUD), machine_dm_token_(machine_dm_token), machine_client_id_(machine_client_id) {} @@ -40,12 +44,13 @@ const std::string& machine_dm_token, const std::string& machine_client_id, const base::FilePath& policy_dir, + bool cloud_policy_has_priority, scoped_refptr<base::SequencedTaskRunner> background_task_runner) { base::FilePath policy_cache_file = policy_dir.Append(kPolicyCache); base::FilePath key_cache_file = policy_dir.Append(kKeyCache); return std::make_unique<MachineLevelUserCloudPolicyStore>( machine_dm_token, machine_client_id, policy_cache_file, key_cache_file, - background_task_runner); + cloud_policy_has_priority, background_task_runner); } void MachineLevelUserCloudPolicyStore::LoadImmediately() {
diff --git a/components/policy/core/common/cloud/machine_level_user_cloud_policy_store.h b/components/policy/core/common/cloud/machine_level_user_cloud_policy_store.h index b3ef3b8..d7bf57a 100644 --- a/components/policy/core/common/cloud/machine_level_user_cloud_policy_store.h +++ b/components/policy/core/common/cloud/machine_level_user_cloud_policy_store.h
@@ -25,6 +25,7 @@ const std::string& machine_client_id, const base::FilePath& policy_path, const base::FilePath& key_path, + bool cloud_policy_has_priority, scoped_refptr<base::SequencedTaskRunner> background_task_runner); ~MachineLevelUserCloudPolicyStore() override; @@ -32,6 +33,7 @@ const std::string& machine_dm_token, const std::string& machine_client_id, const base::FilePath& policy_dir, + bool cloud_policy_has_priority, scoped_refptr<base::SequencedTaskRunner> background_task_runner); // override DesktopCloudPolicyStore
diff --git a/components/policy/core/common/cloud/machine_level_user_cloud_policy_store_unittest.cc b/components/policy/core/common/cloud/machine_level_user_cloud_policy_store_unittest.cc index c33ca52d..239803d 100644 --- a/components/policy/core/common/cloud/machine_level_user_cloud_policy_store_unittest.cc +++ b/components/policy/core/common/cloud/machine_level_user_cloud_policy_store_unittest.cc
@@ -42,11 +42,20 @@ store_ = CreateStore(); } - std::unique_ptr<MachineLevelUserCloudPolicyStore> CreateStore() { + void SetExpectedPolicyMap(PolicySource source) { + expected_policy_map_.Clear(); + expected_policy_map_.Set("IncognitoEnabled", POLICY_LEVEL_MANDATORY, + POLICY_SCOPE_MACHINE, source, + std::make_unique<base::Value>(false), nullptr); + } + + std::unique_ptr<MachineLevelUserCloudPolicyStore> CreateStore( + bool cloud_policy_overrides = false) { std::unique_ptr<MachineLevelUserCloudPolicyStore> store = MachineLevelUserCloudPolicyStore::Create( PolicyBuilder::kFakeToken, PolicyBuilder::kFakeDeviceId, - tmp_policy_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get()); + tmp_policy_dir_.GetPath(), cloud_policy_overrides, + base::ThreadTaskRunnerHandle::Get()); store->AddObserver(&observer_); return store; } @@ -62,6 +71,7 @@ base::ScopedTempDir tmp_policy_dir_; UserPolicyBuilder policy_; MockCloudPolicyStoreObserver observer_; + PolicyMap expected_policy_map_; private: base::test::ScopedTaskEnvironment scoped_task_environment_; @@ -153,9 +163,35 @@ loader->Load(); base::RunLoop().RunUntilIdle(); + SetExpectedPolicyMap(POLICY_SOURCE_CLOUD); ASSERT_TRUE(loader->policy()); EXPECT_EQ(policy_.policy_data().SerializeAsString(), loader->policy()->SerializeAsString()); + EXPECT_TRUE(expected_policy_map_.Equals(loader->policy_map())); + EXPECT_EQ(CloudPolicyStore::STATUS_OK, loader->status()); + loader->RemoveObserver(&observer_); + + ::testing::Mock::VerifyAndClearExpectations(&observer_); +} + +TEST_F(MachineLevelUserCloudPolicyStoreTest, + StoreAndLoadPolicyWithCloudPriority) { + EXPECT_CALL(observer_, OnStoreLoaded(store_.get())); + store_->Store(policy_.policy()); + base::RunLoop().RunUntilIdle(); + + ::testing::Mock::VerifyAndClearExpectations(&observer_); + + std::unique_ptr<MachineLevelUserCloudPolicyStore> loader = CreateStore(true); + EXPECT_CALL(observer_, OnStoreLoaded(loader.get())); + loader->Load(); + base::RunLoop().RunUntilIdle(); + + SetExpectedPolicyMap(POLICY_SOURCE_PRIORITY_CLOUD); + ASSERT_TRUE(loader->policy()); + EXPECT_EQ(policy_.policy_data().SerializeAsString(), + loader->policy()->SerializeAsString()); + EXPECT_TRUE(expected_policy_map_.Equals(loader->policy_map())); EXPECT_EQ(CloudPolicyStore::STATUS_OK, loader->status()); loader->RemoveObserver(&observer_);
diff --git a/components/policy/core/common/cloud/user_cloud_policy_store.cc b/components/policy/core/common/cloud/user_cloud_policy_store.cc index a4f8767b..9e7e3bf 100644 --- a/components/policy/core/common/cloud/user_cloud_policy_store.cc +++ b/components/policy/core/common/cloud/user_cloud_policy_store.cc
@@ -172,8 +172,11 @@ const base::FilePath& policy_path, const base::FilePath& key_path, scoped_refptr<base::SequencedTaskRunner> background_task_runner, - PolicyScope policy_scope) - : UserCloudPolicyStoreBase(background_task_runner, policy_scope), + PolicyScope policy_scope, + PolicySource policy_source) + : UserCloudPolicyStoreBase(background_task_runner, + policy_scope, + policy_source), policy_path_(policy_path), key_path_(key_path), weak_factory_(this) {} @@ -406,7 +409,8 @@ : DesktopCloudPolicyStore(policy_path, key_path, background_task_runner, - PolicyScope::POLICY_SCOPE_USER) {} + PolicyScope::POLICY_SCOPE_USER, + PolicySource::POLICY_SOURCE_CLOUD) {} UserCloudPolicyStore::~UserCloudPolicyStore() {}
diff --git a/components/policy/core/common/cloud/user_cloud_policy_store.h b/components/policy/core/common/cloud/user_cloud_policy_store.h index d281ab7..de9571b 100644 --- a/components/policy/core/common/cloud/user_cloud_policy_store.h +++ b/components/policy/core/common/cloud/user_cloud_policy_store.h
@@ -30,7 +30,8 @@ const base::FilePath& policy_file, const base::FilePath& key_file, scoped_refptr<base::SequencedTaskRunner> background_task_runner, - PolicyScope policy_scope); + PolicyScope policy_scope, + PolicySource policy_source); ~DesktopCloudPolicyStore() override; // Loads policy immediately on the current thread. Virtual for mocks.
diff --git a/components/policy/core/common/cloud/user_cloud_policy_store_base.cc b/components/policy/core/common/cloud/user_cloud_policy_store_base.cc index c6a6b82..35119392 100644 --- a/components/policy/core/common/cloud/user_cloud_policy_store_base.cc +++ b/components/policy/core/common/cloud/user_cloud_policy_store_base.cc
@@ -18,9 +18,14 @@ UserCloudPolicyStoreBase::UserCloudPolicyStoreBase( scoped_refptr<base::SequencedTaskRunner> background_task_runner, - PolicyScope policy_scope) + PolicyScope policy_scope, + PolicySource policy_source) : background_task_runner_(background_task_runner), - policy_scope_(policy_scope) {} + policy_scope_(policy_scope), + policy_source_(policy_source) { + DCHECK(policy_source == POLICY_SOURCE_CLOUD || + policy_source == POLICY_SOURCE_PRIORITY_CLOUD); +} UserCloudPolicyStoreBase::~UserCloudPolicyStoreBase() {} @@ -46,7 +51,7 @@ const std::string& policy_signature_public_key) { // Decode the payload. policy_map_.Clear(); - DecodeProtoFields(*payload, external_data_manager(), POLICY_SOURCE_CLOUD, + DecodeProtoFields(*payload, external_data_manager(), policy_source_, policy_scope_, &policy_map_); policy_ = std::move(policy_data); policy_signature_public_key_ = policy_signature_public_key;
diff --git a/components/policy/core/common/cloud/user_cloud_policy_store_base.h b/components/policy/core/common/cloud/user_cloud_policy_store_base.h index d53bd28..9550115 100644 --- a/components/policy/core/common/cloud/user_cloud_policy_store_base.h +++ b/components/policy/core/common/cloud/user_cloud_policy_store_base.h
@@ -28,9 +28,12 @@ public: UserCloudPolicyStoreBase( scoped_refptr<base::SequencedTaskRunner> background_task_runner, - PolicyScope policy_scope); + PolicyScope policy_scope, + PolicySource policy_source); ~UserCloudPolicyStoreBase() override; + PolicySource source() { return policy_source_; } + protected: // Creates a validator configured to validate a user policy. The caller owns // the resulting object until StartValidation() is invoked. @@ -53,6 +56,7 @@ // Task runner for background file operations. scoped_refptr<base::SequencedTaskRunner> background_task_runner_; PolicyScope policy_scope_; + PolicySource policy_source_; DISALLOW_COPY_AND_ASSIGN(UserCloudPolicyStoreBase); };
diff --git a/components/policy/proto/chrome_device_policy.proto b/components/policy/proto/chrome_device_policy.proto index 5c2d5ff..98449e0 100644 --- a/components/policy/proto/chrome_device_policy.proto +++ b/components/policy/proto/chrome_device_policy.proto
@@ -1269,6 +1269,15 @@ optional bool enabled = 1; } +// Settings that control when a device will wake up and check for updates. These +// checks are recurring. In order to disable a set schedule the policy must be +// removed. +message DeviceScheduledUpdateCheckProto { + // This is a JSON string, for details see "DeviceScheduledUpdateCheck" in + // policy_templates.json. + optional string device_scheduled_update_check_settings = 1; +} + message ChromeDeviceSettingsProto { reserved 61; optional DevicePolicyRefreshRateProto device_policy_refresh_rate = 1; @@ -1379,4 +1388,5 @@ device_advanced_battery_charge_mode = 86; optional DeviceBatteryChargeModeProto device_battery_charge_mode = 87; optional DeviceUsbPowerShareProto device_usb_power_share = 88; + optional DeviceScheduledUpdateCheckProto device_scheduled_update_check = 89; }
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index 0d23ec6..c922981 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -12488,12 +12488,11 @@ 'id': 381, 'caption': '''<ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> cloud policy overrides Platform policy.''', 'tags': [], - 'future': True, 'desc': ''' - If the policy is set to true, cloud policy takes precedence if it conflicts with platform policy. + If the policy is set to true, cloud policy takes precedence if it conflicts with platform policy. If the policy is set to false or not configured, platform policy takes precedence if it conflicts with cloud policy. - This policy is only available as a platform. + This policy is only available as a mandatory machine platform policy and it only affects machine scope cloud policies. ''', }, { @@ -15685,6 +15684,51 @@ If this policy is not configured or left unset, the standard battery charge mode will be applied.''' }, + { + 'name': 'DeviceScheduledUpdateCheck', + 'device_only': True, + 'type': 'dict', + 'schema': { + 'type': 'object', + 'properties': { + 'update_check_time': { + 'description': '''Time when the update check should happen, interpreted in the device's local time zone.''', + '$ref': 'Time' + }, + 'frequency': { + 'description': 'Frequency with which the update check should recur.', + 'type': 'string', + 'enum': [ + 'DAILY', + 'WEEKLY', + 'MONTHLY' + ] + }, + 'day_of_week': { + 'description': '''Day of week when the update check should happen, interpreted in the device's local time zone. Only used when 'frequency' is 'WEEKLY'.''', + '$ref': 'WeekDay' + }, + 'day_of_month': { + 'description': '''Day of month [1-31] when the update check should happen, interpreted in the device's local time zone. Only used when 'frequency' is 'MONTHLY'. If this is more than the maximum number of days in a given month then the last day of the month will be chosen.''', + 'type': 'integer', + 'minimum': 1, + 'maximum': 31 + } + }, + 'required': ['update_check_time', 'frequency'] + }, + 'supported_on': ['chrome_os:75-'], + 'supported_chrome_os_management': ['google_cloud'], + 'features': { + 'dynamic_refresh': True, + 'per_profile': False, + }, + 'example_value': {'update_check_time' : {'hour': 23, 'minute': 35}, 'frequency': 'WEEKLY', 'day_of_week': 'MONDAY', 'day_of_month': 11}, + 'tags': [], + 'id': 556, + 'caption': '''Set custom schedule to check for updates''', + 'desc': '''Allows setting a custom schedule to check for updates. This applies to all users, and to all interfaces on the device. Once set, the device will check for updates according to the schedule. The policy must be removed to cancel any more scheduled update checks.''' + }, ], 'messages': { @@ -15850,5 +15894,5 @@ }, 'placeholders': [], 'deleted_policy_ids': [412], - 'highest_id_currently_used': 555 + 'highest_id_currently_used': 556 }
diff --git a/components/resources/OWNERS b/components/resources/OWNERS index 7e1e4793..456bcda 100644 --- a/components/resources/OWNERS +++ b/components/resources/OWNERS
@@ -19,7 +19,6 @@ per-file neterror*=file://net/OWNERS per-file ntp_tiles_resources.grdp=file://components/ntp_tiles/OWNERS per-file offline_pages_resources.grdp=file://components/offline_pages/OWNERS -per-file omnibox_resources.grdp=file://components/omnibox/OWNERS per-file proximity_auth*=tengs@chromium.org per-file printing_resources.grdp=file://printing/OWNERS per-file security_interstitials_resources.grdp=file://components/security_interstitials/OWNERS
diff --git a/components/resources/components_resources.grd b/components/resources/components_resources.grd index 7e12c82..1097ea55 100644 --- a/components/resources/components_resources.grd +++ b/components/resources/components_resources.grd
@@ -17,7 +17,6 @@ <part file="neterror_resources.grdp" /> <part file="ntp_tiles_resources.grdp" /> <part file="offline_pages_resources.grdp" /> - <part file="omnibox_resources.grdp" /> <part file="password_manager_internals_resources.grdp" /> <part file="printing_resources.grdp" /> <part file="safe_browsing_resources.grdp" />
diff --git a/components/resources/omnibox_resources.grdp b/components/resources/omnibox_resources.grdp deleted file mode 100644 index 80372e1b..0000000 --- a/components/resources/omnibox_resources.grdp +++ /dev/null
@@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<grit-part> - <include name="IDR_OMNIBOX_PEDAL_CONCEPTS" file="../omnibox/resources/omnibox_pedal_concepts.json" type="BINDATA" compress="gzip" /> -</grit-part>
diff --git a/components/search_engines/template_url_data.cc b/components/search_engines/template_url_data.cc index 1bf7f24..e7cfd6c 100644 --- a/components/search_engines/template_url_data.cc +++ b/components/search_engines/template_url_data.cc
@@ -8,10 +8,31 @@ #include "base/i18n/case_conversion.h" #include "base/logging.h" #include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/trace_event/memory_usage_estimator.h" #include "base/values.h" +namespace { + +// Returns a GUID used for sync, which is random except for prepopulated search +// engines. The latter benefit from using a deterministic GUID, to make sure +// sync doesn't incur in duplicates for prepopulated engines. +std::string GenerateGUID(int prepopulate_id) { + // IDs above 1000 are reserved for distribution custom engines. + if (prepopulate_id <= 0 || prepopulate_id > 1000) + return base::GenerateGUID(); + + // We compute a GUID deterministically given |prepopulate_id|, using an + // arbitrary base GUID. + std::string guid = + base::StringPrintf("485bf7d3-0215-45af-87dc-538868%06d", prepopulate_id); + DCHECK(base::IsValidGUID(guid)); + return guid; +} + +} // namespace + TemplateURLData::TemplateURLData() : safe_for_autoreplace(false), id(0), @@ -60,7 +81,7 @@ created_by_policy(false), usage_count(0), prepopulate_id(prepopulate_id), - sync_guid(base::GenerateGUID()) { + sync_guid(GenerateGUID(prepopulate_id)) { SetShortName(name); SetKeyword(keyword); SetURL(search_url.as_string()); @@ -97,6 +118,10 @@ url_ = url; } +void TemplateURLData::GenerateSyncGUID() { + sync_guid = GenerateGUID(prepopulate_id); +} + size_t TemplateURLData::EstimateMemoryUsage() const { size_t res = 0;
diff --git a/components/search_engines/template_url_data.h b/components/search_engines/template_url_data.h index 3d8c8a3..1f77240 100644 --- a/components/search_engines/template_url_data.h +++ b/components/search_engines/template_url_data.h
@@ -64,6 +64,11 @@ void SetURL(const std::string& url); const std::string& url() const { return url_; } + // Recomputes |sync_guid| using the same logic as in the constructor. This + // means a random GUID is generated, except for prepopulated search engines, + // which generate GUIDs deterministically based on |prepopulate_id|. + void GenerateSyncGUID(); + // Estimates dynamic memory usage. // See base/trace_event/memory_usage_estimator.h for more info. size_t EstimateMemoryUsage() const;
diff --git a/components/search_engines/template_url_service.cc b/components/search_engines/template_url_service.cc index b4dd648..88732aca 100644 --- a/components/search_engines/template_url_service.cc +++ b/components/search_engines/template_url_service.cc
@@ -11,7 +11,6 @@ #include "base/callback.h" #include "base/debug/crash_logging.h" #include "base/format_macros.h" -#include "base/guid.h" #include "base/metrics/histogram_macros.h" #include "base/stl_util.h" #include "base/strings/string_split.h" @@ -2089,7 +2088,7 @@ default_search_provider_source_ = DefaultSearchManager::FROM_POLICY; TemplateURLData new_data(*default_from_prefs); if (new_data.sync_guid.empty()) - new_data.sync_guid = base::GenerateGUID(); + new_data.GenerateSyncGUID(); new_data.created_by_policy = true; std::unique_ptr<TemplateURL> new_dse_ptr = std::make_unique<TemplateURL>(new_data); @@ -2321,7 +2320,7 @@ DCHECK(template_url); if (template_url->sync_guid().empty() && (template_url->type() == TemplateURL::NORMAL)) { - template_url->data_.sync_guid = base::GenerateGUID(); + template_url->data_.GenerateSyncGUID(); if (web_data_service_) web_data_service_->UpdateKeyword(template_url->data()); }
diff --git a/components/send_tab_to_self/BUILD.gn b/components/send_tab_to_self/BUILD.gn index 0c44fc7..710aafc 100644 --- a/components/send_tab_to_self/BUILD.gn +++ b/components/send_tab_to_self/BUILD.gn
@@ -10,6 +10,8 @@ "send_tab_to_self_bridge.h", "send_tab_to_self_entry.cc", "send_tab_to_self_entry.h", + "send_tab_to_self_metrics.cc", + "send_tab_to_self_metrics.h", "send_tab_to_self_model.cc", "send_tab_to_self_model.h", "send_tab_to_self_model_observer.h",
diff --git a/components/send_tab_to_self/send_tab_to_self_infobar_delegate.cc b/components/send_tab_to_self/send_tab_to_self_infobar_delegate.cc index 9072e11..2ecb33d 100644 --- a/components/send_tab_to_self/send_tab_to_self_infobar_delegate.cc +++ b/components/send_tab_to_self/send_tab_to_self_infobar_delegate.cc
@@ -4,8 +4,6 @@ #include "components/send_tab_to_self/send_tab_to_self_infobar_delegate.h" -#include <memory> - #include "base/memory/ptr_util.h" #include "base/strings/utf_string_conversions.h" #include "components/send_tab_to_self/send_tab_to_self_entry.h" @@ -13,11 +11,7 @@ namespace send_tab_to_self { -SendTabToSelfInfoBarDelegate::SendTabToSelfInfoBarDelegate( - const SendTabToSelfEntry* entry) { - entry_ = entry; -} - +// static std::unique_ptr<SendTabToSelfInfoBarDelegate> SendTabToSelfInfoBarDelegate::Create(const SendTabToSelfEntry* entry) { return base::WrapUnique(new SendTabToSelfInfoBarDelegate(entry)); @@ -44,4 +38,9 @@ return SEND_TAB_TO_SELF_INFOBAR_DELEGATE; } +SendTabToSelfInfoBarDelegate::SendTabToSelfInfoBarDelegate( + const SendTabToSelfEntry* entry) { + entry_ = entry; +} + } // namespace send_tab_to_self
diff --git a/components/send_tab_to_self/send_tab_to_self_infobar_delegate.h b/components/send_tab_to_self/send_tab_to_self_infobar_delegate.h index 280aaa89..e959ff3 100644 --- a/components/send_tab_to_self/send_tab_to_self_infobar_delegate.h +++ b/components/send_tab_to_self/send_tab_to_self_infobar_delegate.h
@@ -17,7 +17,6 @@ // Delegate containing logic about what to display and how to behave // in the SendTabToSelf infobar. Used across Android and iOS. -// TODO(crbug.com/ class SendTabToSelfInfoBarDelegate : public infobars::InfoBarDelegate { public: static std::unique_ptr<SendTabToSelfInfoBarDelegate> Create( @@ -35,7 +34,7 @@ infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier() const override; private: - SendTabToSelfInfoBarDelegate(const SendTabToSelfEntry* entry); + explicit SendTabToSelfInfoBarDelegate(const SendTabToSelfEntry* entry); // The entry that was share to this device. Must outlive this instance. const SendTabToSelfEntry* entry_ = nullptr; @@ -45,4 +44,4 @@ } // namespace send_tab_to_self -#endif // COMPONENTS_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_INFOBAR_DELEGATE_H_ +#endif // COMPONENTS_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_INFOBAR_DELEGATE_H_ \ No newline at end of file
diff --git a/components/send_tab_to_self/send_tab_to_self_metrics.cc b/components/send_tab_to_self/send_tab_to_self_metrics.cc new file mode 100644 index 0000000..9f035f7 --- /dev/null +++ b/components/send_tab_to_self/send_tab_to_self_metrics.cc
@@ -0,0 +1,17 @@ +// Copyright 2019 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 "components/send_tab_to_self/send_tab_to_self_metrics.h" + +#include "base/metrics/histogram_macros.h" + +namespace send_tab_to_self { + +const char kNotificationStatusHistogram[] = "SendTabToSelf.Notification"; + +void RecordNotificationHistogram(SendTabToSelfNotification status) { + UMA_HISTOGRAM_ENUMERATION(kNotificationStatusHistogram, status); +} + +} // namespace send_tab_to_self
diff --git a/components/send_tab_to_self/send_tab_to_self_metrics.h b/components/send_tab_to_self/send_tab_to_self_metrics.h new file mode 100644 index 0000000..55a5cfd3d --- /dev/null +++ b/components/send_tab_to_self/send_tab_to_self_metrics.h
@@ -0,0 +1,31 @@ +// Copyright 2019 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 COMPONENTS_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_METRICS_H_ +#define COMPONENTS_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_METRICS_H_ + +namespace send_tab_to_self { + +// Metrics for measuring notification interaction. +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +extern const char kNotificationStatusHistogram[]; +enum class SendTabToSelfNotification { + // The user opened a tab from a notification. + kOpened = 0, + // The user closed a notification. + kDismissed = 1, + // A notification was shown from a remotely added entry. + kShown = 2, + // A notification was dismissed remotely. + kDismissedRemotely = 3, + // Update kMaxValue when new enums are added. + kMaxValue = kDismissedRemotely, +}; + +void RecordNotificationHistogram(SendTabToSelfNotification status); + +} // namespace send_tab_to_self + +#endif // COMPONENTS_SEND_TAB_TO_SELF_SEND_TAB_TO_SELF_METRICS_H_ \ No newline at end of file
diff --git a/components/services/heap_profiling/connection_manager.cc b/components/services/heap_profiling/connection_manager.cc index 59aea38..884ef9c 100644 --- a/components/services/heap_profiling/connection_manager.cc +++ b/components/services/heap_profiling/connection_manager.cc
@@ -7,7 +7,7 @@ #include "base/bind.h" #include "base/json/string_escape.h" #include "base/metrics/histogram_macros.h" -#include "base/threading/sequenced_task_runner_handle.h" +#include "base/task/post_task.h" #include "components/services/heap_profiling/json_exporter.h" #include "components/services/heap_profiling/public/cpp/client.h" @@ -85,8 +85,7 @@ uint32_t sampling_rate = 1; }; -ConnectionManager::ConnectionManager() : blocking_thread_("Blocking thread") { - blocking_thread_.Start(); +ConnectionManager::ConnectionManager() { metrics_timer_.Start( FROM_HERE, base::TimeDelta::FromHours(24), base::Bind(&ConnectionManager::ReportMetrics, base::Unretained(this))); @@ -240,7 +239,7 @@ } DCHECK(success); - DoDumpOneProcessForTracing(tracking, pid, process_type, + DoDumpOneProcessForTracing(std::move(tracking), pid, process_type, strip_path_from_mapped_files, sampling_rate, success, std::move(counts), std::move(context_map), std::move(string_map)); @@ -289,55 +288,46 @@ ExportMemoryMapsAndV2StackTraceToJSON(¶ms, oss); std::string reply = oss.str(); size_t reply_size = reply.size(); - next_id_ = params.next_id; - using FinishedCallback = - base::OnceCallback<void(mojo::ScopedSharedBufferHandle)>; - FinishedCallback finished_callback = base::BindOnce( - [](std::string reply, base::ProcessId pid, - scoped_refptr<DumpProcessesForTracingTracking> tracking, - mojo::ScopedSharedBufferHandle buffer) { - if (!buffer.is_valid()) { - DLOG(ERROR) << "Could not create Mojo shared buffer"; - } else { - mojo::ScopedSharedBufferMapping mapping = buffer->Map(reply.size()); - if (!mapping) { - DLOG(ERROR) << "Could not map Mojo shared buffer"; - } else { - memcpy(mapping.get(), reply.c_str(), reply.size()); + base::PostTaskWithTraitsAndReplyWithResult( + FROM_HERE, + {base::TaskPriority::BEST_EFFORT, base::MayBlock(), + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, + base::BindOnce( + [](size_t size) { + // This call sends a synchronous IPC to the browser process. + return mojo::SharedBufferHandle::Create(size); + }, + reply_size), + base::BindOnce( + [](std::string reply, base::ProcessId pid, + scoped_refptr<DumpProcessesForTracingTracking> tracking, + mojo::ScopedSharedBufferHandle buffer) { + if (!buffer.is_valid()) { + DLOG(ERROR) << "Could not create Mojo shared buffer"; + } else { + mojo::ScopedSharedBufferMapping mapping = + buffer->Map(reply.size()); + if (!mapping) { + DLOG(ERROR) << "Could not map Mojo shared buffer"; + } else { + memcpy(mapping.get(), reply.c_str(), reply.size()); - memory_instrumentation::mojom::SharedBufferWithSizePtr result = - memory_instrumentation::mojom::SharedBufferWithSize::New(); - result->buffer = std::move(buffer); - result->size = reply.size(); - result->pid = pid; - tracking->results.push_back(std::move(result)); - } - } + memory_instrumentation::mojom::SharedBufferWithSizePtr result = + memory_instrumentation::mojom::SharedBufferWithSize::New(); + result->buffer = std::move(buffer); + result->size = reply.size(); + result->pid = pid; + tracking->results.push_back(std::move(result)); + } + } - // When all responses complete, issue done callback. - tracking->waiting_responses--; - if (tracking->waiting_responses == 0) - std::move(tracking->callback).Run(std::move(tracking->results)); - }, - std::move(reply), pid, tracking); - - blocking_thread_.task_runner()->PostTask( - FROM_HERE, base::BindOnce( - [](size_t size, - scoped_refptr<base::SingleThreadTaskRunner> task_runner, - FinishedCallback callback) { - // This call will send a synchronous IPC to the browser - // process. - mojo::ScopedSharedBufferHandle buffer = - mojo::SharedBufferHandle::Create(size); - task_runner->PostTask(FROM_HERE, - base::BindOnce(std::move(callback), - std::move(buffer))); - }, - reply_size, base::ThreadTaskRunnerHandle::Get(), - std::move(finished_callback))); + // When all responses complete, issue done callback. + if (--tracking->waiting_responses == 0) + std::move(tracking->callback).Run(std::move(tracking->results)); + }, + std::move(reply), pid, std::move(tracking))); } } // namespace heap_profiling
diff --git a/components/services/heap_profiling/connection_manager.h b/components/services/heap_profiling/connection_manager.h index c4baebe8..b5b3d1e 100644 --- a/components/services/heap_profiling/connection_manager.h +++ b/components/services/heap_profiling/connection_manager.h
@@ -122,13 +122,7 @@ // Every 24-hours, reports the types of profiled processes. base::RepeatingTimer metrics_timer_; - // To avoid deadlock, synchronous calls to the browser are made on a dedicated - // thread that does nothing else. Both the IO thread and connection-specific - // threads could potentially be processing messages from the browser process, - // which in turn could be blocked on sending more messages over the pipe. - base::Thread blocking_thread_; - - // Must be last. + // Must be the last. base::WeakPtrFactory<ConnectionManager> weak_factory_{this}; DISALLOW_COPY_AND_ASSIGN(ConnectionManager);
diff --git a/components/services/heap_profiling/public/cpp/client.cc b/components/services/heap_profiling/public/cpp/client.cc index 704f3733..86776e68 100644 --- a/components/services/heap_profiling/public/cpp/client.cc +++ b/components/services/heap_profiling/public/cpp/client.cc
@@ -6,9 +6,7 @@ #include "base/allocator/allocator_interception_mac.h" #include "base/bind.h" -#include "base/single_thread_task_runner.h" #include "base/task/post_task.h" -#include "base/task/task_traits.h" #include "base/trace_event/malloc_dump_provider.h" #include "build/build_config.h" #include "components/services/heap_profiling/public/cpp/sampling_profiler_wrapper.h" @@ -20,23 +18,6 @@ namespace heap_profiling { -namespace { - -#if defined(OS_ANDROID) && BUILDFLAG(CAN_UNWIND_WITH_CFI_TABLE) && \ - defined(OFFICIAL_BUILD) -void EnsureCFIInitializedOnBackgroundThread( - scoped_refptr<base::SingleThreadTaskRunner> callback_task_runner, - base::OnceClosure callback) { - bool can_unwind = - base::trace_event::CFIBacktraceAndroid::GetInitializedInstance() - ->can_unwind_stack_frames(); - DCHECK(can_unwind); - callback_task_runner->PostTask(FROM_HERE, std::move(callback)); -} -#endif - -} // namespace - Client::Client() : sampling_profiler_(new SamplingProfilerWrapper()) {} Client::~Client() { @@ -67,17 +48,18 @@ defined(OFFICIAL_BUILD) // On Android the unwinder initialization requires file reading before // initializing shim. So, post task on background thread. - auto init_callback = + base::PostTaskWithTraitsAndReply( + FROM_HERE, + {base::TaskPriority::BEST_EFFORT, base::MayBlock(), + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, + base::BindOnce([]() { + bool can_unwind = + base::trace_event::CFIBacktraceAndroid::GetInitializedInstance() + ->can_unwind_stack_frames(); + DCHECK(can_unwind); + }), base::BindOnce(&Client::StartProfilingInternal, - weak_factory_.GetWeakPtr(), std::move(params)); - - auto background_task = base::BindOnce(&EnsureCFIInitializedOnBackgroundThread, - base::ThreadTaskRunnerHandle::Get(), - std::move(init_callback)); - base::PostTaskWithTraits(FROM_HERE, - {base::TaskPriority::BEST_EFFORT, base::MayBlock(), - base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}, - std::move(background_task)); + weak_factory_.GetWeakPtr(), std::move(params))); #else StartProfilingInternal(std::move(params)); #endif
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn index b0bba32..0606b7e 100644 --- a/components/sync/BUILD.gn +++ b/components/sync/BUILD.gn
@@ -84,6 +84,8 @@ "base/unrecoverable_error_handler.h", "base/unrecoverable_error_info.cc", "base/unrecoverable_error_info.h", + "base/user_selectable_type.cc", + "base/user_selectable_type.h", "base/weak_handle.cc", "base/weak_handle.h", ]
diff --git a/components/sync/base/model_type.cc b/components/sync/base/model_type.cc index 4ea35bed..d6dca50d 100644 --- a/components/sync/base/model_type.cc +++ b/components/sync/base/model_type.cc
@@ -443,19 +443,6 @@ return UNSPECIFIED; } -ModelTypeNameMap GetUserSelectableTypeNameMap() { - ModelTypeNameMap type_names; - ModelTypeSet type_set = UserSelectableTypes(); - ModelTypeSet::Iterator it = type_set.begin(); - DCHECK_EQ(base::size(kUserSelectableDataTypeNames), type_set.Size()); - for (size_t i = 0; - i < base::size(kUserSelectableDataTypeNames) && it != type_set.end(); - ++i, ++it) { - type_names[*it] = kUserSelectableDataTypeNames[i]; - } - return type_names; -} - ModelTypeSet EncryptableUserTypes() { static_assert(44 == ModelType::NUM_ENTRIES, "If adding an unencryptable type, remove from "
diff --git a/components/sync/base/model_type.h b/components/sync/base/model_type.h index 3bf14c1..db7e7d7 100644 --- a/components/sync/base/model_type.h +++ b/components/sync/base/model_type.h
@@ -184,19 +184,6 @@ // prefer using GetModelType where possible. ModelType GetModelTypeFromSpecifics(const sync_pb::EntitySpecifics& specifics); -// Notes: -// 1) This list must contain exactly the same elements as the set returned by -// UserSelectableTypes(). -// 2) This list must be in the same order as the respective values in the -// ModelType enum. -constexpr const char* kUserSelectableDataTypeNames[] = { - "bookmarks", "preferences", "passwords", "autofill", - "themes", "typedUrls", "extensions", "apps", -#if BUILDFLAG(ENABLE_READING_LIST) - "readingList", -#endif - "tabs"}; - // Protocol types are those types that have actual protocol buffer // representations. This distinguishes them from Proxy types, which have no // protocol representation and are never sent to the server. @@ -229,20 +216,6 @@ SUPERVISED_USER_WHITELISTS); } -// These are the user-selectable data types. -constexpr ModelTypeSet UserSelectableTypes() { - return ModelTypeSet(BOOKMARKS, PREFERENCES, PASSWORDS, AUTOFILL, THEMES, - TYPED_URLS, EXTENSIONS, APPS, -#if BUILDFLAG(ENABLE_READING_LIST) - READING_LIST, -#endif - PROXY_TABS); -} - -constexpr bool IsUserSelectableType(ModelType model_type) { - return UserSelectableTypes().Has(model_type); -} - // This is the subset of UserTypes() that have priority over other types. These // types are synced before other user types and are never encrypted. constexpr ModelTypeSet PriorityUserTypes() { @@ -283,8 +256,6 @@ return ModelTypeSet(USER_EVENTS, USER_CONSENTS, SECURITY_EVENTS); } -ModelTypeNameMap GetUserSelectableTypeNameMap(); - // This is the subset of UserTypes() that can be encrypted. ModelTypeSet EncryptableUserTypes();
diff --git a/components/sync/base/sync_prefs.cc b/components/sync/base/sync_prefs.cc index d215f38..e0233e2 100644 --- a/components/sync/base/sync_prefs.cc +++ b/components/sync/base/sync_prefs.cc
@@ -15,6 +15,7 @@ #include "base/values.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/pref_service.h" +#include "components/reading_list/features/reading_list_buildflags.h" #include "components/sync/base/pref_names.h" namespace syncer { @@ -78,6 +79,37 @@ } } +const char* GetPrefNameForType(UserSelectableType type) { + switch (type) { + case UserSelectableType::kBookmarks: + return prefs::kSyncBookmarks; + case UserSelectableType::kPreferences: + return prefs::kSyncPreferences; + case UserSelectableType::kPasswords: + return prefs::kSyncPasswords; + case UserSelectableType::kAutofill: + return prefs::kSyncAutofill; + case UserSelectableType::kThemes: + return prefs::kSyncThemes; + case UserSelectableType::kHistory: + // kSyncTypedUrls used here for historic reasons and pref backward + // compatibility. + return prefs::kSyncTypedUrls; + case UserSelectableType::kExtensions: + return prefs::kSyncExtensions; + case UserSelectableType::kApps: + return prefs::kSyncApps; +#if BUILDFLAG(ENABLE_READING_LIST) + case UserSelectableType::kReadingList: + return prefs::kSyncReadingList; +#endif + case UserSelectableType::kTabs: + return prefs::kSyncTabs; + } + NOTREACHED(); + return nullptr; +} + } // namespace CryptoSyncPrefs::~CryptoSyncPrefs() {} @@ -118,8 +150,8 @@ registry->RegisterBooleanPref(prefs::kSyncFirstSetupComplete, false); registry->RegisterBooleanPref(prefs::kSyncSuppressStart, true); registry->RegisterBooleanPref(prefs::kSyncKeepEverythingSynced, true); - for (ModelType type : UserSelectableTypes()) { - RegisterDataTypePreferredPref(registry, type); + for (UserSelectableType type : UserSelectableTypeSet::All()) { + RegisterTypeSelectedPref(registry, type); } // Internal or bookkeeping prefs. @@ -185,8 +217,8 @@ // since they're never actually set as user preferences. // Note: We do *not* clear prefs which are directly user-controlled such as - // the set of preferred data types here, so that if the user ever chooses to - // enable Sync again, they start off with their previous settings by default. + // the set of selected types here, so that if the user ever chooses to enable + // Sync again, they start off with their previous settings by default. // We do however require going through first-time setup again. pref_service_->ClearPref(prefs::kSyncFirstSetupComplete); } @@ -270,34 +302,35 @@ return pref_service_->GetBoolean(prefs::kSyncKeepEverythingSynced); } -ModelTypeSet SyncPrefs::GetChosenDataTypes() const { +UserSelectableTypeSet SyncPrefs::GetSelectedTypes() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (pref_service_->GetBoolean(prefs::kSyncKeepEverythingSynced)) { - return UserSelectableTypes(); + return UserSelectableTypeSet::All(); } - ModelTypeSet chosen_types; - for (ModelType type : UserSelectableTypes()) { - if (IsDataTypeChosen(type)) { - chosen_types.Put(type); + UserSelectableTypeSet selected_types; + for (UserSelectableType type : UserSelectableTypeSet::All()) { + const char* pref_name = GetPrefNameForType(type); + DCHECK(pref_name); + if (pref_service_->GetBoolean(pref_name)) { + selected_types.Put(type); } } - return chosen_types; + return selected_types; } -void SyncPrefs::SetDataTypesConfiguration(bool keep_everything_synced, - ModelTypeSet choosable_types, - ModelTypeSet chosen_types) { +void SyncPrefs::SetSelectedTypes(bool keep_everything_synced, + UserSelectableTypeSet registered_types, + UserSelectableTypeSet selected_types) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(UserSelectableTypes().HasAll(choosable_types)); - DCHECK(choosable_types.HasAll(chosen_types)); pref_service_->SetBoolean(prefs::kSyncKeepEverythingSynced, keep_everything_synced); - for (ModelType type : choosable_types) { - SetDataTypeChosen(type, chosen_types.Has(type)); + for (UserSelectableType type : registered_types) { + const char* pref_name = GetPrefNameForType(type); + pref_service_->SetBoolean(pref_name, selected_types.Has(type)); } for (SyncPrefObserver& observer : sync_pref_observers_) { @@ -331,67 +364,8 @@ } // static -const char* SyncPrefs::GetPrefNameForDataType(ModelType type) { - switch (type) { - case UNSPECIFIED: - case TOP_LEVEL_FOLDER: - case AUTOFILL_PROFILE: - case AUTOFILL_WALLET_DATA: - case AUTOFILL_WALLET_METADATA: - case SEARCH_ENGINES: - case APP_SETTINGS: - case EXTENSION_SETTINGS: - case DEPRECATED_APP_NOTIFICATIONS: - case HISTORY_DELETE_DIRECTIVES: - case DEPRECATED_SYNCED_NOTIFICATIONS: - case DEPRECATED_SYNCED_NOTIFICATION_APP_INFO: - case DICTIONARY: - case FAVICON_IMAGES: - case FAVICON_TRACKING: - case DEVICE_INFO: - case PRIORITY_PREFERENCES: - case SUPERVISED_USER_SETTINGS: - case DEPRECATED_SUPERVISED_USERS: - case DEPRECATED_SUPERVISED_USER_SHARED_SETTINGS: - case DEPRECATED_ARTICLES: - case APP_LIST: - case DEPRECATED_WIFI_CREDENTIALS: - case SUPERVISED_USER_WHITELISTS: - case ARC_PACKAGE: - case PRINTERS: - case USER_EVENTS: - case SECURITY_EVENTS: - case MOUNTAIN_SHARES: - case USER_CONSENTS: - case SEND_TAB_TO_SELF: - case NIGORI: - case DEPRECATED_EXPERIMENTS: - case ModelType::NUM_ENTRIES: - case SESSIONS: - break; - case BOOKMARKS: - return prefs::kSyncBookmarks; - case PREFERENCES: - return prefs::kSyncPreferences; - case PASSWORDS: - return prefs::kSyncPasswords; - case AUTOFILL: - return prefs::kSyncAutofill; - case THEMES: - return prefs::kSyncThemes; - case TYPED_URLS: - return prefs::kSyncTypedUrls; - case EXTENSIONS: - return prefs::kSyncExtensions; - case APPS: - return prefs::kSyncApps; - case READING_LIST: - return prefs::kSyncReadingList; - case PROXY_TABS: - return prefs::kSyncTabs; - } - NOTREACHED() << "No pref mapping for type " << ModelTypeToString(type); - return nullptr; +const char* SyncPrefs::GetPrefNameForTypeForTesting(UserSelectableType type) { + return GetPrefNameForType(type); } void SyncPrefs::OnSyncManagedPrefChanged() { @@ -419,32 +393,14 @@ } // static -void SyncPrefs::RegisterDataTypePreferredPref( +void SyncPrefs::RegisterTypeSelectedPref( user_prefs::PrefRegistrySyncable* registry, - ModelType type) { - const char* pref_name = GetPrefNameForDataType(type); + UserSelectableType type) { + const char* pref_name = GetPrefNameForType(type); DCHECK(pref_name); registry->RegisterBooleanPref(pref_name, false); } -bool SyncPrefs::IsDataTypeChosen(ModelType type) const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - const char* pref_name = GetPrefNameForDataType(type); - DCHECK(pref_name); - DCHECK(IsUserSelectableType(type)); - - return pref_service_->GetBoolean(pref_name); -} - -void SyncPrefs::SetDataTypeChosen(ModelType type, bool is_chosen) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - const char* pref_name = GetPrefNameForDataType(type); - DCHECK(pref_name); - DCHECK(IsUserSelectableType(type)); - - pref_service_->SetBoolean(pref_name, is_chosen); -} - void SyncPrefs::SetCacheGuid(const std::string& cache_guid) { pref_service_->SetString(prefs::kSyncCacheGuid, cache_guid); }
diff --git a/components/sync/base/sync_prefs.h b/components/sync/base/sync_prefs.h index da9dba02..d9a27afb 100644 --- a/components/sync/base/sync_prefs.h +++ b/components/sync/base/sync_prefs.h
@@ -20,6 +20,7 @@ #include "build/build_config.h" #include "components/prefs/pref_member.h" #include "components/sync/base/model_type.h" +#include "components/sync/base/user_selectable_type.h" #include "components/sync/protocol/sync.pb.h" class PrefService; @@ -73,8 +74,7 @@ // Clears "bookkeeping" sync preferences, such as the last synced time, // whether the last shutdown was clean, etc. Does *not* clear sync preferences - // which are directly user-controlled, such as the set of preferred data - // types. + // which are directly user-controlled, such as the set of selected types. void ClearPreferences(); // Clears only the subset of preferences that are redundant with the sync @@ -104,24 +104,21 @@ bool HasKeepEverythingSynced() const; - // The result set is guaranteed to be a subset of UserSelectableTypes(). - // Returns all UserSelectableTypes() if HasKeepEverythingSynced() is true. - ModelTypeSet GetChosenDataTypes() const; + // Returns UserSelectableTypeSet::All() if HasKeepEverythingSynced() is true. + UserSelectableTypeSet GetSelectedTypes() const; - // Sets the desired configuration for all UserSelectableTypes(), including - // the "keep everything synced" flag and the "chosen" state for each - // individual type. - // |keep_everything_synced| indicates that all current and future data types - // should be synced. If this is set to true, then GetChosenDataTypes() will - // always return all UserSelectableTypes(), even if not all of them are - // individually marked as preferred. - // |choosable_types| and |chosen_types| must be a subset of - // UserSelectableTypes(). Changes are still made to the individual data type - // prefs even if |keep_everything_synced| is true, but won't be visible until - // it's set to false. Changes are made only to |choosable_types|. - void SetDataTypesConfiguration(bool keep_everything_synced, - ModelTypeSet choosable_types, - ModelTypeSet chosen_types); + // Sets the selection state for all |registered_types| and "keep everything + // synced" flag. + // |keep_everything_synced| indicates that all current and future types + // should be synced. If this is set to true, then GetSelectedTypes() will + // always return UserSelectableTypeSet::All(), even if not all of them are + // registered or individually marked as selected. + // Changes are still made to the individual selectable type prefs even if + // |keep_everything_synced| is true, but won't be visible until it's set to + // false. + void SetSelectedTypes(bool keep_everything_synced, + UserSelectableTypeSet registered_types, + UserSelectableTypeSet selected_types); // Whether Sync is forced off by enterprise policy. Note that this only covers // one out of two types of policy, "browser" policy. The second kind, "cloud" @@ -138,7 +135,7 @@ void SetKeystoreEncryptionBootstrapToken(const std::string& token) override; // Maps |type| to its corresponding preference name. - static const char* GetPrefNameForDataType(ModelType type); + static const char* GetPrefNameForTypeForTesting(UserSelectableType type); // Copy of various fields historically owned and persisted by the Directory. // This is a future-proof approach to ultimately replace the Directory once @@ -185,14 +182,8 @@ bool IsLocalSyncEnabled() const; private: - static void RegisterDataTypePreferredPref( - user_prefs::PrefRegistrySyncable* prefs, - ModelType type); - - // Get/set the preference indicating that |type| was chosen. |type| must be - // on of UserSelectableTypes(). - bool IsDataTypeChosen(ModelType type) const; - void SetDataTypeChosen(ModelType type, bool is_chosen); + static void RegisterTypeSelectedPref(user_prefs::PrefRegistrySyncable* prefs, + UserSelectableType type); void OnSyncManagedPrefChanged(); void OnFirstSetupCompletePrefChange();
diff --git a/components/sync/base/sync_prefs_unittest.cc b/components/sync/base/sync_prefs_unittest.cc index 2f69214c..737ec95 100644 --- a/components/sync/base/sync_prefs_unittest.cc +++ b/components/sync/base/sync_prefs_unittest.cc
@@ -127,7 +127,7 @@ } // ----------------------------------------------------------------------------- -// Test that manipulate chosen data types. +// Test that manipulate selected types. // ----------------------------------------------------------------------------- TEST_F(SyncPrefsTest, Basic) { @@ -147,15 +147,15 @@ EXPECT_EQ(now, sync_prefs_->GetLastSyncedTime()); EXPECT_TRUE(sync_prefs_->HasKeepEverythingSynced()); - sync_prefs_->SetDataTypesConfiguration( + sync_prefs_->SetSelectedTypes( /*keep_everything_synced=*/false, - /*choosable_types=*/UserSelectableTypes(), - /*chosen_types=*/UserSelectableTypes()); + /*registered_types=*/UserSelectableTypeSet::All(), + /*selected_types=*/UserSelectableTypeSet::All()); EXPECT_FALSE(sync_prefs_->HasKeepEverythingSynced()); - sync_prefs_->SetDataTypesConfiguration( + sync_prefs_->SetSelectedTypes( /*keep_everything_synced=*/true, - /*choosable_types=*/UserSelectableTypes(), - /*chosen_types=*/ModelTypeSet()); + /*registered_types=*/UserSelectableTypeSet::All(), + /*selected_types=*/UserSelectableTypeSet()); EXPECT_TRUE(sync_prefs_->HasKeepEverythingSynced()); EXPECT_TRUE(sync_prefs_->GetEncryptionBootstrapToken().empty()); @@ -163,35 +163,32 @@ EXPECT_EQ("token", sync_prefs_->GetEncryptionBootstrapToken()); } -TEST_F(SyncPrefsTest, ChosenTypesKeepEverythingSynced) { +TEST_F(SyncPrefsTest, SelectedTypesKeepEverythingSynced) { EXPECT_TRUE(sync_prefs_->HasKeepEverythingSynced()); - EXPECT_EQ(UserSelectableTypes(), sync_prefs_->GetChosenDataTypes()); - for (ModelType type : UserSelectableTypes()) { - ModelTypeSet chosen_types; - chosen_types.Put(type); - sync_prefs_->SetDataTypesConfiguration( + EXPECT_EQ(UserSelectableTypeSet::All(), sync_prefs_->GetSelectedTypes()); + for (UserSelectableType type : UserSelectableTypeSet::All()) { + sync_prefs_->SetSelectedTypes( /*keep_everything_synced=*/true, - /*choosable_types=*/UserSelectableTypes(), - /*chosen_types=*/chosen_types); - EXPECT_EQ(UserSelectableTypes(), sync_prefs_->GetChosenDataTypes()); + /*registered_types=*/UserSelectableTypeSet::All(), + /*selected_types=*/{type}); + EXPECT_EQ(UserSelectableTypeSet::All(), sync_prefs_->GetSelectedTypes()); } } -TEST_F(SyncPrefsTest, ChosenTypesNotKeepEverythingSynced) { - sync_prefs_->SetDataTypesConfiguration( +TEST_F(SyncPrefsTest, SelectedTypesNotKeepEverythingSynced) { + sync_prefs_->SetSelectedTypes( /*keep_everything_synced=*/false, - /*choosable_types=*/UserSelectableTypes(), - /*chosen_types=*/ModelTypeSet()); + /*registered_types=*/UserSelectableTypeSet::All(), + /*selected_types=*/UserSelectableTypeSet()); - ASSERT_NE(UserSelectableTypes(), sync_prefs_->GetChosenDataTypes()); - for (ModelType type : UserSelectableTypes()) { - ModelTypeSet chosen_types{type}; - sync_prefs_->SetDataTypesConfiguration( + ASSERT_NE(UserSelectableTypeSet::All(), sync_prefs_->GetSelectedTypes()); + for (UserSelectableType type : UserSelectableTypeSet::All()) { + sync_prefs_->SetSelectedTypes( /*keep_everything_synced=*/false, - /*choosable_types=*/UserSelectableTypes(), - /*chosen_types=*/chosen_types); - EXPECT_EQ(chosen_types, sync_prefs_->GetChosenDataTypes()); + /*registered_types=*/UserSelectableTypeSet::All(), + /*selected_types=*/{type}); + EXPECT_EQ(UserSelectableTypeSet{type}, sync_prefs_->GetSelectedTypes()); } }
diff --git a/components/sync/base/user_selectable_type.cc b/components/sync/base/user_selectable_type.cc new file mode 100644 index 0000000..766f582 --- /dev/null +++ b/components/sync/base/user_selectable_type.cc
@@ -0,0 +1,81 @@ +// Copyright 2019 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 "components/sync/base/user_selectable_type.h" + +#include <type_traits> + +#include "base/logging.h" + +namespace syncer { + +namespace { + +struct UserSelectableTypeInfo { + const char* const type_name; + const ModelType canonical_model_type; + const ModelTypeSet model_type_group; +}; + +UserSelectableTypeInfo GetUserSelectableTypeInfo(UserSelectableType type) { + // UserSelectableTypeInfo::type_name is used in js code and shouldn't be + // changed without updating js part. + switch (type) { + case UserSelectableType::kBookmarks: + return {"bookmarks", BOOKMARKS, {BOOKMARKS}}; + case UserSelectableType::kPreferences: + return {"preferences", + PREFERENCES, + {PREFERENCES, DICTIONARY, PRIORITY_PREFERENCES, SEARCH_ENGINES}}; + case UserSelectableType::kPasswords: + return {"passwords", PASSWORDS, {PASSWORDS}}; + case UserSelectableType::kAutofill: + return {"autofill", + AUTOFILL, + {AUTOFILL, AUTOFILL_PROFILE, AUTOFILL_WALLET_DATA, + AUTOFILL_WALLET_METADATA}}; + case UserSelectableType::kThemes: + return {"themes", THEMES, {THEMES}}; + case UserSelectableType::kHistory: + return {"typedUrls", + TYPED_URLS, + {TYPED_URLS, HISTORY_DELETE_DIRECTIVES, SESSIONS, FAVICON_IMAGES, + FAVICON_TRACKING, USER_EVENTS}}; + case UserSelectableType::kExtensions: + return {"extensions", EXTENSIONS, {EXTENSIONS, EXTENSION_SETTINGS}}; + case UserSelectableType::kApps: + return {"apps", APPS, {APPS, APP_SETTINGS, APP_LIST, ARC_PACKAGE}}; +#if BUILDFLAG(ENABLE_READING_LIST) + case UserSelectableType::kReadingList: + return {"readingList", READING_LIST, {READING_LIST}}; +#endif + case UserSelectableType::kTabs: + return {"tabs", + PROXY_TABS, + {PROXY_TABS, SESSIONS, FAVICON_IMAGES, FAVICON_TRACKING, + SEND_TAB_TO_SELF}}; + } + NOTREACHED(); + return {nullptr, UNSPECIFIED}; +} + +} // namespace + +const char* GetUserSelectableTypeName(UserSelectableType type) { + return GetUserSelectableTypeInfo(type).type_name; +} + +ModelTypeSet UserSelectableTypeToAllModelTypes(UserSelectableType type) { + return GetUserSelectableTypeInfo(type).model_type_group; +} + +ModelType UserSelectableTypeToCanonicalModelType(UserSelectableType type) { + return GetUserSelectableTypeInfo(type).canonical_model_type; +} + +int UserSelectableTypeToHistogramInt(UserSelectableType type) { + return ModelTypeToHistogramInt(UserSelectableTypeToCanonicalModelType(type)); +} + +} // namespace syncer
diff --git a/components/sync/base/user_selectable_type.h b/components/sync/base/user_selectable_type.h new file mode 100644 index 0000000..f69754b66 --- /dev/null +++ b/components/sync/base/user_selectable_type.h
@@ -0,0 +1,50 @@ +// Copyright 2019 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 COMPONENTS_SYNC_BASE_USER_SELECTABLE_TYPE_H_ +#define COMPONENTS_SYNC_BASE_USER_SELECTABLE_TYPE_H_ + +#include "components/reading_list/features/reading_list_buildflags.h" +#include "components/sync/base/enum_set.h" +#include "components/sync/base/model_type.h" + +namespace syncer { + +enum class UserSelectableType { + kBookmarks, + kFirstType = kBookmarks, + + kPreferences, + kPasswords, + kAutofill, + kThemes, + kHistory, + kExtensions, + kApps, +// TODO(crbug.com/950874): remove this usage of ENABLE_READING_LIST build +// flag. +#if BUILDFLAG(ENABLE_READING_LIST) + kReadingList, +#endif + kTabs, + kLastType = kTabs +}; + +using UserSelectableTypeSet = EnumSet<UserSelectableType, + UserSelectableType::kFirstType, + UserSelectableType::kLastType>; + +const char* GetUserSelectableTypeName(UserSelectableType type); +ModelTypeSet UserSelectableTypeToAllModelTypes(UserSelectableType type); + +ModelType UserSelectableTypeToCanonicalModelType(UserSelectableType type); +int UserSelectableTypeToHistogramInt(UserSelectableType type); + +constexpr int UserSelectableTypeHistogramNumEntries() { + return static_cast<int>(ModelType::NUM_ENTRIES); +} + +} // namespace syncer + +#endif // COMPONENTS_SYNC_BASE_USER_SELECTABLE_TYPE_H_
diff --git a/components/sync/driver/about_sync_util.cc b/components/sync/driver/about_sync_util.cc index a125df4..e256d78 100644 --- a/components/sync/driver/about_sync_util.cc +++ b/components/sync/driver/about_sync_util.cc
@@ -455,12 +455,13 @@ SyncStatus full_status; bool is_status_valid = service->QueryDetailedSyncStatusForDebugging(&full_status); - const SyncCycleSnapshot& snapshot = service->GetLastCycleSnapshot(); + const SyncCycleSnapshot& snapshot = + service->GetLastCycleSnapshotForDebugging(); const SyncTokenStatus& token_status = service->GetSyncTokenStatus(); // Version Info. // |client_version| was already set above. - server_url->Set(service->sync_service_url().spec()); + server_url->Set(service->GetSyncServiceUrlForDebugging().spec()); // Identity. if (is_status_valid && !full_status.sync_id.empty()) @@ -485,7 +486,8 @@ // Local State. server_connection->Set(GetConnectionStatus(token_status)); - last_synced->Set(GetLastSyncedTimeString(service->GetLastSyncedTime())); + last_synced->Set( + GetLastSyncedTimeString(service->GetLastSyncedTimeForDebugging())); is_setup_complete->Set(service->GetUserSettings()->IsFirstSetupComplete()); if (is_status_valid) is_syncing->Set(full_status.syncing); @@ -616,8 +618,8 @@ if (service->HasUnrecoverableError()) { std::string unrecoverable_error_message = "Unrecoverable error detected at " + - service->unrecoverable_error_location().ToString() + ": " + - service->unrecoverable_error_message(); + service->GetUnrecoverableErrorLocationForDebugging().ToString() + ": " + + service->GetUnrecoverableErrorMessageForDebugging(); about_info->SetKey("unrecoverable_error_message", base::Value(unrecoverable_error_message)); }
diff --git a/components/sync/driver/fake_sync_service.cc b/components/sync/driver/fake_sync_service.cc index fa1dc13..c50f8e0 100644 --- a/components/sync/driver/fake_sync_service.cc +++ b/components/sync/driver/fake_sync_service.cc
@@ -69,10 +69,6 @@ return ModelTypeSet(); } -ModelTypeSet FakeSyncService::GetForcedDataTypes() const { - return ModelTypeSet(); -} - ModelTypeSet FakeSyncService::GetPreferredDataTypes() const { return ModelTypeSet(); } @@ -113,11 +109,11 @@ return false; } -base::Time FakeSyncService::GetLastSyncedTime() const { +base::Time FakeSyncService::GetLastSyncedTimeForDebugging() const { return base::Time(); } -SyncCycleSnapshot FakeSyncService::GetLastCycleSnapshot() const { +SyncCycleSnapshot FakeSyncService::GetLastCycleSnapshotForDebugging() const { return SyncCycleSnapshot(); } @@ -125,15 +121,16 @@ return nullptr; } -const GURL& FakeSyncService::sync_service_url() const { +const GURL& FakeSyncService::GetSyncServiceUrlForDebugging() const { return sync_service_url_; } -std::string FakeSyncService::unrecoverable_error_message() const { +std::string FakeSyncService::GetUnrecoverableErrorMessageForDebugging() const { return std::string(); } -base::Location FakeSyncService::unrecoverable_error_location() const { +base::Location FakeSyncService::GetUnrecoverableErrorLocationForDebugging() + const { return base::Location(); } @@ -153,7 +150,7 @@ return base::WeakPtr<JsController>(); } -void FakeSyncService::GetAllNodes( +void FakeSyncService::GetAllNodesForDebugging( const base::Callback<void(std::unique_ptr<base::ListValue>)>& callback) {} void FakeSyncService::SetInvalidationsForSessionsEnabled(bool enabled) {}
diff --git a/components/sync/driver/fake_sync_service.h b/components/sync/driver/fake_sync_service.h index 543a0e31..87d0dd9 100644 --- a/components/sync/driver/fake_sync_service.h +++ b/components/sync/driver/fake_sync_service.h
@@ -39,7 +39,6 @@ void OnDataTypeRequestsSyncStartup(ModelType type) override; void StopAndClear() override; ModelTypeSet GetRegisteredDataTypes() const override; - ModelTypeSet GetForcedDataTypes() const override; ModelTypeSet GetPreferredDataTypes() const override; std::unique_ptr<SyncSetupInProgressHandle> GetSetupInProgressHandle() override; @@ -51,19 +50,20 @@ void ReadyForStartChanged(syncer::ModelType type) override; SyncTokenStatus GetSyncTokenStatus() const override; bool QueryDetailedSyncStatusForDebugging(SyncStatus* result) const override; - base::Time GetLastSyncedTime() const override; - SyncCycleSnapshot GetLastCycleSnapshot() const override; + base::Time GetLastSyncedTimeForDebugging() const override; + SyncCycleSnapshot GetLastCycleSnapshotForDebugging() const override; std::unique_ptr<base::Value> GetTypeStatusMapForDebugging() override; - const GURL& sync_service_url() const override; - std::string unrecoverable_error_message() const override; - base::Location unrecoverable_error_location() const override; + const GURL& GetSyncServiceUrlForDebugging() const override; + std::string GetUnrecoverableErrorMessageForDebugging() const override; + base::Location GetUnrecoverableErrorLocationForDebugging() const override; void AddProtocolEventObserver(ProtocolEventObserver* observer) override; void RemoveProtocolEventObserver(ProtocolEventObserver* observer) override; void AddTypeDebugInfoObserver(TypeDebugInfoObserver* observer) override; void RemoveTypeDebugInfoObserver(TypeDebugInfoObserver* observer) override; base::WeakPtr<JsController> GetJsController() override; - void GetAllNodes(const base::Callback<void(std::unique_ptr<base::ListValue>)>& - callback) override; + void GetAllNodesForDebugging( + const base::Callback<void(std::unique_ptr<base::ListValue>)>& callback) + override; void SetInvalidationsForSessionsEnabled(bool enabled) override; // KeyedService implementation.
diff --git a/components/sync/driver/mock_sync_service.h b/components/sync/driver/mock_sync_service.h index 639b699..b09ac30 100644 --- a/components/sync/driver/mock_sync_service.h +++ b/components/sync/driver/mock_sync_service.h
@@ -46,7 +46,6 @@ MOCK_CONST_METHOD0(IsSetupInProgress, bool()); MOCK_CONST_METHOD0(GetRegisteredDataTypes, ModelTypeSet()); - MOCK_CONST_METHOD0(GetForcedDataTypes, ModelTypeSet()); MOCK_CONST_METHOD0(GetPreferredDataTypes, ModelTypeSet()); MOCK_CONST_METHOD0(GetActiveDataTypes, ModelTypeSet()); @@ -65,12 +64,13 @@ MOCK_CONST_METHOD0(GetSyncTokenStatus, SyncTokenStatus()); MOCK_CONST_METHOD1(QueryDetailedSyncStatusForDebugging, bool(SyncStatus* result)); - MOCK_CONST_METHOD0(GetLastSyncedTime, base::Time()); - MOCK_CONST_METHOD0(GetLastCycleSnapshot, SyncCycleSnapshot()); + MOCK_CONST_METHOD0(GetLastSyncedTimeForDebugging, base::Time()); + MOCK_CONST_METHOD0(GetLastCycleSnapshotForDebugging, SyncCycleSnapshot()); MOCK_METHOD0(GetTypeStatusMapForDebugging, std::unique_ptr<base::Value>()); - MOCK_CONST_METHOD0(sync_service_url, const GURL&()); - MOCK_CONST_METHOD0(unrecoverable_error_message, std::string()); - MOCK_CONST_METHOD0(unrecoverable_error_location, base::Location()); + MOCK_CONST_METHOD0(GetSyncServiceUrlForDebugging, const GURL&()); + MOCK_CONST_METHOD0(GetUnrecoverableErrorMessageForDebugging, std::string()); + MOCK_CONST_METHOD0(GetUnrecoverableErrorLocationForDebugging, + base::Location()); MOCK_METHOD1(AddProtocolEventObserver, void(ProtocolEventObserver* observer)); MOCK_METHOD1(RemoveProtocolEventObserver, void(ProtocolEventObserver* observer)); @@ -78,7 +78,7 @@ MOCK_METHOD1(RemoveTypeDebugInfoObserver, void(TypeDebugInfoObserver* observer)); MOCK_METHOD0(GetJsController, base::WeakPtr<JsController>()); - MOCK_METHOD1(GetAllNodes, + MOCK_METHOD1(GetAllNodesForDebugging, void(const base::Callback< void(std::unique_ptr<base::ListValue>)>& callback));
diff --git a/components/sync/driver/profile_sync_service.cc b/components/sync/driver/profile_sync_service.cc index 6d60b35..7c7daae9 100644 --- a/components/sync/driver/profile_sync_service.cc +++ b/components/sync/driver/profile_sync_service.cc
@@ -222,10 +222,9 @@ BuildDataTypeControllerMap(sync_client_->CreateDataTypeControllers(this)); user_settings_ = std::make_unique<SyncUserSettingsImpl>( - &crypto_, &sync_prefs_, GetRegisteredDataTypes(), + &crypto_, &sync_prefs_, sync_client_->GetPreferenceProvider(), + GetRegisteredDataTypes(), base::BindRepeating(&ProfileSyncService::SyncAllowedByPlatformChanged, - base::Unretained(this)), - base::BindRepeating(&ProfileSyncService::IsEncryptEverythingAllowed, base::Unretained(this))); sync_prefs_.AddSyncPrefObserver(this); @@ -455,7 +454,7 @@ params.extensions_activity = sync_client_->GetExtensionsActivity(); params.event_handler = GetJsEventHandler(); - params.service_url = sync_service_url(); + params.service_url = sync_service_url_; params.sync_user_agent = MakeUserAgentForSync(channel_); params.http_factory_getter = MakeHttpPostProviderFactoryGetter(); params.authenticated_account_id = GetAuthenticatedAccountInfo().account_id; @@ -1174,7 +1173,7 @@ return !GetAuthenticatedAccountInfo().account_id.empty(); } -base::Time ProfileSyncService::GetLastSyncedTime() const { +base::Time ProfileSyncService::GetLastSyncedTimeForDebugging() const { return sync_prefs_.GetLastSyncedTime(); } @@ -1224,20 +1223,9 @@ return registered_types; } -ModelTypeSet ProfileSyncService::GetForcedDataTypes() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - const SyncTypePreferenceProvider* provider = - sync_client_->GetPreferenceProvider(); - if (provider) { - return Intersection(provider->GetForcedDataTypes(), - GetRegisteredDataTypes()); - } - return ModelTypeSet(); -} - ModelTypeSet ProfileSyncService::GetPreferredDataTypes() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return Union(user_settings_->GetPreferredDataTypes(), GetForcedDataTypes()); + return user_settings_->GetPreferredDataTypes(); } ModelTypeSet ProfileSyncService::GetActiveDataTypes() const { @@ -1259,16 +1247,6 @@ } } -bool ProfileSyncService::IsEncryptEverythingAllowed() const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - const SyncTypePreferenceProvider* provider = - sync_client_->GetPreferenceProvider(); - if (provider) { - return provider->IsEncryptEverythingAllowed(); - } - return true; -} - void ProfileSyncService::ConfigureDataTypeManager(ConfigureReason reason) { ConfigureContext configure_context; configure_context.authenticated_account_id = @@ -1344,13 +1322,10 @@ UMA_HISTOGRAM_BOOLEAN("Sync.SyncEverything2", sync_everything); if (!sync_everything) { - ModelTypeSet chosen_types = GetPreferredDataTypes(); - chosen_types.RetainAll(UserSelectableTypes()); - - for (ModelType type : chosen_types) { + for (UserSelectableType type : user_settings_->GetSelectedTypes()) { UMA_HISTOGRAM_ENUMERATION("Sync.CustomSync2", - ModelTypeToHistogramInt(type), - static_cast<int>(ModelType::NUM_ENTRIES)); + UserSelectableTypeToHistogramInt(type), + UserSelectableTypeHistogramNumEntries()); } } } @@ -1365,7 +1340,7 @@ return nullptr; } -SyncCycleSnapshot ProfileSyncService::GetLastCycleSnapshot() const { +SyncCycleSnapshot ProfileSyncService::GetLastCycleSnapshotForDebugging() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return last_snapshot_; } @@ -1657,7 +1632,7 @@ } // namespace -void ProfileSyncService::GetAllNodes( +void ProfileSyncService::GetAllNodesForDebugging( const base::Callback<void(std::unique_ptr<base::ListValue>)>& callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -1903,17 +1878,19 @@ } } -const GURL& ProfileSyncService::sync_service_url() const { +const GURL& ProfileSyncService::GetSyncServiceUrlForDebugging() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return sync_service_url_; } -std::string ProfileSyncService::unrecoverable_error_message() const { +std::string ProfileSyncService::GetUnrecoverableErrorMessageForDebugging() + const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return unrecoverable_error_message_; } -base::Location ProfileSyncService::unrecoverable_error_location() const { +base::Location ProfileSyncService::GetUnrecoverableErrorLocationForDebugging() + const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return unrecoverable_error_location_; }
diff --git a/components/sync/driver/profile_sync_service.h b/components/sync/driver/profile_sync_service.h index d2f621e2..3df5ee2 100644 --- a/components/sync/driver/profile_sync_service.h +++ b/components/sync/driver/profile_sync_service.h
@@ -128,7 +128,6 @@ override; bool IsSetupInProgress() const override; ModelTypeSet GetRegisteredDataTypes() const override; - ModelTypeSet GetForcedDataTypes() const override; ModelTypeSet GetPreferredDataTypes() const override; ModelTypeSet GetActiveDataTypes() const override; void StopAndClear() override; @@ -142,19 +141,20 @@ UserShare* GetUserShare() const override; SyncTokenStatus GetSyncTokenStatus() const override; bool QueryDetailedSyncStatusForDebugging(SyncStatus* result) const override; - base::Time GetLastSyncedTime() const override; - SyncCycleSnapshot GetLastCycleSnapshot() const override; + base::Time GetLastSyncedTimeForDebugging() const override; + SyncCycleSnapshot GetLastCycleSnapshotForDebugging() const override; std::unique_ptr<base::Value> GetTypeStatusMapForDebugging() override; - const GURL& sync_service_url() const override; - std::string unrecoverable_error_message() const override; - base::Location unrecoverable_error_location() const override; + const GURL& GetSyncServiceUrlForDebugging() const override; + std::string GetUnrecoverableErrorMessageForDebugging() const override; + base::Location GetUnrecoverableErrorLocationForDebugging() const override; void AddProtocolEventObserver(ProtocolEventObserver* observer) override; void RemoveProtocolEventObserver(ProtocolEventObserver* observer) override; void AddTypeDebugInfoObserver(TypeDebugInfoObserver* observer) override; void RemoveTypeDebugInfoObserver(TypeDebugInfoObserver* observer) override; base::WeakPtr<JsController> GetJsController() override; - void GetAllNodes(const base::Callback<void(std::unique_ptr<base::ListValue>)>& - callback) override; + void GetAllNodesForDebugging( + const base::Callback<void(std::unique_ptr<base::ListValue>)>& callback) + override; // SyncEngineHost implementation. void OnEngineInitialized( @@ -291,7 +291,6 @@ // Callbacks for SyncUserSettingsImpl. void SyncAllowedByPlatformChanged(bool allowed); - bool IsEncryptEverythingAllowed() const; bool IsEngineAllowedToStart() const;
diff --git a/components/sync/driver/profile_sync_service_startup_unittest.cc b/components/sync/driver/profile_sync_service_startup_unittest.cc index 27e3c87..a5ca326 100644 --- a/components/sync/driver/profile_sync_service_startup_unittest.cc +++ b/components/sync/driver/profile_sync_service_startup_unittest.cc
@@ -413,8 +413,8 @@ TEST_F(ProfileSyncServiceStartupTest, StartRecoverDatatypePrefs) { // Clear the datatype preference fields (simulating bug 154940). pref_service()->ClearPref(prefs::kSyncKeepEverythingSynced); - for (ModelType type : UserSelectableTypes()) { - pref_service()->ClearPref(SyncPrefs::GetPrefNameForDataType(type)); + for (UserSelectableType type : UserSelectableTypeSet::All()) { + pref_service()->ClearPref(SyncPrefs::GetPrefNameForTypeForTesting(type)); } sync_prefs()->SetFirstSetupComplete(); @@ -437,10 +437,10 @@ TEST_F(ProfileSyncServiceStartupTest, StartDontRecoverDatatypePrefs) { // Explicitly set Keep Everything Synced to false and have only bookmarks // enabled. - sync_prefs()->SetDataTypesConfiguration( + sync_prefs()->SetSelectedTypes( /*keep_everything_synced=*/false, - /*choosable_types=*/UserSelectableTypes(), - /*chosen_types=*/{BOOKMARKS}); + /*choosable_types=*/UserSelectableTypeSet::All(), + /*chosen_types=*/{UserSelectableType::kBookmarks}); sync_prefs()->SetFirstSetupComplete(); CreateSyncService(ProfileSyncService::MANUAL_START);
diff --git a/components/sync/driver/profile_sync_service_unittest.cc b/components/sync/driver/profile_sync_service_unittest.cc index 18fa176..9dab61b 100644 --- a/components/sync/driver/profile_sync_service_unittest.cc +++ b/components/sync/driver/profile_sync_service_unittest.cc
@@ -18,6 +18,7 @@ #include "base/values.h" #include "components/signin/core/browser/account_info.h" #include "components/sync/base/pref_names.h" +#include "components/sync/base/user_selectable_type.h" #include "components/sync/driver/configure_context.h" #include "components/sync/driver/fake_data_type_controller.h" #include "components/sync/driver/profile_sync_service_bundle.h" @@ -220,10 +221,10 @@ SyncPrefs sync_prefs(prefs()); sync_prefs.SetLastSyncedTime(base::Time::Now()); sync_prefs.SetSyncRequested(true); - sync_prefs.SetDataTypesConfiguration( + sync_prefs.SetSelectedTypes( /*keep_everything_synced=*/true, - /*choosable_types=*/UserSelectableTypes(), - /*chosen_types=*/UserSelectableTypes()); + /*registered_types=*/UserSelectableTypeSet::All(), + /*selected_types=*/UserSelectableTypeSet::All()); sync_prefs.SetFirstSetupComplete(); service_->Initialize(); } @@ -289,7 +290,7 @@ TEST_F(ProfileSyncServiceTest, InitialState) { CreateService(ProfileSyncService::AUTO_START); InitializeForNthSync(); - const std::string& url = service()->sync_service_url().spec(); + const std::string& url = service()->GetSyncServiceUrlForDebugging().spec(); EXPECT_TRUE(url == internal::kSyncServerUrl || url == internal::kSyncDevServerUrl); } @@ -331,10 +332,10 @@ base::Time now = base::Time::Now(); sync_prefs.SetLastSyncedTime(now); sync_prefs.SetSyncRequested(true); - sync_prefs.SetDataTypesConfiguration( + sync_prefs.SetSelectedTypes( /*keep_everything_synced=*/true, - /*choosable_types=*/UserSelectableTypes(), - /*chosen_types=*/UserSelectableTypes()); + /*registered_types=*/UserSelectableTypeSet::All(), + /*selected_types=*/UserSelectableTypeSet::All()); service()->Initialize(); EXPECT_EQ(SyncService::DISABLE_REASON_NONE, service()->GetDisableReasons()); @@ -810,7 +811,7 @@ InitializeForNthSync(); ASSERT_EQ(SyncService::TransportState::ACTIVE, service()->GetTransportState()); - base::Time last_synced_time = service()->GetLastSyncedTime(); + base::Time last_synced_time = service()->GetLastSyncedTimeForDebugging(); ASSERT_LT(base::Time::Now() - last_synced_time, base::TimeDelta::FromMinutes(1)); @@ -823,7 +824,7 @@ service()->GetTransportState()); EXPECT_FALSE(service()->IsSyncFeatureEnabled()); - EXPECT_NE(service()->GetLastSyncedTime(), last_synced_time); + EXPECT_NE(service()->GetLastSyncedTimeForDebugging(), last_synced_time); } TEST_F(ProfileSyncServiceTest, CancelSyncAfterSignOut) { @@ -832,7 +833,7 @@ InitializeForNthSync(); ASSERT_EQ(SyncService::TransportState::ACTIVE, service()->GetTransportState()); - base::Time last_synced_time = service()->GetLastSyncedTime(); + base::Time last_synced_time = service()->GetLastSyncedTimeForDebugging(); ASSERT_LT(base::Time::Now() - last_synced_time, base::TimeDelta::FromMinutes(1)); @@ -1090,7 +1091,7 @@ ASSERT_EQ(SyncService::TransportState::ACTIVE, service()->GetTransportState()); - ASSERT_LT(base::Time::Now() - service()->GetLastSyncedTime(), + ASSERT_LT(base::Time::Now() - service()->GetLastSyncedTimeForDebugging(), base::TimeDelta::FromMinutes(1)); SyncProtocolError client_cmd; @@ -1113,7 +1114,7 @@ service()->GetDisableReasons()); EXPECT_EQ(SyncService::TransportState::DISABLED, service()->GetTransportState()); - EXPECT_TRUE(service()->GetLastSyncedTime().is_null()); + EXPECT_TRUE(service()->GetLastSyncedTimeForDebugging().is_null()); #endif EXPECT_FALSE(service()->IsSyncFeatureEnabled());
diff --git a/components/sync/driver/sync_service.cc b/components/sync/driver/sync_service.cc index d1a5925..b5a6b1f 100644 --- a/components/sync/driver/sync_service.cc +++ b/components/sync/driver/sync_service.cc
@@ -17,7 +17,9 @@ } bool SyncService::HasCompletedSyncCycle() const { - return GetLastCycleSnapshot().is_initialized(); + // Stats on the last Sync cycle are only available in internal "for debugging" + // information. Better to access that here than making clients do it. + return GetLastCycleSnapshotForDebugging().is_initialized(); } bool SyncService::IsSyncFeatureEnabled() const {
diff --git a/components/sync/driver/sync_service.h b/components/sync/driver/sync_service.h index ce7bc3dc..fd057a3 100644 --- a/components/sync/driver/sync_service.h +++ b/components/sync/driver/sync_service.h
@@ -302,10 +302,6 @@ // typically only change via a command-line option. virtual syncer::ModelTypeSet GetRegisteredDataTypes() const = 0; - // Returns the set of types which are enforced programmatically and can not - // be disabled by the user. - virtual syncer::ModelTypeSet GetForcedDataTypes() const = 0; - // Returns the set of types which are preferred for enabling. This is a // superset of the active types (see GetActiveDataTypes()). This also includes // any forced types. @@ -379,6 +375,8 @@ // Returns the state of the access token and token request, for display in // internals UI. + // TODO(crbug.com/953272): This method should also be marked as "ForDebugging" + // but it's currently still used by non-debugging UKM code. virtual SyncTokenStatus GetSyncTokenStatus() const = 0; // Initializes a struct of status indicators with data from the engine. @@ -387,10 +385,10 @@ virtual bool QueryDetailedSyncStatusForDebugging( SyncStatus* result) const = 0; - virtual base::Time GetLastSyncedTime() const = 0; + virtual base::Time GetLastSyncedTimeForDebugging() const = 0; // Returns some statistics on the most-recently completed sync cycle. - virtual SyncCycleSnapshot GetLastCycleSnapshot() const = 0; + virtual SyncCycleSnapshot GetLastCycleSnapshotForDebugging() const = 0; // Returns a ListValue indicating the status of all registered types. // @@ -405,10 +403,10 @@ // it easier to iterate over its elements when constructing that page. virtual std::unique_ptr<base::Value> GetTypeStatusMapForDebugging() = 0; - virtual const GURL& sync_service_url() const = 0; + virtual const GURL& GetSyncServiceUrlForDebugging() const = 0; - virtual std::string unrecoverable_error_message() const = 0; - virtual base::Location unrecoverable_error_location() const = 0; + virtual std::string GetUnrecoverableErrorMessageForDebugging() const = 0; + virtual base::Location GetUnrecoverableErrorLocationForDebugging() const = 0; virtual void AddProtocolEventObserver(ProtocolEventObserver* observer) = 0; virtual void RemoveProtocolEventObserver(ProtocolEventObserver* observer) = 0; @@ -424,7 +422,7 @@ // These requests can live a long time and return when you least expect it. // For safety, the callback should be bound to some sort of WeakPtr<> or // scoped_refptr<>. - virtual void GetAllNodes( + virtual void GetAllNodesForDebugging( const base::Callback<void(std::unique_ptr<base::ListValue>)>& callback) = 0;
diff --git a/components/sync/driver/sync_session_durations_metrics_recorder.cc b/components/sync/driver/sync_session_durations_metrics_recorder.cc index 2988d6b..d81c2bae 100644 --- a/components/sync/driver/sync_session_durations_metrics_recorder.cc +++ b/components/sync/driver/sync_session_durations_metrics_recorder.cc
@@ -188,7 +188,7 @@ // Sync is enabled, but we have an account issue. UpdateSyncAndAccountStatus(FeatureState::ON, FeatureState::OFF); } else if (sync_service_->IsSyncFeatureActive() && - sync_service_->GetLastCycleSnapshot().is_initialized()) { + sync_service_->HasCompletedSyncCycle()) { // Sync is on and running, we must have an account too. UpdateSyncAndAccountStatus(FeatureState::ON, FeatureState::ON); } else {
diff --git a/components/sync/driver/sync_type_preference_provider.h b/components/sync/driver/sync_type_preference_provider.h index f2995d3..0ce36db 100644 --- a/components/sync/driver/sync_type_preference_provider.h +++ b/components/sync/driver/sync_type_preference_provider.h
@@ -5,13 +5,13 @@ #ifndef COMPONENTS_SYNC_DRIVER_SYNC_TYPE_PREFERENCE_PROVIDER_H_ #define COMPONENTS_SYNC_DRIVER_SYNC_TYPE_PREFERENCE_PROVIDER_H_ -#include "components/sync/base/model_type.h" +#include "components/sync/base/user_selectable_type.h" namespace syncer { class SyncTypePreferenceProvider { public: - virtual ModelTypeSet GetForcedDataTypes() const = 0; + virtual UserSelectableTypeSet GetForcedTypes() const = 0; virtual bool IsEncryptEverythingAllowed() const = 0; protected:
diff --git a/components/sync/driver/sync_user_settings.h b/components/sync/driver/sync_user_settings.h index 9725cbd..f831304 100644 --- a/components/sync/driver/sync_user_settings.h +++ b/components/sync/driver/sync_user_settings.h
@@ -11,6 +11,7 @@ #include "base/time/time.h" #include "components/sync/base/model_type.h" #include "components/sync/base/passphrase_enums.h" +#include "components/sync/base/user_selectable_type.h" #include "components/sync/driver/data_type_encryption_handler.h" namespace syncer { @@ -39,16 +40,23 @@ virtual bool IsFirstSetupComplete() const = 0; virtual void SetFirstSetupComplete() = 0; - // The user's chosen data types. The "sync everything" flag means to sync all - // current and future data types. If it is set, then GetChosenDataTypes() will - // always return "all types". The chosen types are always a subset of - // syncer::UserSelectableTypes(). - // NOTE: By default, GetChosenDataTypes() returns "all types", even if the - // user has never enabled Sync, or if only Sync-the-transport is running. + // The user's selected types. The "sync everything" flag means to sync all + // current and future data types. If it is set, then GetSelectedTypes() will + // always return "all types". + // NOTE: By default, GetSelectedTypes() returns "all types", even if the user + // has never enabled Sync, or if only Sync-the-transport is running. virtual bool IsSyncEverythingEnabled() const = 0; - virtual syncer::ModelTypeSet GetChosenDataTypes() const = 0; - virtual void SetChosenDataTypes(bool sync_everything, - syncer::ModelTypeSet types) = 0; + virtual UserSelectableTypeSet GetSelectedTypes() const = 0; + virtual void SetSelectedTypes(bool sync_everything, + UserSelectableTypeSet types) = 0; + // Registered user selectable types are derived from registered model types. + // UserSelectableType is registered iff main corresponding ModelType is + // registered. + virtual UserSelectableTypeSet GetRegisteredSelectableTypes() const = 0; + // Returns the set of types which are enforced programmatically and can not + // be disabled by the user (e.g. enforced for supervised users). Types are + // not guaranteed to be registered. + virtual UserSelectableTypeSet GetForcedTypes() const = 0; // Encryption state. // Note that all of this state may only be queried or modified if the Sync @@ -64,7 +72,7 @@ virtual void EnableEncryptEverything() = 0; // The current set of encrypted data types. - syncer::ModelTypeSet GetEncryptedDataTypes() const override = 0; + ModelTypeSet GetEncryptedDataTypes() const override = 0; // Whether a passphrase is required for encryption or decryption to proceed. // Note that Sync might still be working fine if the user has disabled all // encrypted data types. @@ -82,7 +90,7 @@ // "encrypt everything" is disabled, or CUSTOM_PASSPHRASE if // "encrypt everything" is enabled. There are also some legacy passphrase // types which may still occur for a small number of users. - virtual syncer::PassphraseType GetPassphraseType() const = 0; + virtual PassphraseType GetPassphraseType() const = 0; // Asynchronously sets the passphrase to |passphrase| for encryption. virtual void SetEncryptionPassphrase(const std::string& passphrase) = 0;
diff --git a/components/sync/driver/sync_user_settings_impl.cc b/components/sync/driver/sync_user_settings_impl.cc index 727b28c5..9a95659b 100644 --- a/components/sync/driver/sync_user_settings_impl.cc +++ b/components/sync/driver/sync_user_settings_impl.cc
@@ -12,33 +12,12 @@ namespace { -ModelTypeSet ResolvePrefGroups(ModelTypeSet chosen_types) { - DCHECK(UserSelectableTypes().HasAll(chosen_types)); - ModelTypeSet types_with_groups = chosen_types; - if (chosen_types.Has(APPS)) { - types_with_groups.PutAll({APP_SETTINGS, APP_LIST, ARC_PACKAGE}); +ModelTypeSet ResolvePreferredTypes(UserSelectableTypeSet selected_types) { + ModelTypeSet preferred_types; + for (UserSelectableType type : selected_types) { + preferred_types.PutAll(UserSelectableTypeToAllModelTypes(type)); } - if (chosen_types.Has(AUTOFILL)) { - types_with_groups.PutAll( - {AUTOFILL_PROFILE, AUTOFILL_WALLET_DATA, AUTOFILL_WALLET_METADATA}); - } - if (chosen_types.Has(EXTENSIONS)) { - types_with_groups.Put(EXTENSION_SETTINGS); - } - if (chosen_types.Has(PREFERENCES)) { - types_with_groups.PutAll( - {DICTIONARY, PRIORITY_PREFERENCES, SEARCH_ENGINES}); - } - if (chosen_types.Has(TYPED_URLS)) { - types_with_groups.PutAll({HISTORY_DELETE_DIRECTIVES, SESSIONS, - FAVICON_IMAGES, FAVICON_TRACKING, USER_EVENTS}); - } - if (chosen_types.Has(PROXY_TABS)) { - types_with_groups.PutAll( - {SESSIONS, FAVICON_IMAGES, FAVICON_TRACKING, SEND_TAB_TO_SELF}); - } - - return types_with_groups; + return preferred_types; } } // namespace @@ -46,14 +25,14 @@ SyncUserSettingsImpl::SyncUserSettingsImpl( SyncServiceCrypto* crypto, SyncPrefs* prefs, - ModelTypeSet registered_types, - const base::RepeatingCallback<void(bool)>& sync_allowed_by_platform_changed, - const base::RepeatingCallback<bool()>& is_encrypt_everything_allowed) + const SyncTypePreferenceProvider* preference_provider, + ModelTypeSet registered_model_types, + const base::RepeatingCallback<void(bool)>& sync_allowed_by_platform_changed) : crypto_(crypto), prefs_(prefs), - registered_types_(registered_types), - sync_allowed_by_platform_changed_cb_(sync_allowed_by_platform_changed), - is_encrypt_everything_allowed_cb_(is_encrypt_everything_allowed) { + preference_provider_(preference_provider), + registered_model_types_(registered_model_types), + sync_allowed_by_platform_changed_cb_(sync_allowed_by_platform_changed) { DCHECK(crypto_); DCHECK(prefs_); } @@ -94,26 +73,42 @@ return prefs_->HasKeepEverythingSynced(); } -ModelTypeSet SyncUserSettingsImpl::GetChosenDataTypes() const { - ModelTypeSet types = prefs_->GetChosenDataTypes(); - DCHECK(UserSelectableTypes().HasAll(types)); - types.RetainAll(registered_types_); +UserSelectableTypeSet SyncUserSettingsImpl::GetSelectedTypes() const { + UserSelectableTypeSet types = prefs_->GetSelectedTypes(); + types.PutAll(GetForcedTypes()); + types.RetainAll(GetRegisteredSelectableTypes()); return types; } -void SyncUserSettingsImpl::SetChosenDataTypes(bool sync_everything, - ModelTypeSet types) { - DCHECK(UserSelectableTypes().HasAll(types)); - DCHECK(registered_types_.HasAll(types)); - prefs_->SetDataTypesConfiguration( - sync_everything, - /*choosable_types=*/ - Intersection(registered_types_, UserSelectableTypes()), - /*chosen_types=*/Intersection(registered_types_, types)); +void SyncUserSettingsImpl::SetSelectedTypes(bool sync_everything, + UserSelectableTypeSet types) { + UserSelectableTypeSet registered_types = GetRegisteredSelectableTypes(); + DCHECK(registered_types.HasAll(types)); + prefs_->SetSelectedTypes(sync_everything, registered_types, types); +} + +UserSelectableTypeSet SyncUserSettingsImpl::GetRegisteredSelectableTypes() + const { + UserSelectableTypeSet registered_types; + for (UserSelectableType type : UserSelectableTypeSet::All()) { + if (registered_model_types_.Has( + UserSelectableTypeToCanonicalModelType(type))) { + registered_types.Put(type); + } + } + return registered_types; +} + +UserSelectableTypeSet SyncUserSettingsImpl::GetForcedTypes() const { + if (preference_provider_) { + return preference_provider_->GetForcedTypes(); + } + return UserSelectableTypeSet(); } bool SyncUserSettingsImpl::IsEncryptEverythingAllowed() const { - return is_encrypt_everything_allowed_cb_.Run(); + return !preference_provider_ || + preference_provider_->IsEncryptEverythingAllowed(); } bool SyncUserSettingsImpl::IsEncryptEverythingEnabled() const { @@ -180,11 +175,11 @@ // implementation treats that corresponding type as preferred while // implementation without processing of this case won't treat that type // as preferred. - types = registered_types_; + types = registered_model_types_; } else { - types = ResolvePrefGroups(GetChosenDataTypes()); + types = ResolvePreferredTypes(GetSelectedTypes()); types.PutAll(AlwaysPreferredUserTypes()); - types.RetainAll(registered_types_); + types.RetainAll(registered_model_types_); } static_assert(44 == ModelType::NUM_ENTRIES, @@ -218,9 +213,9 @@ } // static -ModelTypeSet SyncUserSettingsImpl::ResolvePrefGroupsForTesting( - ModelTypeSet chosen_types) { - return ResolvePrefGroups(chosen_types); +ModelTypeSet SyncUserSettingsImpl::ResolvePreferredTypesForTesting( + UserSelectableTypeSet selected_types) { + return ResolvePreferredTypes(selected_types); } } // namespace syncer
diff --git a/components/sync/driver/sync_user_settings_impl.h b/components/sync/driver/sync_user_settings_impl.h index 3ddbb26..29e5b219 100644 --- a/components/sync/driver/sync_user_settings_impl.h +++ b/components/sync/driver/sync_user_settings_impl.h
@@ -9,6 +9,8 @@ #include "base/callback.h" #include "components/sync/base/model_type.h" +#include "components/sync/base/user_selectable_type.h" +#include "components/sync/driver/sync_type_preference_provider.h" #include "components/sync/driver/sync_user_settings.h" namespace syncer { @@ -19,13 +21,14 @@ class SyncUserSettingsImpl : public SyncUserSettings { public: // Both |crypto| and |prefs| must not be null, and must outlive this object. - SyncUserSettingsImpl( - SyncServiceCrypto* crypto, - SyncPrefs* prefs, - ModelTypeSet registered_types, - const base::RepeatingCallback<void(bool)>& - sync_allowed_by_platform_changed, - const base::RepeatingCallback<bool()>& is_encrypt_everything_allowed); + // |preference_provider| can be null, but must outlive this object if not + // null. + SyncUserSettingsImpl(SyncServiceCrypto* crypto, + SyncPrefs* prefs, + const SyncTypePreferenceProvider* preference_provider, + ModelTypeSet registered_types, + const base::RepeatingCallback<void(bool)>& + sync_allowed_by_platform_changed); ~SyncUserSettingsImpl() override; bool IsSyncRequested() const override; @@ -38,8 +41,11 @@ void SetFirstSetupComplete() override; bool IsSyncEverythingEnabled() const override; - ModelTypeSet GetChosenDataTypes() const override; - void SetChosenDataTypes(bool sync_everything, ModelTypeSet types) override; + UserSelectableTypeSet GetSelectedTypes() const override; + void SetSelectedTypes(bool sync_everything, + UserSelectableTypeSet types) override; + UserSelectableTypeSet GetRegisteredSelectableTypes() const override; + UserSelectableTypeSet GetForcedTypes() const override; bool IsEncryptEverythingAllowed() const override; bool IsEncryptEverythingEnabled() const override; @@ -61,17 +67,18 @@ bool IsEncryptedDatatypeEnabled() const; bool IsEncryptionPending() const; - // Converts ModelTypeSet of UserSelectableTypes() to ModelTypeSet of - // corresponding UserTypes() by resolving pref groups (e.g. {EXTENSIONS} - // becomes {EXTENSIONS, EXTENSION_SETTINGS}). - static ModelTypeSet ResolvePrefGroupsForTesting(ModelTypeSet chosen_types); + // Converts |selected_types| to ModelTypeSet of corresponding UserTypes() by + // resolving pref groups (e.g. {kExtensions} becomes {EXTENSIONS, + // EXTENSION_SETTINGS}). + static ModelTypeSet ResolvePreferredTypesForTesting( + UserSelectableTypeSet selected_types); private: SyncServiceCrypto* const crypto_; SyncPrefs* const prefs_; - const ModelTypeSet registered_types_; + const SyncTypePreferenceProvider* const preference_provider_; + const ModelTypeSet registered_model_types_; base::RepeatingCallback<void(bool)> sync_allowed_by_platform_changed_cb_; - base::RepeatingCallback<bool()> is_encrypt_everything_allowed_cb_; // Whether sync is currently allowed on this platform. bool sync_allowed_by_platform_ = true;
diff --git a/components/sync/driver/sync_user_settings_mock.h b/components/sync/driver/sync_user_settings_mock.h index 71b52237..980c67e 100644 --- a/components/sync/driver/sync_user_settings_mock.h +++ b/components/sync/driver/sync_user_settings_mock.h
@@ -27,19 +27,21 @@ MOCK_METHOD0(SetFirstSetupComplete, void()); MOCK_CONST_METHOD0(IsSyncEverythingEnabled, bool()); - MOCK_CONST_METHOD0(GetChosenDataTypes, syncer::ModelTypeSet()); - MOCK_METHOD2(SetChosenDataTypes, void(bool, syncer::ModelTypeSet)); + MOCK_CONST_METHOD0(GetSelectedTypes, UserSelectableTypeSet()); + MOCK_METHOD2(SetSelectedTypes, void(bool, UserSelectableTypeSet)); + MOCK_CONST_METHOD0(GetRegisteredSelectableTypes, UserSelectableTypeSet()); + MOCK_CONST_METHOD0(GetForcedTypes, UserSelectableTypeSet()); MOCK_CONST_METHOD0(IsEncryptEverythingAllowed, bool()); MOCK_CONST_METHOD0(IsEncryptEverythingEnabled, bool()); MOCK_METHOD0(EnableEncryptEverything, void()); - MOCK_CONST_METHOD0(GetEncryptedDataTypes, syncer::ModelTypeSet()); + MOCK_CONST_METHOD0(GetEncryptedDataTypes, ModelTypeSet()); MOCK_CONST_METHOD0(IsPassphraseRequired, bool()); MOCK_CONST_METHOD0(IsPassphraseRequiredForDecryption, bool()); MOCK_CONST_METHOD0(IsUsingSecondaryPassphrase, bool()); MOCK_CONST_METHOD0(GetExplicitPassphraseTime, base::Time()); - MOCK_CONST_METHOD0(GetPassphraseType, syncer::PassphraseType()); + MOCK_CONST_METHOD0(GetPassphraseType, PassphraseType()); MOCK_METHOD1(SetEncryptionPassphrase, void(const std::string&)); MOCK_METHOD1(SetDecryptionPassphrase, bool(const std::string&));
diff --git a/components/sync/driver/sync_user_settings_unittest.cc b/components/sync/driver/sync_user_settings_unittest.cc index 5a5fb75c..1d5f017 100644 --- a/components/sync/driver/sync_user_settings_unittest.cc +++ b/components/sync/driver/sync_user_settings_unittest.cc
@@ -39,11 +39,10 @@ std::unique_ptr<SyncUserSettingsImpl> MakeSyncUserSettings( ModelTypeSet registered_types) { return std::make_unique<SyncUserSettingsImpl>( - sync_service_crypto_.get(), sync_prefs_.get(), registered_types, + sync_service_crypto_.get(), sync_prefs_.get(), + /*preference_provider=*/nullptr, registered_types, /*sync_allowed_by_platform_changed=*/ - base::DoNothing(), - /*is_encrypt_everything_allowed=*/ - base::BindRepeating([] { return true; })); + base::DoNothing()); } // The order of fields matters because it determines destruction order and @@ -71,9 +70,9 @@ MakeSyncUserSettings(registered_types); // Enable all other types. - sync_user_settings->SetChosenDataTypes( + sync_user_settings->SetSelectedTypes( /*keep_everything_synced=*/false, - /*chosen_types=*/Intersection(UserSelectableTypes(), registered_types)); + /*selected_types=*/sync_user_settings->GetRegisteredSelectableTypes()); // Manually enable typed urls (to simulate the old world) and perform the // migration to check it doesn't affect the proxy tab preference value. @@ -110,9 +109,9 @@ EXPECT_TRUE(sync_user_settings->IsSyncEverythingEnabled()); EXPECT_EQ(UserTypes(), GetPreferredUserTypes(*sync_user_settings)); - for (ModelType type : UserSelectableTypes()) { - sync_user_settings->SetChosenDataTypes(/*sync_everything=*/true, - /*chosen_types=*/ModelTypeSet{type}); + for (UserSelectableType type : UserSelectableTypeSet::All()) { + sync_user_settings->SetSelectedTypes(/*sync_everything=*/true, + /*selected_type=*/{type}); EXPECT_EQ(UserTypes(), GetPreferredUserTypes(*sync_user_settings)); } } @@ -121,37 +120,39 @@ std::unique_ptr<SyncUserSettingsImpl> sync_user_settings = MakeSyncUserSettings(UserTypes()); - sync_user_settings->SetChosenDataTypes(/*sync_everything=*/false, - /*chosen_types=*/ModelTypeSet()); + sync_user_settings->SetSelectedTypes( + /*sync_everything=*/false, + /*selected_types=*/UserSelectableTypeSet()); ASSERT_NE(UserTypes(), GetPreferredUserTypes(*sync_user_settings)); - for (ModelType type : UserSelectableTypes()) { - ModelTypeSet expected_preferred_types{type}; - if (type == AUTOFILL) { + for (UserSelectableType type : UserSelectableTypeSet::All()) { + ModelTypeSet expected_preferred_types{ + UserSelectableTypeToCanonicalModelType(type)}; + if (type == UserSelectableType::kAutofill) { expected_preferred_types.Put(AUTOFILL_PROFILE); expected_preferred_types.Put(AUTOFILL_WALLET_DATA); expected_preferred_types.Put(AUTOFILL_WALLET_METADATA); } - if (type == PREFERENCES) { + if (type == UserSelectableType::kPreferences) { expected_preferred_types.Put(DICTIONARY); expected_preferred_types.Put(PRIORITY_PREFERENCES); expected_preferred_types.Put(SEARCH_ENGINES); } - if (type == APPS) { + if (type == UserSelectableType::kApps) { expected_preferred_types.Put(APP_LIST); expected_preferred_types.Put(APP_SETTINGS); expected_preferred_types.Put(ARC_PACKAGE); } - if (type == EXTENSIONS) { + if (type == UserSelectableType::kExtensions) { expected_preferred_types.Put(EXTENSION_SETTINGS); } - if (type == TYPED_URLS) { + if (type == UserSelectableType::kHistory) { expected_preferred_types.Put(HISTORY_DELETE_DIRECTIVES); expected_preferred_types.Put(SESSIONS); expected_preferred_types.Put(FAVICON_IMAGES); expected_preferred_types.Put(FAVICON_TRACKING); expected_preferred_types.Put(USER_EVENTS); } - if (type == PROXY_TABS) { + if (type == UserSelectableType::kTabs) { expected_preferred_types.Put(SESSIONS); expected_preferred_types.Put(FAVICON_IMAGES); expected_preferred_types.Put(FAVICON_TRACKING); @@ -159,8 +160,8 @@ } expected_preferred_types.PutAll(AlwaysPreferredUserTypes()); - sync_user_settings->SetChosenDataTypes(/*sync_everything=*/false, - /*chosen_types=*/ModelTypeSet{type}); + sync_user_settings->SetSelectedTypes(/*sync_everything=*/false, + /*selected_types=*/{type}); EXPECT_EQ(expected_preferred_types, GetPreferredUserTypes(*sync_user_settings)); } @@ -171,18 +172,18 @@ std::unique_ptr<SyncUserSettingsImpl> sync_user_settings = MakeSyncUserSettings(UserTypes()); EXPECT_TRUE(sync_user_settings->GetPreferredDataTypes().Has(DEVICE_INFO)); - sync_user_settings->SetChosenDataTypes( + sync_user_settings->SetSelectedTypes( /*keep_everything_synced=*/true, - /*chosen_types=*/UserSelectableTypes()); + /*selected_types=*/UserSelectableTypeSet::All()); EXPECT_TRUE(sync_user_settings->GetPreferredDataTypes().Has(DEVICE_INFO)); - sync_user_settings->SetChosenDataTypes( + sync_user_settings->SetSelectedTypes( /*keep_everything_synced=*/false, - /*chosen_types=*/UserSelectableTypes()); + /*selected_types=*/UserSelectableTypeSet::All()); EXPECT_TRUE(sync_user_settings->GetPreferredDataTypes().Has(DEVICE_INFO)); sync_user_settings = MakeSyncUserSettings(ModelTypeSet(DEVICE_INFO)); - sync_user_settings->SetChosenDataTypes( + sync_user_settings->SetSelectedTypes( /*keep_everything_synced=*/false, - /*chosen_types=*/ModelTypeSet()); + /*selected_types=*/UserSelectableTypeSet()); EXPECT_TRUE(sync_user_settings->GetPreferredDataTypes().Has(DEVICE_INFO)); } @@ -191,18 +192,18 @@ std::unique_ptr<SyncUserSettingsImpl> sync_user_settings = MakeSyncUserSettings(UserTypes()); EXPECT_TRUE(sync_user_settings->GetPreferredDataTypes().Has(USER_CONSENTS)); - sync_user_settings->SetChosenDataTypes( + sync_user_settings->SetSelectedTypes( /*keep_everything_synced=*/true, - /*chosen_types=*/UserSelectableTypes()); + /*selected_types=*/UserSelectableTypeSet::All()); EXPECT_TRUE(sync_user_settings->GetPreferredDataTypes().Has(USER_CONSENTS)); - sync_user_settings->SetChosenDataTypes( + sync_user_settings->SetSelectedTypes( /*keep_everything_synced=*/false, - /*chosen_types=*/UserSelectableTypes()); + /*selected_types=*/UserSelectableTypeSet::All()); EXPECT_TRUE(sync_user_settings->GetPreferredDataTypes().Has(USER_CONSENTS)); sync_user_settings = MakeSyncUserSettings(ModelTypeSet(USER_CONSENTS)); - sync_user_settings->SetChosenDataTypes( + sync_user_settings->SetSelectedTypes( /*keep_everything_synced=*/false, - /*chosen_types=*/ModelTypeSet()); + /*selected_types=*/UserSelectableTypeSet()); EXPECT_TRUE(sync_user_settings->GetPreferredDataTypes().Has(USER_CONSENTS)); }
diff --git a/components/sync/driver/test_sync_service.cc b/components/sync/driver/test_sync_service.cc index 14d50d5..7a7663cd 100644 --- a/components/sync/driver/test_sync_service.cc +++ b/components/sync/driver/test_sync_service.cc
@@ -171,10 +171,6 @@ return ModelTypeSet::All(); } -ModelTypeSet TestSyncService::GetForcedDataTypes() const { - return ModelTypeSet(); -} - ModelTypeSet TestSyncService::GetPreferredDataTypes() const { return preferred_data_types_; } @@ -225,11 +221,11 @@ return detailed_sync_status_engine_available_; } -base::Time TestSyncService::GetLastSyncedTime() const { +base::Time TestSyncService::GetLastSyncedTimeForDebugging() const { return base::Time(); } -SyncCycleSnapshot TestSyncService::GetLastCycleSnapshot() const { +SyncCycleSnapshot TestSyncService::GetLastCycleSnapshotForDebugging() const { return last_cycle_snapshot_; } @@ -237,15 +233,16 @@ return std::make_unique<base::ListValue>(); } -const GURL& TestSyncService::sync_service_url() const { +const GURL& TestSyncService::GetSyncServiceUrlForDebugging() const { return sync_service_url_; } -std::string TestSyncService::unrecoverable_error_message() const { +std::string TestSyncService::GetUnrecoverableErrorMessageForDebugging() const { return std::string(); } -base::Location TestSyncService::unrecoverable_error_location() const { +base::Location TestSyncService::GetUnrecoverableErrorLocationForDebugging() + const { return base::Location(); } @@ -265,7 +262,7 @@ return base::WeakPtr<JsController>(); } -void TestSyncService::GetAllNodes( +void TestSyncService::GetAllNodesForDebugging( const base::Callback<void(std::unique_ptr<base::ListValue>)>& callback) {} void TestSyncService::SetInvalidationsForSessionsEnabled(bool enabled) {}
diff --git a/components/sync/driver/test_sync_service.h b/components/sync/driver/test_sync_service.h index fee7b33..cfcf77ff 100644 --- a/components/sync/driver/test_sync_service.h +++ b/components/sync/driver/test_sync_service.h
@@ -66,7 +66,6 @@ bool IsSetupInProgress() const override; ModelTypeSet GetRegisteredDataTypes() const override; - ModelTypeSet GetForcedDataTypes() const override; ModelTypeSet GetPreferredDataTypes() const override; ModelTypeSet GetActiveDataTypes() const override; @@ -83,19 +82,20 @@ SyncTokenStatus GetSyncTokenStatus() const override; bool QueryDetailedSyncStatusForDebugging(SyncStatus* result) const override; - base::Time GetLastSyncedTime() const override; - SyncCycleSnapshot GetLastCycleSnapshot() const override; + base::Time GetLastSyncedTimeForDebugging() const override; + SyncCycleSnapshot GetLastCycleSnapshotForDebugging() const override; std::unique_ptr<base::Value> GetTypeStatusMapForDebugging() override; - const GURL& sync_service_url() const override; - std::string unrecoverable_error_message() const override; - base::Location unrecoverable_error_location() const override; + const GURL& GetSyncServiceUrlForDebugging() const override; + std::string GetUnrecoverableErrorMessageForDebugging() const override; + base::Location GetUnrecoverableErrorLocationForDebugging() const override; void AddProtocolEventObserver(ProtocolEventObserver* observer) override; void RemoveProtocolEventObserver(ProtocolEventObserver* observer) override; void AddTypeDebugInfoObserver(TypeDebugInfoObserver* observer) override; void RemoveTypeDebugInfoObserver(TypeDebugInfoObserver* observer) override; base::WeakPtr<JsController> GetJsController() override; - void GetAllNodes(const base::Callback<void(std::unique_ptr<base::ListValue>)>& - callback) override; + void GetAllNodesForDebugging( + const base::Callback<void(std::unique_ptr<base::ListValue>)>& callback) + override; void SetInvalidationsForSessionsEnabled(bool enabled) override; // KeyedService implementation.
diff --git a/components/sync/driver/test_sync_user_settings.cc b/components/sync/driver/test_sync_user_settings.cc index 04948600..741d4ee 100644 --- a/components/sync/driver/test_sync_user_settings.cc +++ b/components/sync/driver/test_sync_user_settings.cc
@@ -58,25 +58,42 @@ return sync_everything_enabled_; } -ModelTypeSet TestSyncUserSettings::GetChosenDataTypes() const { - ModelTypeSet types = service_->GetPreferredDataTypes(); - types.RetainAll(UserSelectableTypes()); - return types; +UserSelectableTypeSet TestSyncUserSettings::GetSelectedTypes() const { + // TODO(crbug.com/950874): consider getting rid of the logic inversion here. + // service_.preferred_type should be derived from selected types, not vice + // versa. + ModelTypeSet preferred_types = service_->GetPreferredDataTypes(); + UserSelectableTypeSet selected_types; + for (UserSelectableType type : UserSelectableTypeSet::All()) { + if (preferred_types.Has(UserSelectableTypeToCanonicalModelType(type))) { + selected_types.Put(type); + } + } + return selected_types; } -void TestSyncUserSettings::SetChosenDataTypes(bool sync_everything, - ModelTypeSet types) { +void TestSyncUserSettings::SetSelectedTypes(bool sync_everything, + UserSelectableTypeSet types) { sync_everything_enabled_ = sync_everything; syncer::ModelTypeSet preferred_types; if (sync_everything_enabled_) { preferred_types = syncer::ModelTypeSet::All(); } else { preferred_types = - syncer::SyncUserSettingsImpl::ResolvePrefGroupsForTesting(types); + syncer::SyncUserSettingsImpl::ResolvePreferredTypesForTesting(types); } service_->SetPreferredDataTypes(preferred_types); } +UserSelectableTypeSet TestSyncUserSettings::GetRegisteredSelectableTypes() + const { + return UserSelectableTypeSet::All(); +} + +UserSelectableTypeSet TestSyncUserSettings::GetForcedTypes() const { + return {}; +} + bool TestSyncUserSettings::IsEncryptEverythingAllowed() const { return true; }
diff --git a/components/sync/driver/test_sync_user_settings.h b/components/sync/driver/test_sync_user_settings.h index 6dab59e..ef3bf5a4 100644 --- a/components/sync/driver/test_sync_user_settings.h +++ b/components/sync/driver/test_sync_user_settings.h
@@ -30,8 +30,11 @@ void SetFirstSetupComplete() override; bool IsSyncEverythingEnabled() const override; - ModelTypeSet GetChosenDataTypes() const override; - void SetChosenDataTypes(bool sync_everything, ModelTypeSet types) override; + UserSelectableTypeSet GetSelectedTypes() const override; + void SetSelectedTypes(bool sync_everything, + UserSelectableTypeSet types) override; + UserSelectableTypeSet GetRegisteredSelectableTypes() const override; + UserSelectableTypeSet GetForcedTypes() const override; bool IsEncryptEverythingAllowed() const override; bool IsEncryptEverythingEnabled() const override;
diff --git a/components/sync/model_impl/client_tag_based_model_type_processor.cc b/components/sync/model_impl/client_tag_based_model_type_processor.cc index 48ca0fc..56c44d6 100644 --- a/components/sync/model_impl/client_tag_based_model_type_processor.cc +++ b/components/sync/model_impl/client_tag_based_model_type_processor.cc
@@ -558,7 +558,13 @@ GetLocalChangesCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_GT(max_entries, 0U); - DCHECK(!model_error_); + // If there is a model error, it must have been reported already but hasn't + // reached the sync engine yet. In this case return directly to avoid + // interactions with the bridge. + if (model_error_) { + std::move(callback).Run(CommitRequestDataList()); + return; + } std::vector<std::string> entities_requiring_data; for (const auto& kv : entities_) {
diff --git a/components/sync/nigori/nigori_model_type_processor.cc b/components/sync/nigori/nigori_model_type_processor.cc index 31d22fa..0de7874 100644 --- a/components/sync/nigori/nigori_model_type_processor.cc +++ b/components/sync/nigori/nigori_model_type_processor.cc
@@ -7,6 +7,7 @@ #include "components/sync/base/time.h" #include "components/sync/engine/commit_queue.h" #include "components/sync/model_impl/processor_entity.h" +#include "components/sync/nigori/nigori_sync_bridge.h" namespace syncer { @@ -27,11 +28,22 @@ void NigoriModelTypeProcessor::ConnectSync( std::unique_ptr<CommitQueue> worker) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - NOTIMPLEMENTED(); + DVLOG(1) << "Successfully connected Encryption Keys"; + + worker_ = std::move(worker); + NudgeForCommitIfNeeded(); } void NigoriModelTypeProcessor::DisconnectSync() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(IsConnected()); + + DVLOG(1) << "Disconnecting sync for Encryption Keys"; + // TODO(mamir): weak_ptr_factory_for_worker_.InvalidateWeakPtrs(); + worker_.reset(); + if (entity_) { + entity_->ClearTransientSyncState(); + } NOTIMPLEMENTED(); } @@ -39,7 +51,36 @@ size_t max_entries, GetLocalChangesCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - NOTIMPLEMENTED(); + DCHECK_GT(max_entries, 0U); + // If there is a model error, it must have been reported already but hasn't + // reached the sync engine yet. In this case return directly to avoid + // interactions with the bridge. + if (model_error_) { + std::move(callback).Run(CommitRequestDataList()); + return; + } + + DCHECK(entity_); + + // No local changes to commit. + if (!entity_->RequiresCommitRequest()) { + std::move(callback).Run(CommitRequestDataList()); + return; + } + + if (entity_->RequiresCommitData()) { + // SetCommitData will update EntityData's fields with values from + // metadata. + entity_->SetCommitData(bridge_->GetData()); + } + + auto commit_request_data = std::make_unique<CommitRequestData>(); + entity_->InitializeCommitRequestData(commit_request_data.get()); + + CommitRequestDataList commit_request_data_list; + commit_request_data_list.push_back(std::move(commit_request_data)); + + std::move(callback).Run(std::move(commit_request_data_list)); } void NigoriModelTypeProcessor::OnCommitCompleted( @@ -138,8 +179,7 @@ } entity_->MakeLocalChange(std::move(entity_data)); - // TODO(mamir): NudgeForCommitIfNeeded(); - NOTIMPLEMENTED(); + NudgeForCommitIfNeeded(); } NigoriMetadataBatch NigoriModelTypeProcessor::GetMetadata() { @@ -158,4 +198,27 @@ return model_type_state_.initial_sync_done(); } +bool NigoriModelTypeProcessor::IsConnected() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return worker_ != nullptr; +} + +void NigoriModelTypeProcessor::NudgeForCommitIfNeeded() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // Don't bother sending anything if there's no one to send to. + if (!IsConnected()) { + return; + } + + // Don't send anything if the type is not ready to handle commits. + if (!model_type_state_.initial_sync_done()) { + return; + } + + // Nudge worker if there are any entities with local changes. + if (entity_->RequiresCommitRequest()) { + worker_->NudgeForCommit(); + } +} + } // namespace syncer
diff --git a/components/sync/nigori/nigori_model_type_processor.h b/components/sync/nigori/nigori_model_type_processor.h index b87a957..b16b5b9 100644 --- a/components/sync/nigori/nigori_model_type_processor.h +++ b/components/sync/nigori/nigori_model_type_processor.h
@@ -53,6 +53,13 @@ private: bool IsTrackingMetadata(); + + // Returns true if the handshake with sync thread is complete. + bool IsConnected() const; + + // Nudges worker if there are any local changes to be committed. + void NudgeForCommitIfNeeded() const; + // The bridge owns this processor instance so the pointer should never become // invalid. NigoriSyncBridge* bridge_; @@ -70,6 +77,12 @@ std::unique_ptr<ProcessorEntity> entity_; + // Reference to the CommitQueue. + // + // The interface hides the posting of tasks across threads as well as the + // CommitQueue's implementation. Both of these features are useful in tests. + std::unique_ptr<CommitQueue> worker_; + SEQUENCE_CHECKER(sequence_checker_); DISALLOW_COPY_AND_ASSIGN(NigoriModelTypeProcessor);
diff --git a/components/sync/nigori/nigori_model_type_processor_unittest.cc b/components/sync/nigori/nigori_model_type_processor_unittest.cc index 04df18c..a878e84 100644 --- a/components/sync/nigori/nigori_model_type_processor_unittest.cc +++ b/components/sync/nigori/nigori_model_type_processor_unittest.cc
@@ -7,7 +7,9 @@ #include <memory> #include <string> +#include "base/bind.h" #include "components/sync/base/time.h" +#include "components/sync/engine/commit_queue.h" #include "components/sync/nigori/nigori_sync_bridge.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -21,6 +23,11 @@ const char kNigoriNonUniqueName[] = "nigori"; +void CaptureCommitRequest(CommitRequestDataList* dst, + CommitRequestDataList&& src) { + *dst = std::move(src); +} + class MockNigoriSyncBridge : public NigoriSyncBridge { public: MockNigoriSyncBridge() = default; @@ -38,9 +45,20 @@ MOCK_METHOD0(ApplyDisableSyncChanges, void()); }; +class MockCommitQueue : public CommitQueue { + public: + MockCommitQueue() = default; + ~MockCommitQueue() = default; + + MOCK_METHOD0(NudgeForCommit, void()); +}; + class NigoriModelTypeProcessorTest : public testing::Test { public: - NigoriModelTypeProcessorTest() = default; + NigoriModelTypeProcessorTest() { + mock_commit_queue_ = std::make_unique<testing::NiceMock<MockCommitQueue>>(); + mock_commit_queue_ptr_ = mock_commit_queue_.get(); + } void SimulateModelReadyToSyncWithInitialSyncDone() { NigoriMetadataBatch nigori_metadata_batch; @@ -49,18 +67,27 @@ nigori_metadata_batch.entity_metadata->set_creation_time( TimeToProtoTime(base::Time::Now())); nigori_metadata_batch.entity_metadata->set_sequence_number(0); + nigori_metadata_batch.entity_metadata->set_acked_sequence_number(0); processor_.ModelReadyToSync(mock_nigori_sync_bridge(), std::move(nigori_metadata_batch)); } + void SimulateConnectSync() { + processor_.ConnectSync(std::move(mock_commit_queue_)); + } + MockNigoriSyncBridge* mock_nigori_sync_bridge() { return &mock_nigori_sync_bridge_; } + MockCommitQueue* mock_commit_queue() { return mock_commit_queue_ptr_; } + NigoriModelTypeProcessor* processor() { return &processor_; } private: testing::NiceMock<MockNigoriSyncBridge> mock_nigori_sync_bridge_; + std::unique_ptr<testing::NiceMock<MockCommitQueue>> mock_commit_queue_; + MockCommitQueue* mock_commit_queue_ptr_; NigoriModelTypeProcessor processor_; }; @@ -115,6 +142,57 @@ Eq(entity_metadata1->sequence_number() + 1)); } +TEST_F(NigoriModelTypeProcessorTest, ShouldGetEmptyLocalChanges) { + SimulateModelReadyToSyncWithInitialSyncDone(); + CommitRequestDataList commit_request; + processor()->GetLocalChanges( + /*max_entries=*/10, + base::BindOnce(&CaptureCommitRequest, &commit_request)); + EXPECT_EQ(0U, commit_request.size()); +} + +TEST_F(NigoriModelTypeProcessorTest, ShouldGetLocalChangesWhenPut) { + SimulateModelReadyToSyncWithInitialSyncDone(); + + auto entity_data = std::make_unique<syncer::EntityData>(); + entity_data->specifics.mutable_nigori(); + entity_data->non_unique_name = kNigoriNonUniqueName; + + processor()->Put(std::move(entity_data)); + CommitRequestDataList commit_request; + processor()->GetLocalChanges( + /*max_entries=*/10, + base::BindOnce(&CaptureCommitRequest, &commit_request)); + ASSERT_EQ(1U, commit_request.size()); + EXPECT_EQ(kNigoriNonUniqueName, commit_request[0]->entity->non_unique_name); +} + +TEST_F(NigoriModelTypeProcessorTest, + ShouldNudgeForCommitUponConnectSyncIfReadyToSyncAndLocalChanges) { + SimulateModelReadyToSyncWithInitialSyncDone(); + + auto entity_data = std::make_unique<syncer::EntityData>(); + entity_data->specifics.mutable_nigori(); + entity_data->non_unique_name = kNigoriNonUniqueName; + + processor()->Put(std::move(entity_data)); + + EXPECT_CALL(*mock_commit_queue(), NudgeForCommit()); + SimulateConnectSync(); +} + +TEST_F(NigoriModelTypeProcessorTest, ShouldNudgeForCommitUponPutIfReadyToSync) { + SimulateModelReadyToSyncWithInitialSyncDone(); + SimulateConnectSync(); + + auto entity_data = std::make_unique<syncer::EntityData>(); + entity_data->specifics.mutable_nigori(); + entity_data->non_unique_name = kNigoriNonUniqueName; + + EXPECT_CALL(*mock_commit_queue(), NudgeForCommit()); + processor()->Put(std::move(entity_data)); +} + } // namespace } // namespace syncer
diff --git a/components/sync_bookmarks/OWNERS b/components/sync_bookmarks/OWNERS index 261ab18..ef97383 100644 --- a/components/sync_bookmarks/OWNERS +++ b/components/sync_bookmarks/OWNERS
@@ -1 +1,3 @@ file://components/sync/OWNERS + +# COMPONENT: Services>Sync
diff --git a/components/sync_preferences/OWNERS b/components/sync_preferences/OWNERS index 2142ec0..ede3ca9 100644 --- a/components/sync_preferences/OWNERS +++ b/components/sync_preferences/OWNERS
@@ -2,4 +2,4 @@ battre@chromium.org gab@chromium.org -# COMPONENT: UI>Browser>Preferences +# COMPONENT: Services>Sync
diff --git a/components/sync_sessions/OWNERS b/components/sync_sessions/OWNERS index 261ab18..ef97383 100644 --- a/components/sync_sessions/OWNERS +++ b/components/sync_sessions/OWNERS
@@ -1 +1,3 @@ file://components/sync/OWNERS + +# COMPONENT: Services>Sync
diff --git a/components/sync_ui_strings_grdp/OWNERS b/components/sync_ui_strings_grdp/OWNERS index 261ab18..ef97383 100644 --- a/components/sync_ui_strings_grdp/OWNERS +++ b/components/sync_ui_strings_grdp/OWNERS
@@ -1 +1,3 @@ file://components/sync/OWNERS + +# COMPONENT: Services>Sync
diff --git a/components/test/data/autofill_assistant/autofill_assistant_target_website.html b/components/test/data/autofill_assistant/autofill_assistant_target_website.html index c66faa8..6c995ab 100644 --- a/components/test/data/autofill_assistant/autofill_assistant_target_website.html +++ b/components/test/data/autofill_assistant/autofill_assistant_target_website.html
@@ -174,21 +174,6 @@ </script> </div> - <div> - <input id="input_js_event_with_timeout" type="text"> - <!-- Uses the 'key' property of a keydown event. --> - <script> - var t = document.getElementById("input_js_event_with_timeout"); - t.addEventListener('keydown', e => { - var value = e.target.value; - if (value.length === 3) { - e.preventDefault(); - setTimeout(() => {e.target.value = value + ' ' + e.key}, 10); - } - }); - </script> - </div> - <div id="testOuterHtml"><span>Span</span><p>Paragraph</p></div> <div id="hidden" style="display: none;">This text is hidden</div>
diff --git a/components/unified_consent/unified_consent_metrics.cc b/components/unified_consent/unified_consent_metrics.cc index 0a4c0e0..3c8b06a1 100644 --- a/components/unified_consent/unified_consent_metrics.cc +++ b/components/unified_consent/unified_consent_metrics.cc
@@ -10,7 +10,7 @@ #include "build/build_config.h" #include "components/autofill/core/common/autofill_prefs.h" #include "components/prefs/pref_service.h" -#include "components/sync/base/model_type.h" +#include "components/sync/base/user_selectable_type.h" #include "components/sync/driver/sync_user_settings.h" #include "components/unified_consent/pref_names.h" @@ -78,21 +78,30 @@ bool metric_recorded = false; - std::vector<std::pair<SyncDataType, syncer::ModelType>> sync_types; - sync_types.emplace_back(SyncDataType::kBookmarks, syncer::BOOKMARKS); - sync_types.emplace_back(SyncDataType::kHistory, syncer::TYPED_URLS); - sync_types.emplace_back(SyncDataType::kSettings, syncer::PREFERENCES); - sync_types.emplace_back(SyncDataType::kTabs, syncer::PROXY_TABS); - sync_types.emplace_back(SyncDataType::kPasswords, syncer::PASSWORDS); - sync_types.emplace_back(SyncDataType::kAutofill, syncer::AUTOFILL); + std::vector<std::pair<SyncDataType, syncer::UserSelectableType>> sync_types; + sync_types.emplace_back(SyncDataType::kBookmarks, + syncer::UserSelectableType::kBookmarks); + sync_types.emplace_back(SyncDataType::kHistory, + syncer::UserSelectableType::kHistory); + sync_types.emplace_back(SyncDataType::kSettings, + syncer::UserSelectableType::kPreferences); + sync_types.emplace_back(SyncDataType::kTabs, + syncer::UserSelectableType::kTabs); + sync_types.emplace_back(SyncDataType::kPasswords, + syncer::UserSelectableType::kPasswords); + sync_types.emplace_back(SyncDataType::kAutofill, + syncer::UserSelectableType::kAutofill); #if !defined(OS_ANDROID) - sync_types.emplace_back(SyncDataType::kApps, syncer::APPS); - sync_types.emplace_back(SyncDataType::kExtensions, syncer::EXTENSIONS); - sync_types.emplace_back(SyncDataType::kThemes, syncer::THEMES); + sync_types.emplace_back(SyncDataType::kApps, + syncer::UserSelectableType::kApps); + sync_types.emplace_back(SyncDataType::kExtensions, + syncer::UserSelectableType::kExtensions); + sync_types.emplace_back(SyncDataType::kThemes, + syncer::UserSelectableType::kThemes); #endif for (const auto& data_type : sync_types) { - if (!sync_settings->GetChosenDataTypes().Has(data_type.second)) { + if (!sync_settings->GetSelectedTypes().Has(data_type.second)) { RecordSyncDataTypeSample(data_type.first); metric_recorded = true; }
diff --git a/components/unified_consent/unified_consent_service.cc b/components/unified_consent/unified_consent_service.cc index f890d5f6..1523882 100644 --- a/components/unified_consent/unified_consent_service.cc +++ b/components/unified_consent/unified_consent_service.cc
@@ -10,7 +10,7 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "build/build_config.h" #include "components/pref_registry/pref_registry_syncable.h" -#include "components/sync/base/model_type.h" +#include "components/sync/base/user_selectable_type.h" #include "components/sync/driver/sync_service.h" #include "components/sync/driver/sync_user_settings.h" #include "components/sync_preferences/pref_service_syncable.h" @@ -187,8 +187,8 @@ // consent. bool url_keyed_metrics_enabled = sync_service_->IsSyncFeatureEnabled() && - sync_service_->GetUserSettings()->GetChosenDataTypes().Has( - syncer::TYPED_URLS) && + sync_service_->GetUserSettings()->GetSelectedTypes().Has( + syncer::UserSelectableType::kHistory) && !sync_service_->GetUserSettings()->IsUsingSecondaryPassphrase(); SetUrlKeyedAnonymizedDataCollectionEnabled(url_keyed_metrics_enabled); }
diff --git a/components/unified_consent/unified_consent_service_unittest.cc b/components/unified_consent/unified_consent_service_unittest.cc index 19aec0a..a8cea518 100644 --- a/components/unified_consent/unified_consent_service_unittest.cc +++ b/components/unified_consent/unified_consent_service_unittest.cc
@@ -120,8 +120,8 @@ TEST_F(UnifiedConsentServiceTest, Migration_UpdateSettings) { // Create user that syncs history and has no custom passphrase. identity_test_environment_.SetPrimaryAccount("testaccount"); - sync_service_.GetUserSettings()->SetChosenDataTypes( - false, syncer::ModelTypeSet(syncer::TYPED_URLS)); + sync_service_.GetUserSettings()->SetSelectedTypes( + false, {syncer::UserSelectableType::kHistory}); EXPECT_TRUE(sync_service_.IsSyncFeatureActive()); // Url keyed data collection is off before the migration. EXPECT_FALSE(pref_service_.GetBoolean(
diff --git a/components/update_client/net/network_impl.cc b/components/update_client/net/network_impl.cc index 8b2959d..c78853e 100644 --- a/components/update_client/net/network_impl.cc +++ b/components/update_client/net/network_impl.cc
@@ -116,7 +116,7 @@ simple_url_loader_->SetRetryOptions( kMaxRetriesOnNetworkChange, network::SimpleURLLoader::RETRY_ON_NETWORK_CHANGE); - simple_url_loader_->AttachStringForUpload(post_data, "application/xml"); + simple_url_loader_->AttachStringForUpload(post_data, "application/json"); simple_url_loader_->SetOnResponseStartedCallback(base::BindOnce( &NetworkFetcherImpl::OnResponseStartedCallback, base::Unretained(this), std::move(response_started_callback)));
diff --git a/components/viz/client/hit_test_data_provider_draw_quad_unittest.cc b/components/viz/client/hit_test_data_provider_draw_quad_unittest.cc index 222748e..b9b678f8 100644 --- a/components/viz/client/hit_test_data_provider_draw_quad_unittest.cc +++ b/components/viz/client/hit_test_data_provider_draw_quad_unittest.cc
@@ -412,4 +412,158 @@ hit_test_region_list_2->regions[0].rect); } +// Test to ensure that render_pass_list caching works correctly. +TEST(HitTestDataProviderDrawQuad, HitTestDataRenderPassListCache) { + std::unique_ptr<HitTestDataProvider> hit_test_data_provider = + std::make_unique<HitTestDataProviderDrawQuad>( + true /* should_ask_for_child_region */, + true /* root_accepts_events */); + + constexpr gfx::Rect frame_rect(1024, 768); + constexpr gfx::Rect child_rect(200, 100); + gfx::Transform invertible_transform; + invertible_transform.Translate(-200, -100); + + RenderPassList pass_list; + + // A RenderPass that has two SurfaceDrawQuad. + SurfaceId child_surface_id1 = CreateChildSurfaceId(2); + SurfaceId child_surface_id2 = CreateChildSurfaceId(3); + auto pass1 = RenderPass::Create(); + pass1->SetNew(1, frame_rect, frame_rect, invertible_transform); + auto* shared_state_1 = pass1->CreateAndAppendSharedQuadState(); + shared_state_1->SetAll(invertible_transform, frame_rect, frame_rect, + gfx::RRectF(), frame_rect, false, false, 1, + SkBlendMode::kSrcOver, 0); + auto* surface_quad_1 = pass1->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); + surface_quad_1->SetNew( + pass1->shared_quad_state_list.back(), child_rect, child_rect, + SurfaceRange(child_surface_id1), SK_ColorWHITE, + /*stretch_content_to_fill_bounds=*/false, /*ignores_input_event=*/false); + gfx::Rect child_rect2(400, 400, 100, 100); + auto* surface_quad_2 = pass1->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); + surface_quad_2->SetNew( + pass1->shared_quad_state_list.back(), child_rect2, child_rect2, + SurfaceRange(child_surface_id2), SK_ColorWHITE, + /*stretch_content_to_fill_bounds=*/false, /*ignores_input_event=*/false); + pass_list.push_back(std::move(pass1)); + + // A RenderPass that has a RenderPassDrawQuad pointing to pass1, a + // SurfaceDrawQuad and a RenderPassDrawQuad pointing to pass1. + auto pass2 = RenderPass::Create(); + pass2->SetNew(4, frame_rect, frame_rect, invertible_transform); + auto* shared_state_2 = pass2->CreateAndAppendSharedQuadState(); + shared_state_2->SetAll(invertible_transform, frame_rect, frame_rect, + gfx::RRectF(), frame_rect, false, false, 1, + SkBlendMode::kSrcOver, 0); + auto* render_pass_quad_1 = + pass2->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); + render_pass_quad_1->SetNew( + pass2->shared_quad_state_list.back(), child_rect, child_rect, + /*render_pass_id=*/1, + /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), gfx::Vector2dF(1, 1), + gfx::PointF(), gfx::RectF(), false, 1.0f); + SurfaceId child_surface_id3 = CreateChildSurfaceId(4); + gfx::Rect child_rect3(500, 500, 100, 100); + auto* surface_quad_3 = pass2->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); + surface_quad_3->SetNew( + pass2->shared_quad_state_list.back(), child_rect3, child_rect3, + SurfaceRange(child_surface_id3), SK_ColorWHITE, + /*stretch_content_to_fill_bounds=*/false, /*ignores_input_event=*/false); + auto* render_pass_quad_2 = + pass2->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); + render_pass_quad_2->SetNew( + pass2->shared_quad_state_list.back(), child_rect2, child_rect2, + /*render_pass_id=*/1, + /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), gfx::Vector2dF(1, 1), + gfx::PointF(), gfx::RectF(), false, 1.0f); + pass_list.push_back(std::move(pass2)); + + // The root RenderPass that has three RenderPassDrawQuad point to pass2. + auto pass_root = RenderPass::Create(); + pass_root->SetNew(5, frame_rect, frame_rect, invertible_transform); + auto* shared_state_3 = pass_root->CreateAndAppendSharedQuadState(); + shared_state_3->SetAll(invertible_transform, frame_rect, frame_rect, + gfx::RRectF(), frame_rect, false, false, 1, + SkBlendMode::kSrcOver, 0); + auto* render_pass_quad_3 = + pass_root->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); + render_pass_quad_3->SetNew( + pass_root->shared_quad_state_list.back(), child_rect, child_rect, + /*render_pass_id=*/4, + /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), gfx::Vector2dF(1, 1), + gfx::PointF(), gfx::RectF(), false, 1.0f); + auto* render_pass_quad_4 = + pass_root->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); + render_pass_quad_4->SetNew( + pass_root->shared_quad_state_list.back(), child_rect2, child_rect2, + /*render_pass_id=*/4, + /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), gfx::Vector2dF(1, 1), + gfx::PointF(), gfx::RectF(), false, 1.0f); + auto* render_pass_quad_5 = + pass_root->CreateAndAppendDrawQuad<RenderPassDrawQuad>(); + render_pass_quad_5->SetNew( + pass_root->shared_quad_state_list.back(), child_rect, child_rect, + /*render_pass_id=*/4, + /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), gfx::Vector2dF(1, 10), + gfx::PointF(), gfx::RectF(), false, 1.0f); + pass_list.push_back(std::move(pass_root)); + + CompositorFrame compositor_frame = + CompositorFrameBuilder().SetRenderPassList(std::move(pass_list)).Build(); + + base::Optional<HitTestRegionList> hit_test_region_list = + hit_test_data_provider->GetHitTestData(compositor_frame); + + // We should have the three SurfaceDrawQuad associated HitTestRegion, repeated + // based on RenderPassDrawQuad. + EXPECT_EQ(15u, hit_test_region_list->regions.size()); + for (size_t i = 0; i < 15; i += 5) { + EXPECT_EQ(child_surface_id1.frame_sink_id(), + hit_test_region_list->regions[i].frame_sink_id); + EXPECT_EQ(HitTestRegionFlags::kHitTestMouse | + HitTestRegionFlags::kHitTestTouch | + HitTestRegionFlags::kHitTestChildSurface | + HitTestRegionFlags::kHitTestAsk, + hit_test_region_list->regions[i].flags); + EXPECT_EQ(child_rect, hit_test_region_list->regions[i].rect); + + EXPECT_EQ(child_surface_id2.frame_sink_id(), + hit_test_region_list->regions[i + 1].frame_sink_id); + EXPECT_EQ(HitTestRegionFlags::kHitTestMouse | + HitTestRegionFlags::kHitTestTouch | + HitTestRegionFlags::kHitTestChildSurface | + HitTestRegionFlags::kHitTestAsk, + hit_test_region_list->regions[i + 1].flags); + EXPECT_EQ(child_rect2, hit_test_region_list->regions[i + 1].rect); + + EXPECT_EQ(child_surface_id3.frame_sink_id(), + hit_test_region_list->regions[i + 2].frame_sink_id); + EXPECT_EQ(HitTestRegionFlags::kHitTestMouse | + HitTestRegionFlags::kHitTestTouch | + HitTestRegionFlags::kHitTestChildSurface | + HitTestRegionFlags::kHitTestAsk, + hit_test_region_list->regions[i + 2].flags); + EXPECT_EQ(child_rect3, hit_test_region_list->regions[i + 2].rect); + + EXPECT_EQ(child_surface_id1.frame_sink_id(), + hit_test_region_list->regions[i + 3].frame_sink_id); + EXPECT_EQ(HitTestRegionFlags::kHitTestMouse | + HitTestRegionFlags::kHitTestTouch | + HitTestRegionFlags::kHitTestChildSurface | + HitTestRegionFlags::kHitTestAsk, + hit_test_region_list->regions[i + 3].flags); + EXPECT_EQ(child_rect, hit_test_region_list->regions[i + 3].rect); + + EXPECT_EQ(child_surface_id2.frame_sink_id(), + hit_test_region_list->regions[i + 4].frame_sink_id); + EXPECT_EQ(HitTestRegionFlags::kHitTestMouse | + HitTestRegionFlags::kHitTestTouch | + HitTestRegionFlags::kHitTestChildSurface | + HitTestRegionFlags::kHitTestAsk, + hit_test_region_list->regions[i + 4].flags); + EXPECT_EQ(child_rect2, hit_test_region_list->regions[i + 4].rect); + } +} + } // namespace viz
diff --git a/components/viz/common/hit_test/hit_test_data_builder.cc b/components/viz/common/hit_test/hit_test_data_builder.cc index 1fce595..11210b7 100644 --- a/components/viz/common/hit_test/hit_test_data_builder.cc +++ b/components/viz/common/hit_test/hit_test_data_builder.cc
@@ -81,10 +81,25 @@ return filter_regions; } -void AddHitTestDataFromRenderPass(const CompositorFrame& frame, - RenderPassId render_pass_id, - std::vector<HitTestRegion>* regions, - bool should_ask_for_child_region) { +void AddHitTestDataFromRenderPass( + const CompositorFrame& frame, + RenderPassId render_pass_id, + std::vector<HitTestRegion>* regions, + bool should_ask_for_child_region, + base::flat_map<RenderPassId, std::pair<uint32_t, uint32_t>>* + render_pass_hit_test_region_list) { + if (render_pass_hit_test_region_list->count(render_pass_id)) { + const auto& list_range = + render_pass_hit_test_region_list->find(render_pass_id)->second; + const uint32_t start = list_range.first; + const uint32_t end = list_range.second; + if (start >= end || regions->size() < end) + return; + regions->insert(regions->end(), regions->begin() + start, + regions->begin() + end); + return; + } + const RenderPass* render_pass = GetRenderPassInFrame(frame, render_pass_id); if (!render_pass) return; @@ -99,6 +114,7 @@ return; } + const uint32_t render_pass_hit_test_region_list_start = regions->size(); for (const DrawQuad* quad : render_pass->quad_list) { if (quad->material == DrawQuad::SURFACE_CONTENT) { const SurfaceDrawQuad* surface_quad = SurfaceDrawQuad::MaterialCast(quad); @@ -139,9 +155,14 @@ const RenderPassDrawQuad* render_quad = RenderPassDrawQuad::MaterialCast(quad); AddHitTestDataFromRenderPass(frame, render_quad->render_pass_id, regions, - should_ask_for_child_region); + should_ask_for_child_region, + render_pass_hit_test_region_list); } } + const uint32_t render_pass_hit_test_region_list_end = regions->size(); + render_pass_hit_test_region_list->emplace( + render_pass_id, std::make_pair(render_pass_hit_test_region_list_start, + render_pass_hit_test_region_list_end)); } } // namespace @@ -157,9 +178,12 @@ : HitTestRegionFlags::kHitTestIgnore) | HitTestRegionFlags::kHitTestMouse | HitTestRegionFlags::kHitTestTouch; hit_test_region_list->bounds.set_size(compositor_frame.size_in_pixels()); + base::flat_map<RenderPassId, std::pair<uint32_t, uint32_t>> + render_pass_hit_test_region_list_cache; AddHitTestDataFromRenderPass( compositor_frame, compositor_frame.render_pass_list.back()->id, - &hit_test_region_list->regions, should_ask_for_child_region); + &hit_test_region_list->regions, should_ask_for_child_region, + &render_pass_hit_test_region_list_cache); return hit_test_region_list; }
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index d0a8ae4..07bc6816 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -648,6 +648,8 @@ "cookie_store/cookie_store_host.h", "cookie_store/cookie_store_manager.cc", "cookie_store/cookie_store_manager.h", + "data_url_loader_factory.cc", + "data_url_loader_factory.h", "devtools/browser_devtools_agent_host.cc", "devtools/browser_devtools_agent_host.h", "devtools/devtools_agent_host_impl.cc",
diff --git a/content/browser/after_startup_task_utils.cc b/content/browser/after_startup_task_utils.cc index c9d74f3..2024105 100644 --- a/content/browser/after_startup_task_utils.cc +++ b/content/browser/after_startup_task_utils.cc
@@ -4,12 +4,14 @@ #include "content/browser/after_startup_task_utils.h" +#include "content/browser/scheduler/browser_task_executor.h" #include "content/public/browser/content_browser_client.h" #include "content/public/common/content_client.h" namespace content { void SetBrowserStartupIsCompleteForTesting() { + content::BrowserTaskExecutor::NotifyBrowserStartupCompleted(); // Forward the message to ContentBrowserClient if one is registered (there are // many tests where one isn't but that's fine as that also means they get the // default ContentBrowserClient::IsBrowserStartupComplete() which is always
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index a0b100c..6e3dfde10 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -84,6 +84,7 @@ #include "content/browser/net/browser_online_state_observer.h" #include "content/browser/renderer_host/media/media_stream_manager.h" #include "content/browser/renderer_host/render_process_host_impl.h" +#include "content/browser/scheduler/browser_task_executor.h" #include "content/browser/scheduler/responsiveness/watcher.h" #include "content/browser/screenlock_monitor/screenlock_monitor.h" #include "content/browser/screenlock_monitor/screenlock_monitor_device_source.h" @@ -1208,6 +1209,11 @@ DCHECK(base::ThreadTaskRunnerHandle::IsSet()); main_thread_.reset(new BrowserThreadImpl( BrowserThread::UI, base::ThreadTaskRunnerHandle::Get())); + // TODO(https://crbug.com/863341): Replace with a better API + GetContentClient()->browser()->PostAfterStartupTask( + FROM_HERE, base::SequencedTaskRunnerHandle::Get(), base::BindOnce([]() { + content::BrowserTaskExecutor::NotifyBrowserStartupCompleted(); + })); } int BrowserMainLoop::BrowserThreadsStarted() {
diff --git a/content/browser/data_url_loader_factory.cc b/content/browser/data_url_loader_factory.cc new file mode 100644 index 0000000..51dfc77 --- /dev/null +++ b/content/browser/data_url_loader_factory.cc
@@ -0,0 +1,104 @@ +// Copyright 2019 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/data_url_loader_factory.h" + +#include "mojo/public/cpp/system/string_data_pipe_producer.h" +#include "net/url_request/url_request_data_job.h" +#include "services/network/public/mojom/url_loader.mojom.h" + +namespace content { + +namespace { +struct WriteData { + network::mojom::URLLoaderClientPtr client; + std::string data; + std::unique_ptr<mojo::StringDataPipeProducer> producer; +}; + +void OnWrite(std::unique_ptr<WriteData> write_data, MojoResult result) { + if (result != MOJO_RESULT_OK) { + network::URLLoaderCompletionStatus status(net::ERR_FAILED); + return; + } + + network::URLLoaderCompletionStatus status(net::OK); + status.encoded_data_length = write_data->data.size(); + status.encoded_body_length = write_data->data.size(); + status.decoded_body_length = write_data->data.size(); + write_data->client->OnComplete(status); +} + +} // namespace + +DataURLLoaderFactory::DataURLLoaderFactory() = default; +DataURLLoaderFactory::~DataURLLoaderFactory() = default; + +DataURLLoaderFactory::DataURLLoaderFactory(const GURL& url) : url_(url) {} + +void DataURLLoaderFactory::CreateLoaderAndStart( + network::mojom::URLLoaderRequest loader, + int32_t routing_id, + int32_t request_id, + uint32_t options, + const network::ResourceRequest& request, + network::mojom::URLLoaderClientPtr client, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) { + std::string mime_type; + std::string charset; + std::string data; + auto headers = base::MakeRefCounted<net::HttpResponseHeaders>(std::string()); + + const GURL* url = nullptr; + if (!url_.is_empty() && request.url.is_empty()) { + url = &url_; + } else { + url = &request.url; + } + + int result = net::URLRequestDataJob::BuildResponse(*url, &mime_type, &charset, + &data, headers.get()); + url_ = GURL(); // Don't need it anymore. + + if (result != net::OK) { + client->OnComplete(network::URLLoaderCompletionStatus(result)); + return; + } + + network::ResourceResponseHead response; + response.mime_type = mime_type; + response.charset = charset; + response.headers = headers; + client->OnReceiveResponse(response); + + mojo::ScopedDataPipeProducerHandle producer; + mojo::ScopedDataPipeConsumerHandle consumer; + if (CreateDataPipe(nullptr, &producer, &consumer) != MOJO_RESULT_OK) { + client->OnComplete( + network::URLLoaderCompletionStatus(net::ERR_INSUFFICIENT_RESOURCES)); + return; + } + + client->OnStartLoadingResponseBody(std::move(consumer)); + + auto write_data = std::make_unique<WriteData>(); + write_data->client = std::move(client); + write_data->data = std::move(data); + write_data->producer = + std::make_unique<mojo::StringDataPipeProducer>(std::move(producer)); + + base::StringPiece string_piece(write_data->data); + + write_data->producer->Write(string_piece, + mojo::StringDataPipeProducer::AsyncWritingMode:: + STRING_STAYS_VALID_UNTIL_COMPLETION, + base::BindOnce(OnWrite, std::move(write_data))); +} + +void DataURLLoaderFactory::Clone( + network::mojom::URLLoaderFactoryRequest loader) { + bindings_.AddBinding(this, std::move(loader)); +} + +} // namespace content
diff --git a/content/browser/data_url_loader_factory.h b/content/browser/data_url_loader_factory.h new file mode 100644 index 0000000..c2a6d7f0 --- /dev/null +++ b/content/browser/data_url_loader_factory.h
@@ -0,0 +1,47 @@ +// Copyright 2019 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_DATA_URL_LOADER_FACTORY_H_ +#define CONTENT_BROWSER_DATA_URL_LOADER_FACTORY_H_ + +#include "base/macros.h" +#include "mojo/public/cpp/bindings/binding_set.h" +#include "services/network/public/mojom/url_loader_factory.mojom.h" + +namespace content { + +// URLLoaderFactory for handling data: URLs. +class DataURLLoaderFactory : public network::mojom::URLLoaderFactory { + public: + DataURLLoaderFactory(); + + // Initializes a factory with a GURL, which is useful if this factory will + // be used only once with a GURL that can be larger than the GURL + // serialization limit. The factory will check that the passed in url to + // CreateLoaderAndStart either matches or is empty (because it was truncated). + explicit DataURLLoaderFactory(const GURL& url); + ~DataURLLoaderFactory() override; + + private: + // network::mojom::URLLoaderFactory: + void CreateLoaderAndStart(network::mojom::URLLoaderRequest loader, + int32_t routing_id, + int32_t request_id, + uint32_t options, + const network::ResourceRequest& request, + network::mojom::URLLoaderClientPtr client, + const net::MutableNetworkTrafficAnnotationTag& + traffic_annotation) override; + void Clone(network::mojom::URLLoaderFactoryRequest loader) override; + + GURL url_; + + mojo::BindingSet<network::mojom::URLLoaderFactory> bindings_; + + DISALLOW_COPY_AND_ASSIGN(DataURLLoaderFactory); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_DATA_URL_LOADER_FACTORY_H_
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc index 7f017b2..a44f9994 100644 --- a/content/browser/download/download_manager_impl.cc +++ b/content/browser/download/download_manager_impl.cc
@@ -39,6 +39,7 @@ #include "components/download/public/common/url_download_handler_factory.h" #include "content/browser/byte_stream.h" #include "content/browser/child_process_security_policy_impl.h" +#include "content/browser/data_url_loader_factory.h" #include "content/browser/devtools/devtools_instrumentation.h" #include "content/browser/download/byte_stream_input_stream.h" #include "content/browser/download/download_resource_handler.h" @@ -318,6 +319,21 @@ std::move(proxy_factory_ptr_info), std::move(proxy_factory_request)); } +scoped_refptr<download::DownloadURLLoaderFactoryGetter> +CreateDownloadURLLoaderFactoryGetterFromURLLoaderFactory( + std::unique_ptr<network::mojom::URLLoaderFactory> factory) { + network::mojom::URLLoaderFactoryPtr factory_ptr; + mojo::MakeStrongBinding(std::move(factory), mojo::MakeRequest(&factory_ptr)); + network::mojom::URLLoaderFactoryPtrInfo factory_ptr_info = + factory_ptr.PassInterface(); + + auto wrapper_factory = + std::make_unique<network::WrapperSharedURLLoaderFactoryInfo>( + std::move(factory_ptr_info)); + return base::MakeRefCounted<download::DownloadURLLoaderFactoryGetterImpl>( + std::move(wrapper_factory)); +} + } // namespace DownloadManagerImpl::DownloadManagerImpl(BrowserContext* browser_context) @@ -1333,6 +1349,10 @@ base::MakeRefCounted<FileSystemDownloadURLLoaderFactoryGetter>( params->url(), rfh, /*is_navigation=*/false, storage_partition->GetFileSystemContext(), storage_domain); + } else if (params->url().SchemeIs(url::kDataScheme)) { + url_loader_factory_getter = + CreateDownloadURLLoaderFactoryGetterFromURLLoaderFactory( + std::make_unique<DataURLLoaderFactory>(params->url())); } else if (rfh && !IsURLHandledByNetworkService(params->url())) { ContentBrowserClient::NonNetworkURLLoaderFactoryMap non_network_url_loader_factories; @@ -1347,20 +1367,9 @@ DLOG(ERROR) << "No URLLoaderFactory found to download " << params->url(); return; } else { - std::unique_ptr<network::mojom::URLLoaderFactory> factory = - std::move(it->second); - network::mojom::URLLoaderFactoryPtr factory_ptr; - mojo::MakeStrongBinding(std::move(factory), - mojo::MakeRequest(&factory_ptr)); - network::mojom::URLLoaderFactoryPtrInfo factory_ptr_info = - factory_ptr.PassInterface(); - - auto wrapper_factory = - std::make_unique<network::WrapperSharedURLLoaderFactoryInfo>( - std::move(factory_ptr_info)); url_loader_factory_getter = - base::MakeRefCounted<download::DownloadURLLoaderFactoryGetterImpl>( - std::move(wrapper_factory)); + CreateDownloadURLLoaderFactoryGetterFromURLLoaderFactory( + std::move(it->second)); } } else { StoragePartitionImpl* storage_partition =
diff --git a/content/browser/download/save_file_manager.cc b/content/browser/download/save_file_manager.cc index 685b462e1..9aab419 100644 --- a/content/browser/download/save_file_manager.cc +++ b/content/browser/download/save_file_manager.cc
@@ -14,6 +14,7 @@ #include "base/strings/string_util.h" #include "components/download/public/common/download_task_runner.h" #include "content/browser/child_process_security_policy_impl.h" +#include "content/browser/data_url_loader_factory.h" #include "content/browser/download/save_file.h" #include "content/browser/download/save_package.h" #include "content/browser/renderer_host/render_view_host_impl.h" @@ -240,12 +241,25 @@ request->priority = net::DEFAULT_PRIORITY; request->load_flags = net::LOAD_SKIP_CACHE_VALIDATION; + network::mojom::URLLoaderFactory* factory = nullptr; + std::unique_ptr<DataURLLoaderFactory> data_url_loader_factory; + + // TODO(qinmin): should this match the if statements in + // DownloadManagerImpl::BeginResourceDownloadOnChecksComplete so that it + // can handle blob, file, webui, embedder provided schemes etc? + // https://crbug.com/953967 + if (url.SchemeIs(url::kDataScheme)) { + data_url_loader_factory = std::make_unique<DataURLLoaderFactory>(); + factory = data_url_loader_factory.get(); + } else { + factory = storage_partition->GetURLLoaderFactoryForBrowserProcess().get(); + } + url_loader_helpers_[save_item_id] = SimpleURLLoaderHelper::CreateAndStartDownload( std::move(request), save_item_id, save_package->id(), render_process_host_id, render_frame_routing_id, traffic_annotation, - storage_partition->GetURLLoaderFactoryForBrowserProcess().get(), - this); + factory, this); } else { // We manually start the save job. auto info = std::make_unique<SaveFileCreateInfo>(
diff --git a/content/browser/frame_host/back_forward_cache_metrics.cc b/content/browser/frame_host/back_forward_cache_metrics.cc index 676e491..da826ddc 100644 --- a/content/browser/frame_host/back_forward_cache_metrics.cc +++ b/content/browser/frame_host/back_forward_cache_metrics.cc
@@ -107,6 +107,8 @@ builder.SetNavigatedToTheMostRecentEntryForDocument( navigation_entry_id == last_committed_navigation_entry_id_); builder.SetMainFrameFeatures(main_frame_features_); + builder.SetSameOriginSubframesFeatures(same_origin_frames_features_); + builder.SetCrossOriginSubframesFeatures(cross_origin_frames_features_); // DidStart notification might be missing for some same-document // navigations. It's good that we don't care about the time in the cache // in that case. @@ -137,7 +139,32 @@ void BackForwardCacheMetrics::RecordFeatureUsage( RenderFrameHostImpl* main_frame) { DCHECK(!main_frame->GetParent()); - main_frame_features_ = main_frame->scheduler_tracked_features(); + + main_frame_features_ = 0; + same_origin_frames_features_ = 0; + cross_origin_frames_features_ = 0; + + CollectFeatureUsageFromSubtree(main_frame, + main_frame->GetLastCommittedOrigin()); +} + +void BackForwardCacheMetrics::CollectFeatureUsageFromSubtree( + RenderFrameHostImpl* rfh, + const url::Origin& main_frame_origin) { + uint64_t features = rfh->scheduler_tracked_features(); + if (!rfh->GetParent()) { + main_frame_features_ |= features; + } else if (rfh->GetLastCommittedOrigin().IsSameOriginWith( + main_frame_origin)) { + same_origin_frames_features_ |= features; + } else { + cross_origin_frames_features_ |= features; + } + + for (size_t i = 0; i < rfh->child_count(); ++i) { + CollectFeatureUsageFromSubtree(rfh->child_at(i)->current_frame_host(), + main_frame_origin); + } } } // namespace content
diff --git a/content/browser/frame_host/back_forward_cache_metrics.h b/content/browser/frame_host/back_forward_cache_metrics.h index 4a4729e..fe1567b 100644 --- a/content/browser/frame_host/back_forward_cache_metrics.h +++ b/content/browser/frame_host/back_forward_cache_metrics.h
@@ -12,6 +12,10 @@ #include "base/time/time.h" #include "content/common/content_export.h" +namespace url { +class Origin; +} + namespace content { class NavigationEntryImpl; class RenderFrameHostImpl; @@ -77,6 +81,11 @@ ~BackForwardCacheMetrics(); + // Recursively collects the feature usage information from the subtree + // of a given frame. + void CollectFeatureUsageFromSubtree(RenderFrameHostImpl* rfh, + const url::Origin& main_frame_origin); + // Main frame document sequence number that identifies all NavigationEntries // this metrics object is associated with. const int64_t document_sequence_number_; @@ -87,7 +96,15 @@ int64_t last_committed_navigation_entry_id_ = -1; - int64_t main_frame_features_ = 0; + uint64_t main_frame_features_ = 0; + // We record metrics for same-origin frames and cross-origin frames + // differently as we might want to apply different policies for them, + // especially for the things around web platform compatibility (e.g. ignore + // unload handlers in cross-origin iframes but not in same-origin). The + // details are still subject to metrics, however. NOTE: This is not related to + // which process these frames are hosted in. + uint64_t same_origin_frames_features_ = 0; + uint64_t cross_origin_frames_features_ = 0; base::Optional<base::TimeTicks> started_navigation_timestamp_; base::Optional<base::TimeTicks> navigated_away_from_main_document_timestamp_;
diff --git a/content/browser/frame_host/back_forward_cache_metrics_browsertest.cc b/content/browser/frame_host/back_forward_cache_metrics_browsertest.cc index 0d32153..d0c5c6d 100644 --- a/content/browser/frame_host/back_forward_cache_metrics_browsertest.cc +++ b/content/browser/frame_host/back_forward_cache_metrics_browsertest.cc
@@ -16,11 +16,15 @@ #include "net/dns/mock_host_resolver.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h" namespace content { namespace { +constexpr int kPageShowFeature = static_cast<int>( + blink::scheduler::WebSchedulerTrackedFeature::kPageShowEventListener); + ukm::SourceId ToSourceId(int64_t navigation_id) { return ukm::ConvertToSourceId(navigation_id, ukm::SourceIdType::NAVIGATION_ID); @@ -262,6 +266,53 @@ UkmEntry{id6, {{last_navigation_id, id4}}})); } +namespace { + +struct FeatureUsage { + ukm::SourceId source_id; + uint64_t main_frame_features; + uint64_t same_origin_subframes_features; + uint64_t cross_origin_subframes_features; +}; + +bool operator==(const FeatureUsage& lhs, const FeatureUsage& rhs) { + return lhs.source_id == rhs.source_id && + lhs.main_frame_features == rhs.main_frame_features && + lhs.same_origin_subframes_features == + rhs.same_origin_subframes_features && + lhs.cross_origin_subframes_features == + rhs.cross_origin_subframes_features; +} + +std::ostream& operator<<(std::ostream& os, const FeatureUsage& usage) { + os << "source_id=" << usage.source_id + << " main_frame_features=" << usage.main_frame_features + << " same_origin_features=" << usage.same_origin_subframes_features + << " cross_origin_features=" << usage.cross_origin_subframes_features; + return os; +} + +std::vector<FeatureUsage> GetFeatureUsageMetrics( + ukm::TestAutoSetUkmRecorder* recorder) { + std::vector<FeatureUsage> result; + for (const auto& entry : + GetEntries(recorder, "HistoryNavigation", + {"MainFrameFeatures", "SameOriginSubframesFeatures", + "CrossOriginSubframesFeatures"})) { + FeatureUsage feature_usage; + feature_usage.source_id = entry.first; + feature_usage.main_frame_features = entry.second.at("MainFrameFeatures"); + feature_usage.same_origin_subframes_features = + entry.second.at("SameOriginSubframesFeatures"); + feature_usage.cross_origin_subframes_features = + entry.second.at("CrossOriginSubframesFeatures"); + result.push_back(feature_usage); + } + return result; +} + +} // namespace + IN_PROC_BROWSER_TEST_F(BackForwardCacheMetricsBrowserTest, Features_MainFrame) { ukm::TestAutoSetUkmRecorder recorder; @@ -278,16 +329,128 @@ navigation_observer.WaitForNavigationFinished(); } - constexpr int kPageShowFeature = 6; + ASSERT_EQ(navigation_ids_.size(), static_cast<size_t>(3)); + // ukm::SourceId id1 = ToSourceId(navigation_ids_[0]); + // ukm::SourceId id2 = ToSourceId(navigation_ids_[1]); + ukm::SourceId id3 = ToSourceId(navigation_ids_[2]); + + EXPECT_THAT( + GetFeatureUsageMetrics(&recorder), + testing::ElementsAre(FeatureUsage{id3, 1 << kPageShowFeature, 0, 0})); +} + +IN_PROC_BROWSER_TEST_F(BackForwardCacheMetricsBrowserTest, + Features_MainFrame_CrossOriginNavigation) { + ukm::TestAutoSetUkmRecorder recorder; + + const GURL url1(embedded_test_server()->GetURL( + "/back_forward_cache/page_with_pageshow.html")); + const GURL url2( + embedded_test_server()->GetURL("/cross-site/bar.com/title1.html")); + + EXPECT_TRUE(NavigateToURL(shell(), url1)); + NavigateToURL(shell(), url2); + + { + TestNavigationObserver navigation_observer(shell()->web_contents()); + shell()->GoBackOrForward(-1); + navigation_observer.WaitForNavigationFinished(); + } ASSERT_EQ(navigation_ids_.size(), static_cast<size_t>(3)); // ukm::SourceId id1 = ToSourceId(navigation_ids_[0]); // ukm::SourceId id2 = ToSourceId(navigation_ids_[1]); ukm::SourceId id3 = ToSourceId(navigation_ids_[2]); - EXPECT_THAT(GetEntries(&recorder, "HistoryNavigation", {"MainFrameFeatures"}), - testing::ElementsAre(UkmEntry{ - id3, {{"MainFrameFeatures", 1 << kPageShowFeature}}})); + EXPECT_THAT( + GetFeatureUsageMetrics(&recorder), + testing::ElementsAre(FeatureUsage{id3, 1 << kPageShowFeature, 0, 0})); +} + +IN_PROC_BROWSER_TEST_F(BackForwardCacheMetricsBrowserTest, + Features_SameOriginSubframes) { + ukm::TestAutoSetUkmRecorder recorder; + + const GURL url1(embedded_test_server()->GetURL( + "/back_forward_cache/page_with_same_origin_subframe_with_pageshow.html")); + const GURL url2(embedded_test_server()->GetURL("/title1.html")); + + EXPECT_TRUE(NavigateToURL(shell(), url1)); + EXPECT_TRUE(NavigateToURL(shell(), url2)); + + { + TestNavigationObserver navigation_observer(shell()->web_contents(), 2); + shell()->GoBackOrForward(-1); + navigation_observer.WaitForNavigationFinished(); + } + + ASSERT_EQ(navigation_ids_.size(), static_cast<size_t>(5)); + // ukm::SourceId id1 = ToSourceId(navigation_ids_[0]); + // ukm::SourceId id2 = ToSourceId(navigation_ids_[1]); + // ukm::SourceId id3 = ToSourceId(navigation_ids_[2]); + ukm::SourceId id4 = ToSourceId(navigation_ids_[3]); + + EXPECT_THAT( + GetFeatureUsageMetrics(&recorder), + testing::ElementsAre(FeatureUsage{id4, 0, 1 << kPageShowFeature, 0})); +} + +IN_PROC_BROWSER_TEST_F(BackForwardCacheMetricsBrowserTest, + Features_SameOriginSubframes_CrossOriginNavigation) { + ukm::TestAutoSetUkmRecorder recorder; + + const GURL url1(embedded_test_server()->GetURL( + "/back_forward_cache/page_with_same_origin_subframe_with_pageshow.html")); + const GURL url2( + embedded_test_server()->GetURL("/cross-site/bar.com/title1.html")); + + EXPECT_TRUE(NavigateToURL(shell(), url1)); + NavigateToURL(shell(), url2); + + { + TestNavigationObserver navigation_observer(shell()->web_contents(), 2); + shell()->GoBackOrForward(-1); + navigation_observer.WaitForNavigationFinished(); + } + + ASSERT_EQ(navigation_ids_.size(), static_cast<size_t>(5)); + // ukm::SourceId id1 = ToSourceId(navigation_ids_[0]); + // ukm::SourceId id2 = ToSourceId(navigation_ids_[1]); + // ukm::SourceId id3 = ToSourceId(navigation_ids_[2]); + ukm::SourceId id4 = ToSourceId(navigation_ids_[3]); + + EXPECT_THAT( + GetFeatureUsageMetrics(&recorder), + testing::ElementsAre(FeatureUsage{id4, 0, 1 << kPageShowFeature, 0})); +} + +IN_PROC_BROWSER_TEST_F(BackForwardCacheMetricsBrowserTest, + Features_CrossOriginSubframes) { + ukm::TestAutoSetUkmRecorder recorder; + + const GURL url1(embedded_test_server()->GetURL( + "/back_forward_cache/" + "page_with_cross_origin_subframe_with_pageshow.html")); + const GURL url2(embedded_test_server()->GetURL("/title1.html")); + + EXPECT_TRUE(NavigateToURL(shell(), url1)); + EXPECT_TRUE(NavigateToURL(shell(), url2)); + + { + TestNavigationObserver navigation_observer(shell()->web_contents(), 2); + shell()->GoBackOrForward(-1); + navigation_observer.WaitForNavigationFinished(); + } + + ASSERT_EQ(navigation_ids_.size(), static_cast<size_t>(5)); + // ukm::SourceId id1 = ToSourceId(navigation_ids_[0]); + // ukm::SourceId id2 = ToSourceId(navigation_ids_[1]); + // ukm::SourceId id3 = ToSourceId(navigation_ids_[2]); + ukm::SourceId id4 = ToSourceId(navigation_ids_[3]); + + EXPECT_THAT( + GetFeatureUsageMetrics(&recorder), + testing::ElementsAre(FeatureUsage{id4, 0, 0, 1 << kPageShowFeature})); } } // namespace content
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 47ddca3..fd5a866d 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -40,6 +40,7 @@ #include "content/browser/browser_main_loop.h" #include "content/browser/child_process_security_policy_impl.h" #include "content/browser/contacts/contacts_manager_impl.h" +#include "content/browser/data_url_loader_factory.h" #include "content/browser/devtools/devtools_instrumentation.h" #include "content/browser/dom_storage/dom_storage_context_wrapper.h" #include "content/browser/download/mhtml_generation_manager.h" @@ -2118,9 +2119,6 @@ void RenderFrameHostImpl::UpdateActiveSchedulerTrackedFeatures( uint64_t features_mask) { - // TODO(altimin): Support subframes too. For now renderer shouldn't send - // this message for subframes at all. - DCHECK(!GetParent()); scheduler_tracked_features_ = features_mask; } @@ -4717,6 +4715,9 @@ this, /*is_navigation=*/false, partition->GetFileSystemContext(), storage_domain)); + non_network_url_loader_factories_.emplace( + url::kDataScheme, std::make_unique<DataURLLoaderFactory>()); + GetContentClient() ->browser() ->RegisterNonNetworkSubresourceURLLoaderFactories( @@ -4815,6 +4816,35 @@ if (IsPerNavigationMojoInterfaceEnabled() && navigation_request) navigation_client = navigation_request->GetCommitNavigationClient(); + // Record the metrics about the state of the old main frame at the moment + // when we navigate away from it as it matters for whether the page + // is eligible for being put into back-forward cache. + // + // Ideally we would do this when we are just about to swap out the old + // render frame and swap in the new one, but we can't do this for + // same-process navigations yet as we are reusing the RenderFrameHost and + // as the local frame navigates it overrides the values that we are + // interested in. The cross-process navigation case is handled in + // RenderFrameHostManager::SwapOutOldFrame. + // + // Here we are recording the metrics for same-process navigations at the + // point just before the navigation commits. + // TODO(altimin, crbug.com/933147): Remove this logic after we are done with + // implementing back-forward cache. + if (!GetParent() && frame_tree_node()->current_frame_host() == this) { + if (NavigationEntryImpl* last_committed_entry = + NavigationEntryImpl::FromNavigationEntry( + frame_tree_node() + ->navigator() + ->GetController() + ->GetLastCommittedEntry())) { + if (last_committed_entry->back_forward_cache_metrics()) { + last_committed_entry->back_forward_cache_metrics() + ->RecordFeatureUsage(this); + } + } + } + SendCommitNavigation( navigation_client, navigation_request, head, common_params, commit_params, std::move(url_loader_client_endpoints),
diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc index 07238ea..5487ac4 100644 --- a/content/browser/frame_host/render_frame_host_manager.cc +++ b/content/browser/frame_host/render_frame_host_manager.cc
@@ -282,22 +282,6 @@ RenderFrameHostImpl* render_frame_host, bool was_caused_by_user_gesture, bool is_same_document_navigation) { - // Record the metrics about the state of the old frame at the moment when - // we navigate away from it as it matters for whether the page is eligible - // for being put into back-forward cache. - // TODO(altimin, crbug.com/933147): Remove this logic after we are done with - // implementing back-forward cache. - if (!render_frame_host->GetParent() && !is_same_document_navigation) { - if (NavigationEntryImpl* last_committed_entry = - delegate_->GetControllerForRenderManager() - .GetLastCommittedEntry()) { - if (last_committed_entry->back_forward_cache_metrics()) { - last_committed_entry->back_forward_cache_metrics()->RecordFeatureUsage( - render_frame_host); - } - } - } - CommitPendingIfNecessary(render_frame_host, was_caused_by_user_gesture, is_same_document_navigation); @@ -457,6 +441,27 @@ // RenderFrameHost should not be trying to commit a navigation. old_render_frame_host->ResetNavigationRequests(); + // Record the metrics about the state of the old main frame at the moment when + // we navigate away from it as it matters for whether the page is eligible for + // being put into back-forward cache. + // + // This covers the cross-process navigation case and the same-process case is + // handled in RenderFrameHostImpl::CommitNavigation, so the subframe state + // can be captured before the frame navigates away. + // + // TODO(altimin, crbug.com/933147): Remove this logic after we are done with + // implementing back-forward cache. + if (!old_render_frame_host->GetParent()) { + if (NavigationEntryImpl* last_committed_entry = + delegate_->GetControllerForRenderManager() + .GetLastCommittedEntry()) { + if (last_committed_entry->back_forward_cache_metrics()) { + last_committed_entry->back_forward_cache_metrics()->RecordFeatureUsage( + old_render_frame_host.get()); + } + } + } + // BackForwardCache: // // If the old RenderFrameHost can be stored in the BackForwardCache, return
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index c767bc4..269f4dc 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -23,6 +23,7 @@ #include "content/browser/appcache/appcache_navigation_handle_core.h" #include "content/browser/appcache/appcache_request_handler.h" #include "content/browser/blob_storage/chrome_blob_storage_context.h" +#include "content/browser/data_url_loader_factory.h" #include "content/browser/devtools/devtools_instrumentation.h" #include "content/browser/file_url_loader_factory.h" #include "content/browser/fileapi/file_system_url_loader_factory.h" @@ -1578,6 +1579,9 @@ non_network_url_loader_factories_[url::kAboutScheme] = std::make_unique<AboutURLLoaderFactory>(); + non_network_url_loader_factories_[url::kDataScheme] = + std::make_unique<DataURLLoaderFactory>(); + std::unique_ptr<network::mojom::URLLoaderFactory> file_url_loader_factory = std::make_unique<FileURLLoaderFactory>( partition->browser_context()->GetPath(),
diff --git a/content/browser/media/session/media_session_controller.cc b/content/browser/media/session/media_session_controller.cc index cf06f768..92ca3a1 100644 --- a/content/browser/media/session/media_session_controller.cc +++ b/content/browser/media/session/media_session_controller.cc
@@ -83,8 +83,11 @@ void MediaSessionController::OnSuspend(int player_id) { DCHECK_EQ(player_id_, player_id); + // TODO(crbug.com/953645): Set triggered_by_user to true ONLY if that action + // was actually triggered by user as this will create a WebUserGestureToken. id_.render_frame_host->Send(new MediaPlayerDelegateMsg_Pause( - id_.render_frame_host->GetRoutingID(), id_.delegate_id)); + id_.render_frame_host->GetRoutingID(), id_.delegate_id, + true /* triggered_by_user */)); } void MediaSessionController::OnResume(int player_id) {
diff --git a/content/browser/media/session/media_session_controller_unittest.cc b/content/browser/media/session/media_session_controller_unittest.cc index b919541..5653bf1 100644 --- a/content/browser/media/session/media_session_controller_unittest.cc +++ b/content/browser/media/session/media_session_controller_unittest.cc
@@ -72,7 +72,7 @@ } template <typename T> - bool ReceivedMessagePlayPause() { + bool ReceivedMessagePlay() { const IPC::Message* msg = test_sink().GetUniqueMessageMatching(T::ID); if (!msg) return false; @@ -87,6 +87,26 @@ } template <typename T> + bool ReceivedMessagePause(bool triggered_by_user) { + const IPC::Message* msg = test_sink().GetUniqueMessageMatching(T::ID); + if (!msg) + return false; + + std::tuple<int, bool> result; + if (!T::Read(msg, &result)) + return false; + + EXPECT_EQ(id_.delegate_id, std::get<0>(result)); + test_sink().ClearMessages(); + if (id_.delegate_id != std::get<0>(result)) + return false; + + EXPECT_EQ(triggered_by_user, std::get<1>(result)); + test_sink().ClearMessages(); + return triggered_by_user == std::get<1>(result); + } + + template <typename T> bool ReceivedMessageSeek(base::TimeDelta expected_seek_time) { const IPC::Message* msg = test_sink().GetUniqueMessageMatching(T::ID); if (!msg) @@ -161,11 +181,12 @@ // Verify suspend notifies the renderer and maintains its session. Suspend(); - EXPECT_TRUE(ReceivedMessagePlayPause<MediaPlayerDelegateMsg_Pause>()); + EXPECT_TRUE(ReceivedMessagePause<MediaPlayerDelegateMsg_Pause>( + true /* triggered_by_user */)); // Likewise verify the resume behavior. Resume(); - EXPECT_TRUE(ReceivedMessagePlayPause<MediaPlayerDelegateMsg_Play>()); + EXPECT_TRUE(ReceivedMessagePlay<MediaPlayerDelegateMsg_Play>()); // ...as well as the seek behavior. const base::TimeDelta kTestSeekForwardTime = base::TimeDelta::FromSeconds(1); @@ -241,11 +262,12 @@ // Verify suspend notifies the renderer and maintains its session. Suspend(); - EXPECT_TRUE(ReceivedMessagePlayPause<MediaPlayerDelegateMsg_Pause>()); + EXPECT_TRUE(ReceivedMessagePause<MediaPlayerDelegateMsg_Pause>( + true /* triggered_by_user */)); // Likewise verify the resume behavior. Resume(); - EXPECT_TRUE(ReceivedMessagePlayPause<MediaPlayerDelegateMsg_Play>()); + EXPECT_TRUE(ReceivedMessagePlay<MediaPlayerDelegateMsg_Play>()); // Attempt to switch to no audio player, which should do nothing. // TODO(dalecurtis): Delete this test once we're no longer using WMPA and
diff --git a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc index 66075a5..0db14f5 100644 --- a/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc +++ b/content/browser/picture_in_picture/picture_in_picture_window_controller_impl.cc
@@ -209,7 +209,7 @@ media_player_id_->render_frame_host->Send(new MediaPlayerDelegateMsg_Pause( media_player_id_->render_frame_host->GetRoutingID(), - media_player_id_->delegate_id)); + media_player_id_->delegate_id, false /* triggered_by_user */)); return false /* paused */; } @@ -406,7 +406,7 @@ // Pause the current video so there is only one video playing at a time. media_player_id_->render_frame_host->Send(new MediaPlayerDelegateMsg_Pause( media_player_id_->render_frame_host->GetRoutingID(), - media_player_id_->delegate_id)); + media_player_id_->delegate_id, false /* triggered_by_user */)); } if (media_player_id_.has_value()) {
diff --git a/content/browser/scheduler/browser_task_executor.cc b/content/browser/scheduler/browser_task_executor.cc index e829e4b..81131371 100644 --- a/content/browser/scheduler/browser_task_executor.cc +++ b/content/browser/scheduler/browser_task_executor.cc
@@ -347,10 +347,8 @@ switch (traits.priority()) { case base::TaskPriority::BEST_EFFORT: - // TODO(eseckler): For now, make BEST_EFFORT tasks run after startup. Once - // the BrowserUIThreadScheduler is in place, this should be handled by its - // policies instead. - return GetAfterStartupTaskRunnerForThread(thread_id); + return browser_ui_thread_scheduler_->GetTaskRunner( + QueueType::kBestEffort); case base::TaskPriority::USER_VISIBLE: return browser_ui_thread_scheduler_->GetTaskRunner(QueueType::kDefault); @@ -373,4 +371,11 @@ return GetAfterStartupTaskRunnerForThreadImpl(id); } +// static +void BrowserTaskExecutor::NotifyBrowserStartupCompleted() { + DCHECK(g_browser_task_executor); + g_browser_task_executor->browser_ui_thread_scheduler_ + ->EnableBestEffortQueues(); +} + } // namespace content
diff --git a/content/browser/scheduler/browser_task_executor.h b/content/browser/scheduler/browser_task_executor.h index a576ab995..65a084e 100644 --- a/content/browser/scheduler/browser_task_executor.h +++ b/content/browser/scheduler/browser_task_executor.h
@@ -42,6 +42,8 @@ // called. static void Shutdown(); + static void NotifyBrowserStartupCompleted(); + // Unregister and delete the TaskExecutor after a test. static void ResetForTesting();
diff --git a/content/browser/scheduler/browser_task_executor_unittest.cc b/content/browser/scheduler/browser_task_executor_unittest.cc index d76a957e..995755c 100644 --- a/content/browser/scheduler/browser_task_executor_unittest.cc +++ b/content/browser/scheduler/browser_task_executor_unittest.cc
@@ -81,12 +81,6 @@ BrowserTaskExecutor::GetProxyTaskRunnerForThread(BrowserThread::IO)); } -namespace { -void SetBoolFlag(bool* flag) { - *flag = true; -} -} // namespace - using MockTask = testing::StrictMock<base::MockCallback<base::RepeatingCallback<void()>>>; @@ -148,86 +142,6 @@ BrowserTaskExecutor::RunAllPendingTasksOnThreadForTesting(BrowserThread::IO); } -TEST_F(BrowserTaskExecutorTest, UserVisibleOrBlockingTasksRunDuringStartup) { - bool ran_best_effort = false; - bool ran_user_visible = false; - bool ran_user_blocking = false; - - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI, base::TaskPriority::BEST_EFFORT}, - base::BindOnce(&SetBoolFlag, base::Unretained(&ran_best_effort))); - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI, base::TaskPriority::USER_VISIBLE}, - base::BindOnce(&SetBoolFlag, base::Unretained(&ran_user_visible))); - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::UI, base::TaskPriority::USER_BLOCKING}, - base::BindOnce(&SetBoolFlag, base::Unretained(&ran_user_blocking))); - - thread_bundle_.RunUntilIdle(); - - EXPECT_FALSE(ran_best_effort); - EXPECT_TRUE(ran_user_visible); - EXPECT_TRUE(ran_user_blocking); -} - -TEST_F(BrowserTaskExecutorTest, BestEffortTasksRunAfterStartup) { - auto ui_best_effort_runner = base::CreateSingleThreadTaskRunnerWithTraits( - {BrowserThread::UI, base::TaskPriority::BEST_EFFORT}); - - // The TaskRunner shouldn't post directly to the proxy task runner. - EXPECT_NE( - ui_best_effort_runner, - BrowserTaskExecutor::GetProxyTaskRunnerForThread(BrowserThread::UI)); - - // Posting BEST_EFFORT tasks before startup should go to the browser_client_. - bool ran_first_task = false; - ui_best_effort_runner->PostTask( - FROM_HERE, - base::BindOnce(&SetBoolFlag, base::Unretained(&ran_first_task))); - - ui_best_effort_runner->PostDelayedTask( - FROM_HERE, base::DoNothing(), base::TimeDelta::FromMilliseconds(100)); - base::PostDelayedTaskWithTraits( - FROM_HERE, {BrowserThread::UI, base::TaskPriority::BEST_EFFORT}, - base::DoNothing(), base::TimeDelta::FromMilliseconds(200)); - PostDelayedTaskWithTraits( - FROM_HERE, {BrowserThread::IO, base::TaskPriority::BEST_EFFORT}, - base::DoNothing(), base::TimeDelta::FromMilliseconds(300)); - - // There should be a pending tasks, one from each thread's - // AfterStartupTaskRunner. - EXPECT_EQ(browser_client_.tasks_.size(), 2u); - - EXPECT_EQ(thread_bundle_.GetPendingMainThreadTaskCount(), 0u); - - // Emulate startup complete after 1 sec - this should post the two tasks to - // the UI thread. - thread_bundle_.FastForwardBy(base::TimeDelta::FromSeconds(1)); - browser_client_.RunTasks(); - EXPECT_EQ(thread_bundle_.GetPendingMainThreadTaskCount(), 2u); - - // Run the two tasks including the first BEST_EFFORT task posted as immediate. - // The three other BEST_EFFORT tasks should remain since they are delayed - // tasks. They should have been posted with their original delays. - thread_bundle_.RunUntilIdle(); - EXPECT_TRUE(ran_first_task); - EXPECT_EQ(thread_bundle_.GetPendingMainThreadTaskCount(), 3u); - - // Run the delayed tasks one by one. - for (size_t pending_tasks = 3; pending_tasks > 0; pending_tasks--) { - EXPECT_EQ(thread_bundle_.NextMainThreadPendingTaskDelay(), - base::TimeDelta::FromMilliseconds(100)); - thread_bundle_.FastForwardBy(base::TimeDelta::FromMilliseconds(100)); - EXPECT_EQ(thread_bundle_.GetPendingMainThreadTaskCount(), - pending_tasks - 1u); - } - - // Posting another BEST_EFFORT task should bypass the browser_client_. - ui_best_effort_runner->PostTask(FROM_HERE, base::DoNothing()); - EXPECT_EQ(browser_client_.tasks_.size(), 0u); - EXPECT_EQ(thread_bundle_.GetPendingMainThreadTaskCount(), 1u); -} - class BrowserTaskExecutorWithCustomSchedulerTest : public testing::Test { private: class ScopedTaskEnvironmentWithCustomScheduler @@ -276,4 +190,50 @@ scoped_task_environment_.GetMainThreadTaskRunner()); } +TEST_F(BrowserTaskExecutorWithCustomSchedulerTest, + UserVisibleOrBlockingTasksRunDuringStartup) { + MockTask best_effort; + MockTask user_visible; + MockTask user_blocking; + + base::PostTaskWithTraits(FROM_HERE, + {BrowserThread::UI, base::TaskPriority::BEST_EFFORT}, + best_effort.Get()); + base::PostTaskWithTraits( + FROM_HERE, {BrowserThread::UI, base::TaskPriority::USER_VISIBLE}, + user_visible.Get()); + base::PostTaskWithTraits( + FROM_HERE, {BrowserThread::UI, base::TaskPriority::USER_BLOCKING}, + user_blocking.Get()); + + EXPECT_CALL(user_visible, Run); + EXPECT_CALL(user_blocking, Run); + + scoped_task_environment_.RunUntilIdle(); +} + +TEST_F(BrowserTaskExecutorWithCustomSchedulerTest, + BestEffortTasksRunAfterStartup) { + auto ui_best_effort_runner = base::CreateSingleThreadTaskRunnerWithTraits( + {BrowserThread::UI, base::TaskPriority::BEST_EFFORT}); + + MockTask best_effort; + + ui_best_effort_runner->PostTask(FROM_HERE, best_effort.Get()); + ui_best_effort_runner->PostDelayedTask( + FROM_HERE, best_effort.Get(), base::TimeDelta::FromMilliseconds(100)); + base::PostDelayedTaskWithTraits( + FROM_HERE, {BrowserThread::UI, base::TaskPriority::BEST_EFFORT}, + best_effort.Get(), base::TimeDelta::FromMilliseconds(100)); + base::PostTaskWithTraits(FROM_HERE, + {BrowserThread::UI, base::TaskPriority::BEST_EFFORT}, + best_effort.Get()); + scoped_task_environment_.RunUntilIdle(); + + BrowserTaskExecutor::NotifyBrowserStartupCompleted(); + EXPECT_CALL(best_effort, Run).Times(4); + scoped_task_environment_.FastForwardBy( + base::TimeDelta::FromMilliseconds(100)); +} + } // namespace content
diff --git a/content/browser/scheduler/browser_ui_thread_scheduler.cc b/content/browser/scheduler/browser_ui_thread_scheduler.cc index c4e85fe0..54cae85 100644 --- a/content/browser/scheduler/browser_ui_thread_scheduler.cc +++ b/content/browser/scheduler/browser_ui_thread_scheduler.cc
@@ -7,12 +7,14 @@ #include <utility> #include "base/feature_list.h" +#include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/message_loop/message_loop.h" #include "base/process/process.h" #include "base/run_loop.h" #include "base/task/sequence_manager/sequence_manager.h" #include "base/task/sequence_manager/sequence_manager_impl.h" +#include "base/task/sequence_manager/task_queue.h" #include "base/task/sequence_manager/time_domain.h" #include "base/threading/platform_thread.h" #include "build/build_config.h" @@ -77,6 +79,12 @@ // To avoid locks in BrowserUIThreadScheduler::GetTaskRunner, eagerly // create all the well known task queues. + CreateTaskQueuesAndRunners(); + + InitialiseBestEffortQueue(); +} + +void BrowserUIThreadScheduler::CreateTaskQueuesAndRunners() { for (int i = 0; i < static_cast<int>(BrowserUIThreadTaskQueue::QueueType::kCount); i++) { BrowserUIThreadTaskQueue::QueueType queue_type = @@ -92,6 +100,14 @@ } } +void BrowserUIThreadScheduler::InitialiseBestEffortQueue() { + auto queue = task_queues_[BrowserUIThreadTaskQueue::QueueType::kBestEffort]; + queue->SetQueuePriority( + base::sequence_manager::TaskQueue::kBestEffortPriority); + best_effort_voter_ = queue->CreateQueueEnabledVoter(); + best_effort_voter_->SetVoteToEnable(false); +} + scoped_refptr<base::SingleThreadTaskRunner> BrowserUIThreadScheduler::GetTaskRunnerForTesting(QueueType queue_type) { return GetTaskRunner(queue_type); @@ -106,6 +122,11 @@ return scoped_refptr<base::SingleThreadTaskRunner>(); } +void BrowserUIThreadScheduler::EnableBestEffortQueues() { + DCHECK(!best_effort_voter_->IsVotingToEnable()); + best_effort_voter_->SetVoteToEnable(true); +} + void BrowserUIThreadScheduler::RunAllPendingTasksForTesting() { std::vector<scoped_refptr<BrowserUIThreadTaskQueue>> fenced_queues; for (const auto& queue : task_queues_) {
diff --git a/content/browser/scheduler/browser_ui_thread_scheduler.h b/content/browser/scheduler/browser_ui_thread_scheduler.h index d511c23..17f7c4f 100644 --- a/content/browser/scheduler/browser_ui_thread_scheduler.h +++ b/content/browser/scheduler/browser_ui_thread_scheduler.h
@@ -8,6 +8,8 @@ #include <memory> #include "base/containers/flat_map.h" +#include "base/message_loop/message_loop.h" +#include "base/task/sequence_manager/task_queue.h" #include "content/browser/scheduler/browser_ui_thread_task_queue.h" #include "content/common/content_export.h" @@ -40,6 +42,9 @@ // however no tasks will be executed after this point. void Shutdown(); + // Attention: Can only be called once + void EnableBestEffortQueues(); + using QueueType = BrowserUIThreadTaskQueue::QueueType; // Can be called from any thread. @@ -61,6 +66,11 @@ // Note this will be called before the FeatureList has been initialized. void InitialiseTaskQueues(); + // Creates all well known task queues (BrowserUIThreadTaskQueue::QueueType). + void CreateTaskQueuesAndRunners(); + + void InitialiseBestEffortQueue(); + scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner( QueueType queue_type); @@ -81,6 +91,9 @@ base::flat_map<QueueType, scoped_refptr<base::SingleThreadTaskRunner>> task_runners_; + std::unique_ptr<base::sequence_manager::TaskQueue::QueueEnabledVoter> + best_effort_voter_; + DISALLOW_COPY_AND_ASSIGN(BrowserUIThreadScheduler); };
diff --git a/content/browser/scheduler/browser_ui_thread_scheduler_unittest.cc b/content/browser/scheduler/browser_ui_thread_scheduler_unittest.cc index 80fa886..9b47b06 100644 --- a/content/browser/scheduler/browser_ui_thread_scheduler_unittest.cc +++ b/content/browser/scheduler/browser_ui_thread_scheduler_unittest.cc
@@ -73,20 +73,53 @@ }; TEST_F(BrowserUIThreadSchedulerTest, RunAllPendingTasksForTesting) { - MockTask task; - MockTask nested_task; - EXPECT_CALL(task, Run).WillOnce(Invoke([&]() { - task_runners_[QueueType::kDefault]->PostTask(FROM_HERE, nested_task.Get()); - task_runners_[QueueType::kBestEffort]->PostTask(FROM_HERE, - nested_task.Get()); + browser_ui_thread_scheduler_->EnableBestEffortQueues(); + MockTask task_1; + MockTask task_2; + EXPECT_CALL(task_1, Run).WillOnce(Invoke([&]() { + task_runners_[QueueType::kDefault]->PostTask(FROM_HERE, task_2.Get()); + task_runners_[QueueType::kBestEffort]->PostTask(FROM_HERE, task_2.Get()); })); - task_runners_[QueueType::kDefault]->PostTask(FROM_HERE, task.Get()); + task_runners_[QueueType::kDefault]->PostTask(FROM_HERE, task_1.Get()); browser_ui_thread_scheduler_->RunAllPendingTasksForTesting(); - Mock::VerifyAndClearExpectations(&task); - EXPECT_CALL(nested_task, Run).Times(2); + Mock::VerifyAndClearExpectations(&task_1); + EXPECT_CALL(task_2, Run).Times(2); + + browser_ui_thread_scheduler_->RunAllPendingTasksForTesting(); +} + +TEST_F(BrowserUIThreadSchedulerTest, + RunAllPendingTasksForTestingIgnoresBestEffortIfNotEnabled) { + MockTask best_effort_task; + MockTask default_task; + + task_runners_[QueueType::kBestEffort]->PostTask(FROM_HERE, + best_effort_task.Get()); + task_runners_[QueueType::kDefault]->PostTask(FROM_HERE, default_task.Get()); + + EXPECT_CALL(default_task, Run); + + browser_ui_thread_scheduler_->RunAllPendingTasksForTesting(); +} + +TEST_F(BrowserUIThreadSchedulerTest, + RunAllPendingTasksForTestingRunsBestEffortTasksWhenEnabled) { + MockTask task_1; + MockTask task_2; + MockTask task_3; + EXPECT_CALL(task_1, Run).WillOnce(Invoke([&]() { + // This task should not run as it is posted after the + // RunAllPendingTasksForTesting() call + task_runners_[QueueType::kBestEffort]->PostTask(FROM_HERE, task_3.Get()); + browser_ui_thread_scheduler_->EnableBestEffortQueues(); + })); + EXPECT_CALL(task_2, Run); + + task_runners_[QueueType::kDefault]->PostTask(FROM_HERE, task_1.Get()); + task_runners_[QueueType::kBestEffort]->PostTask(FROM_HERE, task_2.Get()); browser_ui_thread_scheduler_->RunAllPendingTasksForTesting(); }
diff --git a/content/browser/service_worker/embedded_worker_instance.cc b/content/browser/service_worker/embedded_worker_instance.cc index d7ea5af..3ac0a977 100644 --- a/content/browser/service_worker/embedded_worker_instance.cc +++ b/content/browser/service_worker/embedded_worker_instance.cc
@@ -17,6 +17,7 @@ #include "base/task/post_task.h" #include "base/trace_event/trace_event.h" #include "content/browser/bad_message.h" +#include "content/browser/data_url_loader_factory.h" #include "content/browser/devtools/devtools_instrumentation.h" #include "content/browser/devtools/service_worker_devtools_manager.h" #include "content/browser/renderer_host/render_process_host_impl.h" @@ -988,6 +989,8 @@ factory_bundle->set_bypass_redirect_checks(bypass_redirect_checks); ContentBrowserClient::NonNetworkURLLoaderFactoryMap non_network_factories; + non_network_factories[url::kDataScheme] = + std::make_unique<DataURLLoaderFactory>(); GetContentClient() ->browser() ->RegisterNonNetworkSubresourceURLLoaderFactories(
diff --git a/content/browser/worker_host/worker_script_fetch_initiator.cc b/content/browser/worker_host/worker_script_fetch_initiator.cc index 0f3b4af2..09f73a0 100644 --- a/content/browser/worker_host/worker_script_fetch_initiator.cc +++ b/content/browser/worker_host/worker_script_fetch_initiator.cc
@@ -13,6 +13,7 @@ #include "base/task/post_task.h" #include "content/browser/appcache/appcache_navigation_handle.h" #include "content/browser/appcache/appcache_navigation_handle_core.h" +#include "content/browser/data_url_loader_factory.h" #include "content/browser/file_url_loader_factory.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" #include "content/browser/storage_partition_impl.h" @@ -130,6 +131,8 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); ContentBrowserClient::NonNetworkURLLoaderFactoryMap non_network_factories; + non_network_factories[url::kDataScheme] = + std::make_unique<DataURLLoaderFactory>(); GetContentClient() ->browser() ->RegisterNonNetworkSubresourceURLLoaderFactories(
diff --git a/content/common/content_constants_internal.cc b/content/common/content_constants_internal.cc index d6e2a4f..f933ffa 100644 --- a/content/common/content_constants_internal.cc +++ b/content/common/content_constants_internal.cc
@@ -37,6 +37,7 @@ const char kMachBootstrapName[] = "rohitfork"; #endif +const char kCorsExemptPurposeHeaderName[] = "Purpose"; const char kCorsExemptRequestedWithHeaderName[] = "X-Requested-With"; } // namespace content
diff --git a/content/common/content_constants_internal.h b/content/common/content_constants_internal.h index b520383..abdc9ba2 100644 --- a/content/common/content_constants_internal.h +++ b/content/common/content_constants_internal.h
@@ -48,6 +48,7 @@ // Defines a HTTP header name that is set internally, and some code places // in content need to know the name to manage the header stored in // network::ResourceRequest::cors_exempt_headers. +extern const char kCorsExemptPurposeHeaderName[]; extern const char kCorsExemptRequestedWithHeaderName[]; } // namespace content
diff --git a/content/common/media/media_player_delegate_messages.h b/content/common/media/media_player_delegate_messages.h index 6df63ad..706adc9 100644 --- a/content/common/media/media_player_delegate_messages.h +++ b/content/common/media/media_player_delegate_messages.h
@@ -32,8 +32,9 @@ // Messages from the browser to the renderer requesting playback state changes. // ---------------------------------------------------------------------------- -IPC_MESSAGE_ROUTED1(MediaPlayerDelegateMsg_Pause, - int /* delegate_id, distinguishes instances */) +IPC_MESSAGE_ROUTED2(MediaPlayerDelegateMsg_Pause, + int /* delegate_id, distinguishes instances */, + bool /* triggered_by_user */) IPC_MESSAGE_ROUTED1(MediaPlayerDelegateMsg_Play, int /* delegate_id, distinguishes instances */)
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherIntegrationTest.java b/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherIntegrationTest.java index 33961e60e..c620e734 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherIntegrationTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/ChildProcessLauncherIntegrationTest.java
@@ -67,7 +67,7 @@ boolean bindToCaller, boolean bindAsExternalService, Bundle childProcessCommonParameters) { super(context, serviceName, bindToCaller, bindAsExternalService, - childProcessCommonParameters); + childProcessCommonParameters, null /* instanceName */); } @Override
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/scheduler/UiThreadSchedulerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/scheduler/UiThreadSchedulerTest.java index 07ff7c6..caeb8436 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/scheduler/UiThreadSchedulerTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/scheduler/UiThreadSchedulerTest.java
@@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; /** @@ -226,6 +227,52 @@ Assert.assertTrue(taskExecuted.get()); } + @Test + @MediumTest + public void testChoreographerFrameTrait() throws Exception { + List<Integer> orderList = new ArrayList<>(); + CountDownLatch latch = new CountDownLatch(3); + // Post a task so we can run on the UI thread. + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { + @Override + public void run() { + PostTask.postTask(TaskTraits.CHOREOGRAPHER_FRAME, new Runnable() { + @Override + public void run() { + synchronized (orderList) { + orderList.add(1); + latch.countDown(); + } + } + }); + + PostTask.postTask(TaskTraits.CHOREOGRAPHER_FRAME, new Runnable() { + @Override + public void run() { + synchronized (orderList) { + orderList.add(2); + latch.countDown(); + } + } + }); + + PostTask.postTask(UiThreadTaskTraits.DEFAULT, new Runnable() { + @Override + public void run() { + synchronized (orderList) { + orderList.add(3); + latch.countDown(); + } + } + }); + } + }); + latch.await(); + + // The UiThreadTaskTraits.DEFAULT task should run before the two choreographer tasks. + assertThat(orderList, contains(3, 1, 2)); + } + private void startContentMainOnUiThread() { final Object lock = new Object(); final AtomicBoolean uiThreadInitalized = new AtomicBoolean();
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index 7a48231..445e1feb 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -397,7 +397,8 @@ return std::string(); } -QuotaPermissionContext* ContentBrowserClient::CreateQuotaPermissionContext() { +scoped_refptr<QuotaPermissionContext> +ContentBrowserClient::CreateQuotaPermissionContext() { return nullptr; }
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 71730143..0a1bf5d 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -30,6 +30,7 @@ #include "content/public/browser/navigation_throttle.h" #include "content/public/browser/overlay_window.h" #include "content/public/browser/page_visibility_state.h" +#include "content/public/browser/quota_permission_context.h" #include "content/public/browser/resource_request_info.h" #include "content/public/common/content_client.h" #include "content/public/common/previews_state.h" @@ -732,7 +733,7 @@ bool* in_memory); // Create and return a new quota permission context. - virtual QuotaPermissionContext* CreateQuotaPermissionContext(); + virtual scoped_refptr<QuotaPermissionContext> CreateQuotaPermissionContext(); // Allows the embedder to provide settings that determine the amount // of disk space that may be used by content facing storage apis like
diff --git a/content/public/browser/cors_exempt_headers.cc b/content/public/browser/cors_exempt_headers.cc index c82e8d71..616f3a4 100644 --- a/content/public/browser/cors_exempt_headers.cc +++ b/content/public/browser/cors_exempt_headers.cc
@@ -12,6 +12,7 @@ // Note: This mechanism will be deprecated in the near future. You can find // a recommended alternative approach on URLRequest::cors_exempt_headers at // services/network/public/mojom/url_loader.mojom. + params->cors_exempt_header_list.push_back(kCorsExemptPurposeHeaderName); params->cors_exempt_header_list.push_back(kCorsExemptRequestedWithHeaderName); }
diff --git a/content/public/common/url_utils.cc b/content/public/common/url_utils.cc index 43da363b..5fcc9b7 100644 --- a/content/public/common/url_utils.cc +++ b/content/public/common/url_utils.cc
@@ -64,8 +64,7 @@ bool IsURLHandledByNetworkService(const GURL& url) { return url.SchemeIsHTTPOrHTTPS() || url.SchemeIsWSOrWSS() || - url.SchemeIs(url::kFtpScheme) || url.SchemeIs(url::kGopherScheme) || - url.SchemeIs(url::kDataScheme); + url.SchemeIs(url::kFtpScheme) || url.SchemeIs(url::kGopherScheme); } bool IsRendererDebugURL(const GURL& url) {
diff --git a/content/public/renderer/resource_dispatcher_delegate.h b/content/public/renderer/resource_dispatcher_delegate.h index 565d2006..c255239 100644 --- a/content/public/renderer/resource_dispatcher_delegate.h +++ b/content/public/renderer/resource_dispatcher_delegate.h
@@ -8,7 +8,6 @@ #include <string> #include "content/common/content_export.h" -#include "content/public/common/resource_type.h" class GURL; @@ -24,9 +23,7 @@ public: virtual ~ResourceDispatcherDelegate() {} - virtual std::unique_ptr<RequestPeer> OnRequestComplete( - std::unique_ptr<RequestPeer> current_peer, - int error_code) = 0; + virtual void OnRequestComplete() = 0; // Note that |url|, |referrer| and |method| are the final values (e.g. after // any redirects).
diff --git a/content/public/renderer/window_features_converter.cc b/content/public/renderer/window_features_converter.cc index b8dc864..49fd3e6 100644 --- a/content/public/renderer/window_features_converter.cc +++ b/content/public/renderer/window_features_converter.cc
@@ -4,6 +4,12 @@ #include "content/public/renderer/window_features_converter.h" +// This converter only converts WebWindowFeatures members +// which should be used across process boundaries. +// All the members of WebWindowFeatures are listed in web_window_features.h, +// and classified to two groups, one is transferred by this converter +// and one is not. + namespace content { blink::mojom::WindowFeaturesPtr ConvertWebWindowFeaturesToMojoWindowFeatures(
diff --git a/content/public/test/navigation_simulator.h b/content/public/test/navigation_simulator.h index ee42a3e..1cc8c2b 100644 --- a/content/public/test/navigation_simulator.h +++ b/content/public/test/navigation_simulator.h
@@ -254,6 +254,9 @@ // commits. They should be specified before calling |Fail| or |Commit|. virtual void SetSocketAddress(const net::IPEndPoint& remote_endpoint) = 0; + // Pretend the navigation response is served from cache. + virtual void SetWasFetchedViaCache(bool was_fetched_via_cache) = 0; + // Pretend the navigation is against an inner response of a signed exchange. virtual void SetIsSignedExchangeInnerResponse( bool is_signed_exchange_inner_response) = 0;
diff --git a/content/renderer/loader/resource_dispatcher.cc b/content/renderer/loader/resource_dispatcher.cc index 9bc5663..962ddf90 100644 --- a/content/renderer/loader/resource_dispatcher.cc +++ b/content/renderer/loader/resource_dispatcher.cc
@@ -281,10 +281,7 @@ RequestPeer* peer = request_info->peer.get(); if (delegate_) { - std::unique_ptr<RequestPeer> new_peer = delegate_->OnRequestComplete( - std::move(request_info->peer), status.error_code); - DCHECK(new_peer); - request_info->peer = std::move(new_peer); + delegate_->OnRequestComplete(); } network::URLLoaderCompletionStatus renderer_status(status);
diff --git a/content/renderer/loader/resource_dispatcher_unittest.cc b/content/renderer/loader/resource_dispatcher_unittest.cc index b3254be..dab6a80 100644 --- a/content/renderer/loader/resource_dispatcher_unittest.cc +++ b/content/renderer/loader/resource_dispatcher_unittest.cc
@@ -179,11 +179,7 @@ TestResourceDispatcherDelegate() {} ~TestResourceDispatcherDelegate() override {} - std::unique_ptr<RequestPeer> OnRequestComplete( - std::unique_ptr<RequestPeer> current_peer, - int error_code) override { - return current_peer; - } + void OnRequestComplete() override {} std::unique_ptr<RequestPeer> OnReceivedResponse( std::unique_ptr<RequestPeer> current_peer,
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc index 7e11c59..20625ce 100644 --- a/content/renderer/loader/web_url_loader_impl.cc +++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -679,6 +679,13 @@ kCorsExemptRequestedWithHeaderName, WebString(request.GetRequestedWithHeader()).Utf8()); } + // Set Purpose header to cors_exempt_headers rather than headers to be + // exempted from CORS checks. + if (!request.GetPurposeHeader().IsEmpty()) { + resource_request->cors_exempt_headers.SetHeader( + kCorsExemptPurposeHeaderName, + WebString(request.GetPurposeHeader()).Utf8()); + } if (resource_request->resource_type == RESOURCE_TYPE_PREFETCH || resource_request->resource_type == RESOURCE_TYPE_FAVICON) {
diff --git a/content/renderer/media/renderer_webmediaplayer_delegate.cc b/content/renderer/media/renderer_webmediaplayer_delegate.cc index e229913..4b8faa4 100644 --- a/content/renderer/media/renderer_webmediaplayer_delegate.cc +++ b/content/renderer/media/renderer_webmediaplayer_delegate.cc
@@ -270,17 +270,21 @@ ScheduleUpdateTask(); } -void RendererWebMediaPlayerDelegate::OnMediaDelegatePause(int player_id) { +void RendererWebMediaPlayerDelegate::OnMediaDelegatePause( + int player_id, + bool triggered_by_user) { RecordAction(base::UserMetricsAction("Media.Controls.RemotePause")); Observer* observer = id_map_.Lookup(player_id); if (observer) { - // TODO(avayvod): remove when default play/pause is handled via - // the MediaSession code path. - std::unique_ptr<blink::WebScopedUserGesture> gesture( - render_frame() - ? new blink::WebScopedUserGesture(render_frame()->GetWebFrame()) - : nullptr); + if (triggered_by_user) { + // TODO(avayvod): remove when default play/pause is handled via + // the MediaSession code path. + std::unique_ptr<blink::WebScopedUserGesture> gesture( + render_frame() + ? new blink::WebScopedUserGesture(render_frame()->GetWebFrame()) + : nullptr); + } observer->OnPause(); } }
diff --git a/content/renderer/media/renderer_webmediaplayer_delegate.h b/content/renderer/media/renderer_webmediaplayer_delegate.h index 896e729..3e3921e 100644 --- a/content/renderer/media/renderer_webmediaplayer_delegate.h +++ b/content/renderer/media/renderer_webmediaplayer_delegate.h
@@ -87,7 +87,7 @@ friend class RendererWebMediaPlayerDelegateTest; private: - void OnMediaDelegatePause(int player_id); + void OnMediaDelegatePause(int player_id, bool triggered_by_user); void OnMediaDelegatePlay(int player_id); void OnMediaDelegateMuted(int player_id, bool muted); void OnMediaDelegateSeekForward(int player_id, base::TimeDelta seek_time);
diff --git a/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc b/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc index 8d1526a..64a7efd 100644 --- a/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc +++ b/content/renderer/media/renderer_webmediaplayer_delegate_browsertest.cc
@@ -80,7 +80,8 @@ } void CallOnMediaDelegatePause(int delegate_id) { - delegate_manager_->OnMediaDelegatePause(delegate_id); + delegate_manager_->OnMediaDelegatePause(delegate_id, + true /* triggered_by_user */); } void SetIsLowEndDeviceForTesting() { @@ -206,7 +207,8 @@ delegate_manager_->WasShown(); EXPECT_CALL(observer_1_, OnPause()); - MediaPlayerDelegateMsg_Pause pause_msg(0, delegate_id); + MediaPlayerDelegateMsg_Pause pause_msg(0, delegate_id, + true /* triggered_by_user */); delegate_manager_->OnMessageReceived(pause_msg); EXPECT_CALL(observer_1_, OnPlay());
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc index 04128d2..7b52db6 100644 --- a/content/shell/browser/shell_content_browser_client.cc +++ b/content/shell/browser/shell_content_browser_client.cc
@@ -428,7 +428,7 @@ return CreateShellWebContentsViewDelegate(web_contents); } -QuotaPermissionContext* +scoped_refptr<content::QuotaPermissionContext> ShellContentBrowserClient::CreateQuotaPermissionContext() { return new ShellQuotaPermissionContext(); }
diff --git a/content/shell/browser/shell_content_browser_client.h b/content/shell/browser/shell_content_browser_client.h index 3828b35..223774a 100644 --- a/content/shell/browser/shell_content_browser_client.h +++ b/content/shell/browser/shell_content_browser_client.h
@@ -59,7 +59,8 @@ std::string GetDefaultDownloadName() override; WebContentsViewDelegate* GetWebContentsViewDelegate( WebContents* web_contents) override; - QuotaPermissionContext* CreateQuotaPermissionContext() override; + scoped_refptr<content::QuotaPermissionContext> CreateQuotaPermissionContext() + override; void GetQuotaSettings( content::BrowserContext* context, content::StoragePartition* partition,
diff --git a/content/test/data/back_forward_cache/page_with_cross_origin_subframe_with_pageshow.html b/content/test/data/back_forward_cache/page_with_cross_origin_subframe_with_pageshow.html new file mode 100644 index 0000000..6be983d --- /dev/null +++ b/content/test/data/back_forward_cache/page_with_cross_origin_subframe_with_pageshow.html
@@ -0,0 +1,5 @@ +<html> +<head></head> +<body>This page has a cross-origin subframe which has an onpageshow() event listener.</body> + <iframe name="frame1" src="/cross-site/bar.com/back_forward_cache/page_with_pageshow.html"/> +</html>
diff --git a/content/test/data/back_forward_cache/page_with_pageshow.html b/content/test/data/back_forward_cache/page_with_pageshow.html index 6cf0dda3..d239326d 100644 --- a/content/test/data/back_forward_cache/page_with_pageshow.html +++ b/content/test/data/back_forward_cache/page_with_pageshow.html
@@ -1,6 +1,6 @@ <html> <head></head> -<body>This page creates a WebSocket.</body> +<body>This page has an onpageshow() event listener.</body> <script> window.addEventListener("pageshow", () => {}); </script>
diff --git a/content/test/data/back_forward_cache/page_with_same_origin_subframe_with_pageshow.html b/content/test/data/back_forward_cache/page_with_same_origin_subframe_with_pageshow.html new file mode 100644 index 0000000..d427f3c7 --- /dev/null +++ b/content/test/data/back_forward_cache/page_with_same_origin_subframe_with_pageshow.html
@@ -0,0 +1,5 @@ +<html> +<head></head> +<body>This page has a same-origin subframe which has an onpageshow() event listener.</body> + <iframe name="frame1" src="page_with_pageshow.html"/> +</html>
diff --git a/content/test/navigation_simulator_impl.cc b/content/test/navigation_simulator_impl.cc index 21a65ebf..a7b3581 100644 --- a/content/test/navigation_simulator_impl.cc +++ b/content/test/navigation_simulator_impl.cc
@@ -519,8 +519,9 @@ if (frame_tree_node_->navigation_request()) { static_cast<TestRenderFrameHost*>(frame_tree_node_->current_frame_host()) ->PrepareForCommitDeprecatedForNavigationSimulator( - remote_endpoint_, is_signed_exchange_inner_response_, - http_connection_info_, ssl_info_); + remote_endpoint_, was_fetched_via_cache_, + is_signed_exchange_inner_response_, http_connection_info_, + ssl_info_); } // Synchronous failure can cause the navigation to finish here. @@ -840,6 +841,13 @@ remote_endpoint_ = remote_endpoint; } +void NavigationSimulatorImpl::SetWasFetchedViaCache( + bool was_fetched_via_cache) { + CHECK_LE(state_, STARTED) << "The was_fetched_via_cache flag cannot be set " + "after the navigation has committed or failed"; + was_fetched_via_cache_ = was_fetched_via_cache; +} + void NavigationSimulatorImpl::SetIsSignedExchangeInnerResponse( bool is_signed_exchange_inner_response) { CHECK_LE(state_, STARTED) << "The signed exchange flag cannot be set after "
diff --git a/content/test/navigation_simulator_impl.h b/content/test/navigation_simulator_impl.h index 517dbdc..d9ff4dd2 100644 --- a/content/test/navigation_simulator_impl.h +++ b/content/test/navigation_simulator_impl.h
@@ -81,6 +81,7 @@ void SetIsFormSubmission(bool is_form_submission) override; void SetReferrer(const Referrer& referrer) override; void SetSocketAddress(const net::IPEndPoint& remote_endpoint) override; + void SetWasFetchedViaCache(bool was_fetched_via_cache) override; void SetIsSignedExchangeInnerResponse( bool is_signed_exchange_inner_response) override; void SetInterfaceProviderRequest( @@ -249,6 +250,7 @@ GURL original_url_; GURL navigation_url_; net::IPEndPoint remote_endpoint_; + bool was_fetched_via_cache_ = false; bool is_signed_exchange_inner_response_ = false; std::string initial_method_; bool is_form_submission_ = false;
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc index c37656d..bfd60896 100644 --- a/content/test/test_render_frame_host.cc +++ b/content/test/test_render_frame_host.cc
@@ -362,6 +362,7 @@ void TestRenderFrameHost::PrepareForCommit() { PrepareForCommitInternal(GURL(), net::IPEndPoint(), + /* was_fetched_via_cache=*/false, /* is_signed_exchange_inner_response=*/false, net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN, base::nullopt); @@ -369,10 +370,11 @@ void TestRenderFrameHost::PrepareForCommitDeprecatedForNavigationSimulator( const net::IPEndPoint& remote_endpoint, + bool was_fetched_via_cache, bool is_signed_exchange_inner_response, net::HttpResponseInfo::ConnectionInfo connection_info, base::Optional<net::SSLInfo> ssl_info) { - PrepareForCommitInternal(GURL(), remote_endpoint, + PrepareForCommitInternal(GURL(), remote_endpoint, was_fetched_via_cache, is_signed_exchange_inner_response, connection_info, ssl_info); } @@ -380,6 +382,7 @@ void TestRenderFrameHost::PrepareForCommitWithServerRedirect( const GURL& redirect_url) { PrepareForCommitInternal(redirect_url, net::IPEndPoint(), + /* was_fetched_via_cache=*/false, /* is_signed_exchange_inner_response=*/false, net::HttpResponseInfo::CONNECTION_INFO_UNKNOWN, base::nullopt); @@ -388,6 +391,7 @@ void TestRenderFrameHost::PrepareForCommitInternal( const GURL& redirect_url, const net::IPEndPoint& remote_endpoint, + bool was_fetched_via_cache, bool is_signed_exchange_inner_response, net::HttpResponseInfo::ConnectionInfo connection_info, base::Optional<net::SSLInfo> ssl_info) { @@ -429,6 +433,7 @@ scoped_refptr<network::ResourceResponse> response( new network::ResourceResponse); response->head.remote_endpoint = remote_endpoint; + response->head.was_fetched_via_cache = was_fetched_via_cache; response->head.is_signed_exchange_inner_response = is_signed_exchange_inner_response; response->head.connection_info = connection_info;
diff --git a/content/test/test_render_frame_host.h b/content/test/test_render_frame_host.h index 7d464d6f..c5dfa409 100644 --- a/content/test/test_render_frame_host.h +++ b/content/test/test_render_frame_host.h
@@ -144,6 +144,7 @@ // remove this function. void PrepareForCommitDeprecatedForNavigationSimulator( const net::IPEndPoint& remote_endpoint, + bool was_fetched_via_cache, bool is_signed_exchange_inner_response, net::HttpResponseInfo::ConnectionInfo connection_info, base::Optional<net::SSLInfo> ssl_info); @@ -248,6 +249,7 @@ void PrepareForCommitInternal( const GURL& redirect_url, const net::IPEndPoint& remote_endpoint, + bool was_fetched_via_cache, bool is_signed_exchange_inner_response, net::HttpResponseInfo::ConnectionInfo connection_info, base::Optional<net::SSLInfo> ssl_info);
diff --git a/dbus/property.cc b/dbus/property.cc index 7ec7eb7..489ef99 100644 --- a/dbus/property.cc +++ b/dbus/property.cc
@@ -105,12 +105,9 @@ writer.AppendString(property->name()); DCHECK(object_proxy_); - object_proxy_->CallMethod(&method_call, - ObjectProxy::TIMEOUT_USE_DEFAULT, - base::Bind(&PropertySet::OnGet, - GetWeakPtr(), - property, - callback)); + object_proxy_->CallMethod(&method_call, ObjectProxy::TIMEOUT_USE_DEFAULT, + base::BindOnce(&PropertySet::OnGet, GetWeakPtr(), + property, std::move(callback))); } void PropertySet::OnGet(PropertyBase* property, GetCallback callback, @@ -132,7 +129,7 @@ } if (!callback.is_null()) - callback.Run(response); + std::move(callback).Run(response); } bool PropertySet::GetAndBlock(PropertyBase* property) { @@ -196,12 +193,9 @@ property->AppendSetValueToWriter(&writer); DCHECK(object_proxy_); - object_proxy_->CallMethod(&method_call, - ObjectProxy::TIMEOUT_USE_DEFAULT, - base::Bind(&PropertySet::OnSet, - GetWeakPtr(), - property, - callback)); + object_proxy_->CallMethod(&method_call, ObjectProxy::TIMEOUT_USE_DEFAULT, + base::BindOnce(&PropertySet::OnSet, GetWeakPtr(), + property, std::move(callback))); } bool PropertySet::SetAndBlock(PropertyBase* property) { @@ -224,7 +218,7 @@ Response* response) { LOG_IF(WARNING, !response) << property->name() << ": Set: failed."; if (!callback.is_null()) - callback.Run(response); + std::move(callback).Run(response); } bool PropertySet::UpdatePropertiesFromReader(MessageReader* reader) {
diff --git a/dbus/property.h b/dbus/property.h index 6dc49474..68cf38b3 100644 --- a/dbus/property.h +++ b/dbus/property.h
@@ -250,7 +250,7 @@ // Callback for Get() method, |success| indicates whether or not the // value could be retrived, if true the new value can be obtained by // calling value() on the property. - typedef base::Callback<void(bool success)> GetCallback; + using GetCallback = base::OnceCallback<void(bool success)>; // Requests an updated value from the remote object for |property| // incurring a round-trip. |callback| will be called when the new @@ -274,7 +274,7 @@ // Callback for Set() method, |success| indicates whether or not the // new property value was accepted by the remote object. - typedef base::Callback<void(bool success)> SetCallback; + using SetCallback = base::OnceCallback<void(bool success)>; // Requests that the remote object for |property| change the property to // its new value. |callback| will be called to indicate the success or @@ -387,7 +387,7 @@ // round-trip. |callback| will be called when the new value is available. // This may not be implemented by some interfaces. virtual void Get(dbus::PropertySet::GetCallback callback) { - property_set()->Get(this, callback); + property_set()->Get(this, std::move(callback)); } // The synchronous version of Get(). @@ -402,7 +402,7 @@ // remote object. virtual void Set(const T& value, dbus::PropertySet::SetCallback callback) { set_value_ = value; - property_set()->Set(this, callback); + property_set()->Set(this, std::move(callback)); } // The synchronous version of Set().
diff --git a/device/bluetooth/dbus/fake_bluetooth_adapter_client.cc b/device/bluetooth/dbus/fake_bluetooth_adapter_client.cc index 853d52e5..e9dd80f 100644 --- a/device/bluetooth/dbus/fake_bluetooth_adapter_client.cc +++ b/device/bluetooth/dbus/fake_bluetooth_adapter_client.cc
@@ -52,7 +52,7 @@ dbus::PropertyBase* property, dbus::PropertySet::GetCallback callback) { VLOG(1) << "Get " << property->name(); - callback.Run(false); + std::move(callback).Run(false); } void FakeBluetoothAdapterClient::Properties::GetAll() { @@ -66,10 +66,10 @@ if (property->name() == powered.name() || property->name() == alias.name() || property->name() == discoverable.name() || property->name() == discoverable_timeout.name()) { - callback.Run(true); + std::move(callback).Run(true); property->ReplaceValueWithSetValue(); } else { - callback.Run(false); + std::move(callback).Run(false); } }
diff --git a/device/bluetooth/dbus/fake_bluetooth_device_client.cc b/device/bluetooth/dbus/fake_bluetooth_device_client.cc index 1446da1..cc4b1a60 100644 --- a/device/bluetooth/dbus/fake_bluetooth_device_client.cc +++ b/device/bluetooth/dbus/fake_bluetooth_device_client.cc
@@ -279,7 +279,7 @@ dbus::PropertyBase* property, dbus::PropertySet::GetCallback callback) { VLOG(1) << "Get " << property->name(); - callback.Run(false); + std::move(callback).Run(false); } void FakeBluetoothDeviceClient::Properties::GetAll() { @@ -291,10 +291,10 @@ dbus::PropertySet::SetCallback callback) { VLOG(1) << "Set " << property->name(); if (property->name() == trusted.name()) { - callback.Run(true); + std::move(callback).Run(true); property->ReplaceValueWithSetValue(); } else { - callback.Run(false); + std::move(callback).Run(false); } }
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.cc index a0369e5..a9180eb 100644 --- a/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.cc +++ b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.cc
@@ -62,7 +62,7 @@ dbus::PropertyBase* property, dbus::PropertySet::GetCallback callback) { VLOG(1) << "Get " << property->name(); - callback.Run(true); + std::move(callback).Run(true); } void FakeBluetoothGattCharacteristicClient::Properties::GetAll() { @@ -73,7 +73,7 @@ dbus::PropertyBase* property, dbus::PropertySet::SetCallback callback) { VLOG(1) << "Set " << property->name(); - callback.Run(false); + std::move(callback).Run(false); } FakeBluetoothGattCharacteristicClient::FakeBluetoothGattCharacteristicClient()
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.cc index a3b2acb..cce7db84 100644 --- a/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.cc +++ b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.cc
@@ -37,7 +37,7 @@ dbus::PropertyBase* property, dbus::PropertySet::GetCallback callback) { VLOG(1) << "Get " << property->name(); - callback.Run(true); + std::move(callback).Run(true); } void FakeBluetoothGattDescriptorClient::Properties::GetAll() { @@ -48,7 +48,7 @@ dbus::PropertyBase* property, dbus::PropertySet::SetCallback callback) { VLOG(1) << "Set " << property->name(); - callback.Run(false); + std::move(callback).Run(false); } FakeBluetoothGattDescriptorClient::DescriptorData::DescriptorData() = default;
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.cc b/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.cc index 37a84ac..b3781d6 100644 --- a/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.cc +++ b/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.cc
@@ -41,7 +41,7 @@ dbus::PropertyBase* property, dbus::PropertySet::GetCallback callback) { VLOG(1) << "Get " << property->name(); - callback.Run(false); + std::move(callback).Run(false); } void FakeBluetoothGattServiceClient::Properties::GetAll() { @@ -50,9 +50,9 @@ void FakeBluetoothGattServiceClient::Properties::Set( dbus::PropertyBase* property, - dbus::PropertySet::GetCallback callback) { + dbus::PropertySet::SetCallback callback) { VLOG(1) << "Set " << property->name(); - callback.Run(false); + std::move(callback).Run(false); } FakeBluetoothGattServiceClient::FakeBluetoothGattServiceClient()
diff --git a/device/bluetooth/dbus/fake_bluetooth_input_client.cc b/device/bluetooth/dbus/fake_bluetooth_input_client.cc index 5ce6953d..9d72a0de2 100644 --- a/device/bluetooth/dbus/fake_bluetooth_input_client.cc +++ b/device/bluetooth/dbus/fake_bluetooth_input_client.cc
@@ -31,7 +31,7 @@ dbus::PropertyBase* property, dbus::PropertySet::GetCallback callback) { VLOG(1) << "Get " << property->name(); - callback.Run(false); + std::move(callback).Run(false); } void FakeBluetoothInputClient::Properties::GetAll() { @@ -42,7 +42,7 @@ dbus::PropertyBase* property, dbus::PropertySet::SetCallback callback) { VLOG(1) << "Set " << property->name(); - callback.Run(false); + std::move(callback).Run(false); } FakeBluetoothInputClient::FakeBluetoothInputClient() = default;
diff --git a/device/bluetooth/dbus/fake_bluetooth_media_transport_client.cc b/device/bluetooth/dbus/fake_bluetooth_media_transport_client.cc index e5f7156..990f9fe5 100644 --- a/device/bluetooth/dbus/fake_bluetooth_media_transport_client.cc +++ b/device/bluetooth/dbus/fake_bluetooth_media_transport_client.cc
@@ -74,7 +74,7 @@ dbus::PropertyBase* property, dbus::PropertySet::GetCallback callback) { VLOG(1) << "Get " << property->name(); - callback.Run(false); + std::move(callback).Run(false); } void FakeBluetoothMediaTransportClient::Properties::GetAll() { @@ -85,7 +85,7 @@ dbus::PropertyBase* property, dbus::PropertySet::SetCallback callback) { VLOG(1) << "Set " << property->name(); - callback.Run(false); + std::move(callback).Run(false); } FakeBluetoothMediaTransportClient::Transport::Transport(
diff --git a/extensions/browser/api/management/management_api.cc b/extensions/browser/api/management/management_api.cc index 5026753..17677a5 100644 --- a/extensions/browser/api/management/management_api.cc +++ b/extensions/browser/api/management/management_api.cc
@@ -846,6 +846,11 @@ auto* api_delegate = ManagementAPI::GetFactoryInstance() ->Get(browser_context()) ->GetDelegate(); + if (!api_delegate->CanContextInstallWebApps(browser_context())) { + return RespondNow( + Error(keys::kInstallReplacementWebAppInvalidContextError)); + } + if (api_delegate->IsWebAppInstalled(browser_context(), web_app_url)) { return RespondNow( Error(keys::kInstallReplacementWebAppAlreadyInstalledError));
diff --git a/extensions/browser/api/management/management_api_constants.cc b/extensions/browser/api/management/management_api_constants.cc index 1108e4c..e5fd74e 100644 --- a/extensions/browser/api/management/management_api_constants.cc +++ b/extensions/browser/api/management/management_api_constants.cc
@@ -51,6 +51,8 @@ "Web app is already installed."; const char kInstallReplacementWebAppInvalidWebAppError[] = "Web app is not a valid installable web app."; +const char kInstallReplacementWebAppInvalidContextError[] = + "Web apps can't be installed in the current user profile."; const char kGestureNeededForInstallReplacementWebAppError[] = "chrome.management.installWebApp requires a user gesture.";
diff --git a/extensions/browser/api/management/management_api_constants.h b/extensions/browser/api/management/management_api_constants.h index ce767cae..f64123e 100644 --- a/extensions/browser/api/management/management_api_constants.h +++ b/extensions/browser/api/management/management_api_constants.h
@@ -38,6 +38,7 @@ extern const char kCannotChangePrimaryKioskAppError[]; extern const char kInstallReplacementWebAppAlreadyInstalledError[]; extern const char kInstallReplacementWebAppInvalidWebAppError[]; +extern const char kInstallReplacementWebAppInvalidContextError[]; extern const char kGestureNeededForInstallReplacementWebAppError[]; } // namespace extension_management_api_constants
diff --git a/extensions/browser/api/management/management_api_delegate.h b/extensions/browser/api/management/management_api_delegate.h index 3da5c62..0fce178 100644 --- a/extensions/browser/api/management/management_api_delegate.h +++ b/extensions/browser/api/management/management_api_delegate.h
@@ -124,6 +124,9 @@ // Returns true if there is already a web app installed for |web_app_url|. virtual bool IsWebAppInstalled(content::BrowserContext* context, const GURL& web_app_url) const = 0; + // Returns whether the current user type can install web apps. + virtual bool CanContextInstallWebApps( + content::BrowserContext* context) const = 0; // Installs a web app for |web_app_url|. virtual void InstallReplacementWebApp(
diff --git a/extensions/browser/sandboxed_unpacker.cc b/extensions/browser/sandboxed_unpacker.cc index 316c5b5..5e60ac9 100644 --- a/extensions/browser/sandboxed_unpacker.cc +++ b/extensions/browser/sandboxed_unpacker.cc
@@ -212,6 +212,8 @@ return message_catalog_paths; } +base::Optional<crx_file::VerifierFormat> g_verifier_format_override_for_test; + } // namespace SandboxedUnpackerClient::SandboxedUnpackerClient() @@ -221,6 +223,17 @@ DCHECK_CURRENTLY_ON(BrowserThread::UI); } +SandboxedUnpacker::ScopedVerifierFormatOverrideForTest:: + ScopedVerifierFormatOverrideForTest(crx_file::VerifierFormat format) { + DCHECK(!g_verifier_format_override_for_test.has_value()); + g_verifier_format_override_for_test = format; +} + +SandboxedUnpacker::ScopedVerifierFormatOverrideForTest:: + ~ScopedVerifierFormatOverrideForTest() { + g_verifier_format_override_for_test.reset(); +} + SandboxedUnpacker::SandboxedUnpacker( std::unique_ptr<service_manager::Connector> connector, Manifest::Location location, @@ -295,7 +308,8 @@ // Extract the public key and validate the package. if (!ValidateSignature(crx_info.path, expected_hash, - crx_info.required_format)) + g_verifier_format_override_for_test.value_or( + crx_info.required_format))) return; // ValidateSignature() already reported the error. // Copy the crx file into our working directory.
diff --git a/extensions/browser/sandboxed_unpacker.h b/extensions/browser/sandboxed_unpacker.h index feb9130..c3d1dbb 100644 --- a/extensions/browser/sandboxed_unpacker.h +++ b/extensions/browser/sandboxed_unpacker.h
@@ -110,6 +110,15 @@ // class SandboxedUnpacker : public base::RefCountedThreadSafe<SandboxedUnpacker> { public: + // Overrides the required verifier format for testing purposes. Only one + // ScopedVerifierFormatOverrideForTest may exist at a time. + class ScopedVerifierFormatOverrideForTest { + public: + explicit ScopedVerifierFormatOverrideForTest( + crx_file::VerifierFormat format); + ~ScopedVerifierFormatOverrideForTest(); + }; + // Creates a SandboxedUnpacker that will do work to unpack an extension, // passing the |location| and |creation_flags| to Extension::Create. The // |extensions_dir| parameter should specify the directory under which we'll
diff --git a/extensions/common/verifier_formats.cc b/extensions/common/verifier_formats.cc index 25b90c1..b12db6e 100644 --- a/extensions/common/verifier_formats.cc +++ b/extensions/common/verifier_formats.cc
@@ -7,9 +7,7 @@ namespace extensions { crx_file::VerifierFormat GetWebstoreVerifierFormat() { - // TODO(waffles@chromium.org): This should be CRX3_WITH_PUBLISHER_PROOF, but - // we have not decided how to sign the test data yet. - return crx_file::VerifierFormat::CRX3; + return crx_file::VerifierFormat::CRX3_WITH_PUBLISHER_PROOF; } crx_file::VerifierFormat GetPolicyVerifierFormat(
diff --git a/gpu/command_buffer/build_raster_cmd_buffer.py b/gpu/command_buffer/build_raster_cmd_buffer.py index e13f9e4..643edd0 100755 --- a/gpu/command_buffer/build_raster_cmd_buffer.py +++ b/gpu/command_buffer/build_raster_cmd_buffer.py
@@ -107,7 +107,6 @@ 'gfx::BufferUsage::GPU_READ', 'gfx::BufferUsage::SCANOUT', 'gfx::BufferUsage::GPU_READ_CPU_READ_WRITE', - 'gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT', ], 'invalid': [ 'gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE',
diff --git a/gpu/command_buffer/service/external_vk_image_backing.cc b/gpu/command_buffer/service/external_vk_image_backing.cc index 55eaadb6..4c23e70 100644 --- a/gpu/command_buffer/service/external_vk_image_backing.cc +++ b/gpu/command_buffer/service/external_vk_image_backing.cc
@@ -141,22 +141,22 @@ NOTIMPLEMENTED_LOG_ONCE(); return nullptr; #elif defined(OS_LINUX) - VkMemoryGetFdInfoKHR get_fd_info; - get_fd_info.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR; - get_fd_info.pNext = nullptr; - get_fd_info.memory = memory_; - get_fd_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR; - - int memory_fd = -1; - vkGetMemoryFdKHR(device(), &get_fd_info, &memory_fd); - if (memory_fd < 0) { - LOG(ERROR) << "Unable to extract file descriptor out of external VkImage"; - return nullptr; - } - - gl::GLApi* api = gl::g_current_gl_context; - if (!texture_) { + VkMemoryGetFdInfoKHR get_fd_info; + get_fd_info.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR; + get_fd_info.pNext = nullptr; + get_fd_info.memory = memory_; + get_fd_info.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR; + + int memory_fd = -1; + vkGetMemoryFdKHR(device(), &get_fd_info, &memory_fd); + if (memory_fd < 0) { + LOG(ERROR) << "Unable to extract file descriptor out of external VkImage"; + return nullptr; + } + + gl::GLApi* api = gl::g_current_gl_context; + constexpr GLenum target = GL_TEXTURE_2D; constexpr GLenum get_target = GL_TEXTURE_BINDING_2D; GLuint internal_format = viz::TextureStorageFormat(format());
diff --git a/gpu/command_buffer/service/gl_utils.cc b/gpu/command_buffer/service/gl_utils.cc index 25def54d..fbfef93de 100644 --- a/gpu/command_buffer/service/gl_utils.cc +++ b/gpu/command_buffer/service/gl_utils.cc
@@ -914,6 +914,10 @@ dest_internal_format != GL_RGB10_A2) { return CopyTextureMethod::DRAW_AND_COPY; } + if (feature_info->workarounds().disable_copy_tex_image_2d_rgb10_a2_mali && + (dest_internal_format == GL_RGB || dest_internal_format == GL_RGBA)) { + return CopyTextureMethod::DRAW_AND_COPY; + } } // CopyTexImage* should not allow internalformat of GL_BGRA_EXT and
diff --git a/gpu/command_buffer/service/raster_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/raster_cmd_validation_implementation_autogen.h index d7e5536..6c7d04c 100644 --- a/gpu/command_buffer/service/raster_cmd_validation_implementation_autogen.h +++ b/gpu/command_buffer/service/raster_cmd_validation_implementation_autogen.h
@@ -68,7 +68,6 @@ gfx::BufferUsage::GPU_READ, gfx::BufferUsage::SCANOUT, gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, - gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT, }; static const viz::ResourceFormat valid_viz_resource_format_table[] = {
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 9a3eae1..24cac23 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
@@ -412,26 +412,18 @@ mailbox_, format, size_, color_space, usage, is_thread_safe); EXPECT_TRUE(backing_); - LOG(ERROR) << "cblume 1"; - // Check clearing. if (!backing_->IsCleared()) { backing_->SetCleared(); EXPECT_TRUE(backing_->IsCleared()); } - LOG(ERROR) << "cblume 2"; - // First, validate via a legacy mailbox. GLenum expected_target = GL_TEXTURE_2D; EXPECT_TRUE(backing_->ProduceLegacyMailbox(mailbox_manager_)); - LOG(ERROR) << "cblume 3"; - TextureBase* texture_base = mailbox_manager_->ConsumeTexture(mailbox_); - LOG(ERROR) << "cblume 4"; - // Currently there is no support for passthrough texture on android and hence // in AHB backing. So the TextureBase* should be pointing to a Texture object. auto* texture = gles2::Texture::CheckedCast(texture_base); @@ -445,18 +437,12 @@ EXPECT_EQ(width, size_.width()); EXPECT_EQ(height, size_.height()); - LOG(ERROR) << "cblume 5"; - shared_image_ = shared_image_manager->Register(std::move(backing_), memory_type_tracker); - LOG(ERROR) << "cblume 6"; - auto gl_representation = shared_image_representation_factory->ProduceGLTexture(mailbox_); - LOG(ERROR) << "cblume 7"; - EXPECT_TRUE(gl_representation); EXPECT_TRUE(gl_representation->GetTexture()->service_id()); EXPECT_EQ(expected_target, gl_representation->GetTexture()->target());
diff --git a/gpu/command_buffer/service/webgpu_decoder_impl.cc b/gpu/command_buffer/service/webgpu_decoder_impl.cc index aedc8bcf..9b2552e 100644 --- a/gpu/command_buffer/service/webgpu_decoder_impl.cc +++ b/gpu/command_buffer/service/webgpu_decoder_impl.cc
@@ -371,12 +371,42 @@ DawnDevice WebGPUDecoderImpl::CreateDefaultDevice() { dawn_instance_->DiscoverDefaultAdapters(); std::vector<dawn_native::Adapter> adapters = dawn_instance_->GetAdapters(); + + dawn_native::Adapter integrated_gpu_adapter = {}; + dawn_native::Adapter cpu_adapter = {}; + dawn_native::Adapter unknown_adapter = {}; + for (dawn_native::Adapter adapter : adapters) { if (adapter.GetBackendType() != dawn_native::BackendType::Null && adapter.GetBackendType() != dawn_native::BackendType::OpenGL) { - return adapter.CreateDevice(); + switch (adapter.GetDeviceType()) { + case dawn_native::DeviceType::DiscreteGPU: + // For now, we always prefer the discrete GPU + return adapter.CreateDevice(); + case dawn_native::DeviceType::IntegratedGPU: + integrated_gpu_adapter = adapter; + break; + case dawn_native::DeviceType::CPU: + cpu_adapter = adapter; + break; + case dawn_native::DeviceType::Unknown: + unknown_adapter = adapter; + break; + default: + NOTREACHED(); + break; + } } } + if (integrated_gpu_adapter) { + return integrated_gpu_adapter.CreateDevice(); + } + if (cpu_adapter) { + return cpu_adapter.CreateDevice(); + } + if (unknown_adapter) { + return unknown_adapter.CreateDevice(); + } return nullptr; }
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json index a0648773..2a767b3c 100644 --- a/gpu/config/gpu_driver_bug_list.json +++ b/gpu/config/gpu_driver_bug_list.json
@@ -3281,6 +3281,19 @@ "max_texture_size_limit_4096", "max_3d_array_texture_size_1024" ] + }, + { + "id": 302, + "description": "glCopyTexImage2D on Mali-T820 fails in certain cases if source is GL_RGB10_A2.", + "cr_bugs": [953771], + "os": { + "type": "android" + }, + "gl_vendor": "ARM.*", + "gl_renderer": "Mali-T820", + "features": [ + "disable_copy_tex_image_2d_rgb10_a2_mali" + ] } ] }
diff --git a/gpu/config/gpu_workaround_list.txt b/gpu/config/gpu_workaround_list.txt index 757690a4..6a7ccdb 100644 --- a/gpu/config/gpu_workaround_list.txt +++ b/gpu/config/gpu_workaround_list.txt
@@ -113,3 +113,4 @@ disable_copy_tex_image_2d_rgb10_a2_tegra use_eqaa_storage_samples_2 max_3d_array_texture_size_1024 +disable_copy_tex_image_2d_rgb10_a2_mali
diff --git a/gpu/ipc/common/gpu_memory_buffer_impl_io_surface.cc b/gpu/ipc/common/gpu_memory_buffer_impl_io_surface.cc index 56862fe..28e166d5 100644 --- a/gpu/ipc/common/gpu_memory_buffer_impl_io_surface.cc +++ b/gpu/ipc/common/gpu_memory_buffer_impl_io_surface.cc
@@ -30,7 +30,6 @@ case gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE: case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE: case gfx::BufferUsage::SCANOUT_VDA_WRITE: - case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: return 0; } NOTREACHED();
diff --git a/gpu/ipc/common/gpu_memory_buffer_impl_shared_memory.cc b/gpu/ipc/common/gpu_memory_buffer_impl_shared_memory.cc index 3ea3fa89..e39b772 100644 --- a/gpu/ipc/common/gpu_memory_buffer_impl_shared_memory.cc +++ b/gpu/ipc/common/gpu_memory_buffer_impl_shared_memory.cc
@@ -116,7 +116,6 @@ switch (usage) { case gfx::BufferUsage::GPU_READ: case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: - case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE: return true; case gfx::BufferUsage::SCANOUT:
diff --git a/gpu/ipc/common/gpu_memory_buffer_impl_test_template.h b/gpu/ipc/common/gpu_memory_buffer_impl_test_template.h index 1f1658db..21c2892 100644 --- a/gpu/ipc/common/gpu_memory_buffer_impl_test_template.h +++ b/gpu/ipc/common/gpu_memory_buffer_impl_test_template.h
@@ -87,15 +87,13 @@ const gfx::Size kBufferSize(8, 8); for (auto format : gfx::GetBufferFormatsForTesting()) { - gfx::BufferUsage usages[] = { - gfx::BufferUsage::GPU_READ, - gfx::BufferUsage::SCANOUT, - gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE, - gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE, - gfx::BufferUsage::SCANOUT_CPU_READ_WRITE, - gfx::BufferUsage::SCANOUT_VDA_WRITE, - gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, - gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT}; + gfx::BufferUsage usages[] = {gfx::BufferUsage::GPU_READ, + gfx::BufferUsage::SCANOUT, + gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE, + gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE, + gfx::BufferUsage::SCANOUT_CPU_READ_WRITE, + gfx::BufferUsage::SCANOUT_VDA_WRITE, + gfx::BufferUsage::GPU_READ_CPU_READ_WRITE}; for (auto usage : usages) { if (!TestFixture::gpu_memory_buffer_support()->IsConfigurationSupported( TypeParam::kBufferType, format, usage)) @@ -182,21 +180,20 @@ for (auto format : gfx::GetBufferFormatsForTesting()) { if (!TestFixture::gpu_memory_buffer_support()->IsConfigurationSupported( TypeParam::kBufferType, format, - gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT)) { + gfx::BufferUsage::GPU_READ_CPU_READ_WRITE)) { continue; } gfx::GpuMemoryBufferHandle handle; GpuMemoryBufferImpl::DestructionCallback destroy_callback = TestFixture::CreateGpuMemoryBuffer( - kBufferSize, format, - gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT, &handle, - nullptr); + kBufferSize, format, gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, + &handle, nullptr); std::unique_ptr<GpuMemoryBufferImpl> buffer( TestFixture::gpu_memory_buffer_support() ->CreateGpuMemoryBufferImplFromHandle( std::move(handle), kBufferSize, format, - gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT, + gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, std::move(destroy_callback))); ASSERT_TRUE(buffer); @@ -256,15 +253,13 @@ const gfx::GpuMemoryBufferType kBufferType = TypeParam::kBufferType; for (auto format : gfx::GetBufferFormatsForTesting()) { - gfx::BufferUsage usages[] = { - gfx::BufferUsage::GPU_READ, - gfx::BufferUsage::SCANOUT, - gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE, - gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE, - gfx::BufferUsage::SCANOUT_CPU_READ_WRITE, - gfx::BufferUsage::SCANOUT_VDA_WRITE, - gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, - gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT}; + gfx::BufferUsage usages[] = {gfx::BufferUsage::GPU_READ, + gfx::BufferUsage::SCANOUT, + gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE, + gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE, + gfx::BufferUsage::SCANOUT_CPU_READ_WRITE, + gfx::BufferUsage::SCANOUT_VDA_WRITE, + gfx::BufferUsage::GPU_READ_CPU_READ_WRITE}; for (auto usage : usages) { if (!TestFixture::gpu_memory_buffer_support()->IsConfigurationSupported( TypeParam::kBufferType, format, usage))
diff --git a/gpu/ipc/common/gpu_memory_buffer_support.cc b/gpu/ipc/common/gpu_memory_buffer_support.cc index 9627879..fdd622e 100644 --- a/gpu/ipc/common/gpu_memory_buffer_support.cc +++ b/gpu/ipc/common/gpu_memory_buffer_support.cc
@@ -74,7 +74,6 @@ case gfx::BufferUsage::SCANOUT: case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE: case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: - case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: return format == gfx::BufferFormat::BGRA_8888 || format == gfx::BufferFormat::RGBA_8888 || format == gfx::BufferFormat::BGRX_8888 || @@ -102,7 +101,6 @@ format == gfx::BufferFormat::BGR_565; case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE: case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: - case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: case gfx::BufferUsage::SCANOUT_VDA_WRITE: case gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE: case gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE: @@ -123,7 +121,6 @@ format == gfx::BufferFormat::RGBX_8888; case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE: case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: - case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: case gfx::BufferUsage::SCANOUT_VDA_WRITE: case gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE: case gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE:
diff --git a/gpu/ipc/host/gpu_memory_buffer_support.cc b/gpu/ipc/host/gpu_memory_buffer_support.cc index d5891be..2218578 100644 --- a/gpu/ipc/host/gpu_memory_buffer_support.cc +++ b/gpu/ipc/host/gpu_memory_buffer_support.cc
@@ -51,8 +51,7 @@ gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE, gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE, gfx::BufferUsage::SCANOUT_CPU_READ_WRITE, - gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, - gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT}; + gfx::BufferUsage::GPU_READ_CPU_READ_WRITE}; for (auto format : kNativeFormats) { for (auto usage : kNativeUsages) { if (support->IsNativeGpuMemoryBufferConfigurationSupported(format,
diff --git a/gpu/ipc/service/gpu_memory_buffer_factory_test_template.h b/gpu/ipc/service/gpu_memory_buffer_factory_test_template.h index b9e8aa4..4df68b47 100644 --- a/gpu/ipc/service/gpu_memory_buffer_factory_test_template.h +++ b/gpu/ipc/service/gpu_memory_buffer_factory_test_template.h
@@ -51,15 +51,13 @@ GpuMemoryBufferSupport support; for (auto format : gfx::GetBufferFormatsForTesting()) { - gfx::BufferUsage usages[] = { - gfx::BufferUsage::GPU_READ, - gfx::BufferUsage::SCANOUT, - gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE, - gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE, - gfx::BufferUsage::SCANOUT_CPU_READ_WRITE, - gfx::BufferUsage::SCANOUT_VDA_WRITE, - gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, - gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT}; + gfx::BufferUsage usages[] = {gfx::BufferUsage::GPU_READ, + gfx::BufferUsage::SCANOUT, + gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE, + gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE, + gfx::BufferUsage::SCANOUT_CPU_READ_WRITE, + gfx::BufferUsage::SCANOUT_VDA_WRITE, + gfx::BufferUsage::GPU_READ_CPU_READ_WRITE}; for (auto usage : usages) { if (!support.IsNativeGpuMemoryBufferConfigurationSupported(format, usage)) continue;
diff --git a/headless/lib/browser/headless_content_browser_client.cc b/headless/lib/browser/headless_content_browser_client.cc index 92da092c..406bb8f 100644 --- a/headless/lib/browser/headless_content_browser_client.cc +++ b/headless/lib/browser/headless_content_browser_client.cc
@@ -166,7 +166,7 @@ #endif } -content::QuotaPermissionContext* +scoped_refptr<content::QuotaPermissionContext> HeadlessContentBrowserClient::CreateQuotaPermissionContext() { return new HeadlessQuotaPermissionContext(); }
diff --git a/headless/lib/browser/headless_content_browser_client.h b/headless/lib/browser/headless_content_browser_client.h index 8e4e1f70..f463d0ab 100644 --- a/headless/lib/browser/headless_content_browser_client.h +++ b/headless/lib/browser/headless_content_browser_client.h
@@ -27,7 +27,8 @@ base::Optional<service_manager::Manifest> GetServiceManifestOverlay( base::StringPiece name) override; void RegisterOutOfProcessServices(OutOfProcessServiceMap* services) override; - content::QuotaPermissionContext* CreateQuotaPermissionContext() override; + scoped_refptr<content::QuotaPermissionContext> CreateQuotaPermissionContext() + override; void GetQuotaSettings( content::BrowserContext* context, content::StoragePartition* partition,
diff --git a/ios/chrome/app/application_delegate/BUILD.gn b/ios/chrome/app/application_delegate/BUILD.gn index 4c100d53..e99d1fb7 100644 --- a/ios/chrome/app/application_delegate/BUILD.gn +++ b/ios/chrome/app/application_delegate/BUILD.gn
@@ -58,6 +58,7 @@ "//ios/chrome/browser/ui/safe_mode", "//ios/chrome/browser/ui/settings", "//ios/chrome/browser/ui/settings:settings_root", + "//ios/chrome/browser/url_loading", "//ios/chrome/browser/web:tab_id_tab_helper", "//ios/chrome/browser/web_state_list", "//ios/chrome/browser/web_state_list:test_support", @@ -133,6 +134,7 @@ "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/main", "//ios/chrome/browser/ui/safe_mode", + "//ios/chrome/browser/url_loading", "//ios/chrome/browser/web:tab_id_tab_helper", "//ios/chrome/browser/web_state_list", "//ios/chrome/common/app_group:main_app", @@ -169,6 +171,7 @@ "//ios/chrome/app:app_internal", "//ios/chrome/app:mode", "//ios/chrome/browser", + "//ios/chrome/browser/url_loading", "//net", "//ui/base", "//url",
diff --git a/ios/chrome/app/application_delegate/metrics_mediator.mm b/ios/chrome/app/application_delegate/metrics_mediator.mm index 898d528c..1f62fad 100644 --- a/ios/chrome/app/application_delegate/metrics_mediator.mm +++ b/ios/chrome/app/application_delegate/metrics_mediator.mm
@@ -265,6 +265,7 @@ } - (void)setBreakpadEnabled:(BOOL)enabled withUploading:(BOOL)allowUploading { + breakpad_helper::SetUserEnabledUploading(enabled); if (enabled) { breakpad_helper::SetEnabled(true);
diff --git a/ios/chrome/app/application_delegate/mock_tab_opener.h b/ios/chrome/app/application_delegate/mock_tab_opener.h index 0d6c15bd..fe7bc7b1 100644 --- a/ios/chrome/app/application_delegate/mock_tab_opener.h +++ b/ios/chrome/app/application_delegate/mock_tab_opener.h
@@ -9,15 +9,16 @@ #import "ios/chrome/app/application_delegate/tab_opening.h" -class GURL; +struct UrlLoadParams; -// Mocks a class adopting the TabOpening protocol. It save the arguments of -// -dismissModalsAndOpenSelectedTabInMode:withURL:transition:completion:. +// Mocks a class adopting the TabOpening protocol. It saves the arguments of +// -dismissModalsAndOpenSelectedTabInMode:withUrlLoadParams:dismissOmnibox: +// completion:. @interface MockTabOpener : NSObject<TabOpening> // Arguments for -// -dismissModalsAndOpenSelectedTabInMode:withURL:virtualURL:transition:completion:. -@property(nonatomic, readonly) GURL url; -@property(nonatomic, readonly) GURL virtualURL; +// -dismissModalsAndOpenSelectedTabInMode:withUrlLoadParams:dismissOmnibox: +// completion:. +@property(nonatomic, readonly) UrlLoadParams urlLoadParams; @property(nonatomic, readonly) ApplicationMode applicationMode; @property(nonatomic, strong, readonly) void (^completionBlock)(void);
diff --git a/ios/chrome/app/application_delegate/mock_tab_opener.mm b/ios/chrome/app/application_delegate/mock_tab_opener.mm index 2745500..d8697b5 100644 --- a/ios/chrome/app/application_delegate/mock_tab_opener.mm +++ b/ios/chrome/app/application_delegate/mock_tab_opener.mm
@@ -7,6 +7,7 @@ #include "base/ios/block_types.h" #include "base/mac/scoped_block.h" #include "ios/chrome/app/application_mode.h" +#import "ios/chrome/browser/url_loading/url_loading_params.h" #include "ui/base/page_transition_types.h" #include "url/gurl.h" @@ -16,25 +17,18 @@ @implementation MockTabOpener -@synthesize url = _url; -@synthesize virtualURL = _virtualURL; -@synthesize applicationMode = _applicationMode; -@synthesize completionBlock = _completionBlock; - - (void)dismissModalsAndOpenSelectedTabInMode:(ApplicationMode)targetMode - withURL:(const GURL&)url - virtualURL:(const GURL&)virtualURL + withUrlLoadParams: + (const UrlLoadParams&)urlLoadParams dismissOmnibox:(BOOL)dismissOmnibox - transition:(ui::PageTransition)transition completion:(ProceduralBlock)completion { - _url = url; - _virtualURL = virtualURL; + _urlLoadParams = urlLoadParams; _applicationMode = targetMode; _completionBlock = [completion copy]; } - (void)resetURL { - _url = _url.EmptyGURL(); + _urlLoadParams.web_params.url = _urlLoadParams.web_params.url.EmptyGURL(); } - (void)openTabFromLaunchOptions:(NSDictionary*)launchOptions
diff --git a/ios/chrome/app/application_delegate/tab_opening.h b/ios/chrome/app/application_delegate/tab_opening.h index 18c621b8..202dd57 100644 --- a/ios/chrome/app/application_delegate/tab_opening.h +++ b/ios/chrome/app/application_delegate/tab_opening.h
@@ -13,7 +13,7 @@ @class AppState; @class TabModel; @protocol StartupInformation; -class GURL; +struct UrlLoadParams; // Protocol for object that can open new tabs during application launch. @protocol TabOpening<NSObject> @@ -23,10 +23,9 @@ // run completion |handler| if it is not nil. After Tab is opened the virtual // URL is set to the pending navigation item. - (void)dismissModalsAndOpenSelectedTabInMode:(ApplicationMode)targetMode - withURL:(const GURL&)url - virtualURL:(const GURL&)virtualURL + withUrlLoadParams: + (const UrlLoadParams&)urlLoadParams dismissOmnibox:(BOOL)dismissOmnibox - transition:(ui::PageTransition)transition completion:(ProceduralBlock)completion; // Creates a new tab if the launch options are not null.
diff --git a/ios/chrome/app/application_delegate/url_opener.mm b/ios/chrome/app/application_delegate/url_opener.mm index 02156ee9..6209b46 100644 --- a/ios/chrome/app/application_delegate/url_opener.mm +++ b/ios/chrome/app/application_delegate/url_opener.mm
@@ -12,6 +12,7 @@ #import "ios/chrome/app/application_delegate/tab_opening.h" #include "ios/chrome/app/startup/chrome_app_startup_parameters.h" #import "ios/chrome/browser/chrome_url_util.h" +#import "ios/chrome/browser/url_loading/url_loading_params.h" #include "url/gurl.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -78,15 +79,14 @@ } else { URL = [params externalURL]; } + UrlLoadParams urlLoadParams = UrlLoadParams::InNewTab(URL, virtualURL); [tabOpener dismissModalsAndOpenSelectedTabInMode:[params launchInIncognito] ? ApplicationMode::INCOGNITO : ApplicationMode::NORMAL - withURL:URL - virtualURL:virtualURL + withUrlLoadParams:urlLoadParams dismissOmnibox:[params postOpeningAction] != FOCUS_OMNIBOX - transition:ui::PAGE_TRANSITION_LINK completion:tabOpenedCompletion]; return YES; }
diff --git a/ios/chrome/app/application_delegate/url_opener_unittest.mm b/ios/chrome/app/application_delegate/url_opener_unittest.mm index 37d1491..03ebae78 100644 --- a/ios/chrome/app/application_delegate/url_opener_unittest.mm +++ b/ios/chrome/app/application_delegate/url_opener_unittest.mm
@@ -14,6 +14,7 @@ #import "ios/chrome/browser/tabs/tab_model.h" #import "ios/chrome/browser/ui/main/test/stub_browser_interface.h" #import "ios/chrome/browser/ui/main/test/stub_browser_interface_provider.h" +#import "ios/chrome/browser/url_loading/url_loading_params.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/test/base/scoped_block_swizzler.h" #include "ios/web/public/test/test_web_thread_bundle.h" @@ -174,12 +175,15 @@ // External file:// URL will be loaded by WebState, which expects // complete // file:// URL. chrome:// URL is expected to be // displayed in the omnibox, and omnibox shows virtual URL. - EXPECT_EQ([params completeURL], [tabOpener url]); - EXPECT_EQ([params externalURL], [tabOpener virtualURL]); + EXPECT_EQ([params completeURL], + tabOpener.urlLoadParams.web_params.url); + EXPECT_EQ([params externalURL], + tabOpener.urlLoadParams.web_params.virtual_url); } else { // External chromium-x-callback:// URL will be loaded by // WebState, which expects externalURL URL. - EXPECT_EQ([params externalURL], [tabOpener url]); + EXPECT_EQ([params externalURL], + tabOpener.urlLoadParams.web_params.url); } tabOpener.completionBlock(); EXPECT_EQ(nil, startupInformation.startupParameters);
diff --git a/ios/chrome/app/application_delegate/user_activity_handler.mm b/ios/chrome/app/application_delegate/user_activity_handler.mm index b6cad08..32112d4 100644 --- a/ios/chrome/app/application_delegate/user_activity_handler.mm +++ b/ios/chrome/app/application_delegate/user_activity_handler.mm
@@ -25,6 +25,7 @@ #import "ios/chrome/browser/tabs/tab_model.h" #import "ios/chrome/browser/u2f/u2f_tab_helper.h" #import "ios/chrome/browser/ui/main/browser_interface_provider.h" +#import "ios/chrome/browser/url_loading/url_loading_params.h" #import "ios/chrome/browser/web/tab_id_tab_helper.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" #import "net/base/mac/url_conversions.h" @@ -172,11 +173,10 @@ [[startupInformation startupParameters] launchInIncognito] ? ApplicationMode::INCOGNITO : ApplicationMode::NORMAL; + UrlLoadParams params = UrlLoadParams::InNewTab(webpageGURL); [tabOpener dismissModalsAndOpenSelectedTabInMode:targetMode - withURL:webpageGURL - virtualURL:GURL::EmptyGURL() + withUrlLoadParams:params dismissOmnibox:YES - transition:ui::PAGE_TRANSITION_LINK completion:^{ [startupInformation setStartupParameters:nil]; @@ -275,14 +275,14 @@ } else { URL = externalURL; } + UrlLoadParams params = UrlLoadParams::InNewTab(URL, virtualURL); + [tabOpener dismissModalsAndOpenSelectedTabInMode:targetMode - withURL:URL - virtualURL:virtualURL + withUrlLoadParams:params dismissOmnibox:[[startupInformation startupParameters] postOpeningAction] != FOCUS_OMNIBOX - transition:ui::PAGE_TRANSITION_LINK completion:^{ [startupInformation setStartupParameters:nil];
diff --git a/ios/chrome/app/application_delegate/user_activity_handler_unittest.mm b/ios/chrome/app/application_delegate/user_activity_handler_unittest.mm index 9d56644..d91cbe2 100644 --- a/ios/chrome/app/application_delegate/user_activity_handler_unittest.mm +++ b/ios/chrome/app/application_delegate/user_activity_handler_unittest.mm
@@ -30,6 +30,7 @@ #import "ios/chrome/browser/tabs/tab_model_observer.h" #import "ios/chrome/browser/u2f/u2f_tab_helper.h" #import "ios/chrome/browser/ui/main/test/stub_browser_interface_provider.h" +#import "ios/chrome/browser/url_loading/url_loading_params.h" #import "ios/chrome/browser/web/tab_id_tab_helper.h" #import "ios/chrome/browser/web_state_list/fake_web_state_list_delegate.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" @@ -384,8 +385,8 @@ startupInformation:startupInformationMock]; // Test. - EXPECT_EQ(gurl, tabOpener.url); - EXPECT_TRUE(tabOpener.virtualURL.is_empty()); + EXPECT_EQ(gurl, tabOpener.urlLoadParams.web_params.url); + EXPECT_TRUE(tabOpener.urlLoadParams.web_params.virtual_url.is_empty()); EXPECT_TRUE(result); } @@ -413,7 +414,7 @@ startupInformation:fakeStartupInformation]; GURL newTabURL(kChromeUINewTabURL); - EXPECT_EQ(newTabURL, [tabOpener url]); + EXPECT_EQ(newTabURL, tabOpener.urlLoadParams.web_params.url); // AppStartupParameters default to opening pages in non-Incognito mode. EXPECT_EQ(ApplicationMode::NORMAL, [tabOpener applicationMode]); EXPECT_TRUE(result); @@ -521,8 +522,8 @@ // External file:// URL will be loaded by WebState, which expects complete // file:// URL. chrome:// URL is expected to be displayed in the omnibox, // and omnibox shows virtual URL. - EXPECT_EQ(completeURL, tabOpener.url); - EXPECT_EQ(externalURL, tabOpener.virtualURL); + EXPECT_EQ(completeURL, tabOpener.urlLoadParams.web_params.url); + EXPECT_EQ(externalURL, tabOpener.urlLoadParams.web_params.virtual_url); EXPECT_EQ(ApplicationMode::INCOGNITO, [tabOpener applicationMode]); } @@ -556,8 +557,8 @@ // Tests. EXPECT_OCMOCK_VERIFY(startupInformationMock); - EXPECT_EQ(gurl, tabOpener.url); - EXPECT_TRUE(tabOpener.virtualURL.is_empty()); + EXPECT_EQ(gurl, tabOpener.urlLoadParams.web_params.url); + EXPECT_TRUE(tabOpener.urlLoadParams.web_params.virtual_url.is_empty()); EXPECT_EQ(ApplicationMode::INCOGNITO, [tabOpener applicationMode]); } @@ -600,8 +601,8 @@ // Tests. EXPECT_OCMOCK_VERIFY(startupInformationMock); EXPECT_EQ(gurl, [tabMock U2FTabHelper] -> url()); - EXPECT_TRUE(tabOpener.url.is_empty()); - EXPECT_TRUE(tabOpener.virtualURL.is_empty()); + EXPECT_TRUE(tabOpener.urlLoadParams.web_params.url.is_empty()); + EXPECT_TRUE(tabOpener.urlLoadParams.web_params.virtual_url.is_empty()); } // Tests that performActionForShortcutItem set startupParameters accordingly to
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index 3c6bf3c2..39ccf6dd 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -467,18 +467,14 @@ // |completion| is executed after the tab is opened. After Tab is open the // virtual URL is set to the pending navigation item. - (void)openSelectedTabInMode:(ApplicationMode)targetMode - withURL:(const GURL&)url - virtualURL:(const GURL&)virtualURL - transition:(ui::PageTransition)transition + withUrlLoadParams:(const UrlLoadParams&)urlLoadParams completion:(ProceduralBlock)completion; // Checks the target BVC's current tab's URL. If this URL is chrome://newtab, -// loads |url| in this tab. Otherwise, open |url| in a new tab in the target -// BVC. -// |tabDisplayedCompletion| will be called on the new tab (if not nil). +// loads |urlLoadParams| in this tab. Otherwise, open |urlLoadParams| in a new +// tab in the target BVC. |tabDisplayedCompletion| will be called on the new tab +// (if not nil). - (void)openOrReuseTabInMode:(ApplicationMode)targetMode - withURL:(const GURL&)url - virtualURL:(const GURL&)virtualURL - transition:(ui::PageTransition)transition + withUrlLoadParams:(const UrlLoadParams&)urlLoadParams tabOpenedCompletion:(ProceduralBlock)tabOpenedCompletion; // Returns whether the restore infobar should be displayed. - (bool)mustShowRestoreInfobar; @@ -845,11 +841,11 @@ [self markEulaAsAccepted]; if (_startupParameters) { + UrlLoadParams params = + UrlLoadParams::InNewTab(_startupParameters.externalURL); [self dismissModalsAndOpenSelectedTabInMode:ApplicationMode::NORMAL - withURL:_startupParameters.externalURL - virtualURL:GURL::EmptyGURL() + withUrlLoadParams:params dismissOmnibox:YES - transition:ui::PAGE_TRANSITION_LINK completion:^{ [self setStartupParameters:nil]; }]; @@ -1799,12 +1795,12 @@ - (void)openUrlFromSettings:(OpenNewTabCommand*)command { DCHECK([command fromChrome]); + UrlLoadParams params = UrlLoadParams::InNewTab([command URL]); + params.web_params.transition_type = ui::PAGE_TRANSITION_TYPED; ProceduralBlock completion = ^{ [self dismissModalsAndOpenSelectedTabInMode:ApplicationMode::NORMAL - withURL:[command URL] - virtualURL:GURL::EmptyGURL() + withUrlLoadParams:params dismissOmnibox:YES - transition:ui::PAGE_TRANSITION_TYPED completion:nil]; }; [self closeSettingsAnimated:YES completion:completion]; @@ -2062,11 +2058,13 @@ if (!_tabSwitcher) return NO; + UrlLoadParams urlLoadParams = + UrlLoadParams::InNewTab(GURL(kChromeUINewTabURL)); + urlLoadParams.web_params.transition_type = ui::PAGE_TRANSITION_TYPED; + [_tabSwitcher dismissWithNewTabAnimationToModel:self.mainTabModel - withURL:GURL(kChromeUINewTabURL) - virtualURL:GURL::EmptyGURL() - atIndex:self.mainTabModel.count - transition:ui::PAGE_TRANSITION_TYPED]; + withUrlLoadParams:urlLoadParams + atIndex:self.mainTabModel.count]; return YES; } @@ -2256,9 +2254,7 @@ #pragma mark - Tab opening utility methods. - (void)openOrReuseTabInMode:(ApplicationMode)targetMode - withURL:(const GURL&)URL - virtualURL:(const GURL&)virtualURL - transition:(ui::PageTransition)transition + withUrlLoadParams:(const UrlLoadParams&)urlLoadParams tabOpenedCompletion:(ProceduralBlock)tabOpenedCompletion { BrowserViewController* targetBVC = targetMode == ApplicationMode::NORMAL ? self.mainBVC : self.otrBVC; @@ -2271,7 +2267,7 @@ // NTP hasn't finished loading. if (currentTabInTargetBVC.webState && IsURLNtp(currentTabInTargetBVC.webState->GetVisibleURL()) && - IsURLNtp(URL)) { + IsURLNtp(urlLoadParams.web_params.url)) { if (tabOpenedCompletion) { tabOpenedCompletion(); } @@ -2290,17 +2286,19 @@ !(currentTabInTargetBVC.webState && IsURLNtp(currentTabInTargetBVC.webState->GetVisibleURL()))) { [targetBVC appendTabAddedCompletion:tabOpenedCompletion]; - UrlLoadParams params = UrlLoadParams::InNewTab(URL, virtualURL); - params.web_params.transition_type = transition; - params.in_incognito = targetMode == ApplicationMode::INCOGNITO; + UrlLoadParams newTabParams = urlLoadParams; + newTabParams.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; + newTabParams.in_incognito = targetMode == ApplicationMode::INCOGNITO; UrlLoadingServiceFactory::GetForBrowserState([targetBVC browserState]) - ->Load(params); + ->Load(newTabParams); return; } - // Otherwise, load |url| in the current tab. + // Otherwise, load |urlLoadParams| in the current tab. + UrlLoadParams sameTabParams = urlLoadParams; + sameTabParams.disposition = WindowOpenDisposition::CURRENT_TAB; UrlLoadingServiceFactory::GetForBrowserState([targetBVC browserState]) - ->Load(UrlLoadParams::InCurrentTab(URL, virtualURL)); + ->Load(sameTabParams); if (tabOpenedCompletion) { tabOpenedCompletion(); } @@ -2335,9 +2333,7 @@ } - (void)openSelectedTabInMode:(ApplicationMode)targetMode - withURL:(const GURL&)url - virtualURL:(const GURL&)virtualURL - transition:(ui::PageTransition)transition + withUrlLoadParams:(const UrlLoadParams&)urlLoadParams completion:(ProceduralBlock)completion { id<BrowserInterface> targetInterface = targetMode == ApplicationMode::NORMAL @@ -2349,7 +2345,7 @@ postOpeningAction]]; // Commands are only allowed on NTP. - DCHECK(IsURLNtp(url) || !startupCompletion); + DCHECK(IsURLNtp(urlLoadParams.web_params.url) || !startupCompletion); ProceduralBlock tabOpenedCompletion = nil; if (startupCompletion && completion) { @@ -2375,12 +2371,11 @@ ? TabSwitcherDismissalMode::NORMAL : TabSwitcherDismissalMode::INCOGNITO; [targetInterface.bvc appendTabAddedCompletion:tabOpenedCompletion]; - UrlLoadParams params = UrlLoadParams::InNewTab(url, virtualURL); - params.web_params.transition_type = transition; - params.in_incognito = targetMode == ApplicationMode::INCOGNITO; + UrlLoadParams savedParams = urlLoadParams; + savedParams.in_incognito = targetMode == ApplicationMode::INCOGNITO; UrlLoadingServiceFactory::GetForBrowserState( [targetInterface.bvc browserState]) - ->Load(params); + ->Load(savedParams); } else { // Voice search, QRScanner and the omnibox are presented by the BVC. // They must be started after the BVC view is added in the hierarchy. @@ -2388,10 +2383,8 @@ [_startupParameters postOpeningAction]; [self setStartupParameters:nil]; [_tabSwitcher dismissWithNewTabAnimationToModel:targetInterface.tabModel - withURL:url - virtualURL:virtualURL - atIndex:tabIndex - transition:transition]; + withUrlLoadParams:urlLoadParams + atIndex:tabIndex]; } } else { if (!self.currentBVC.presentedViewController) { @@ -2399,9 +2392,7 @@ } [self setCurrentInterfaceForMode:targetMode]; [self openOrReuseTabInMode:targetMode - withURL:url - virtualURL:virtualURL - transition:transition + withUrlLoadParams:urlLoadParams tabOpenedCompletion:tabOpenedCompletion]; } @@ -2544,19 +2535,15 @@ #pragma mark - TabOpening implementation. - (void)dismissModalsAndOpenSelectedTabInMode:(ApplicationMode)targetMode - withURL:(const GURL&)url - virtualURL:(const GURL&)virtualURL + withUrlLoadParams: + (const UrlLoadParams&)urlLoadParams dismissOmnibox:(BOOL)dismissOmnibox - transition:(ui::PageTransition)transition completion:(ProceduralBlock)completion { - GURL copyOfURL = url; - GURL copyOfVirtualURL = virtualURL; + UrlLoadParams copyOfUrlLoadParams = urlLoadParams; [self dismissModalDialogsWithCompletion:^{ [self openSelectedTabInMode:targetMode - withURL:copyOfURL - virtualURL:copyOfVirtualURL - transition:transition + withUrlLoadParams:copyOfUrlLoadParams completion:completion]; } dismissOmnibox:dismissOmnibox];
diff --git a/ios/chrome/app/theme/default_100_percent/infobar_send_tab_to_self.png b/ios/chrome/app/theme/default_100_percent/infobar_send_tab_to_self.png new file mode 100644 index 0000000..ad9b780 --- /dev/null +++ b/ios/chrome/app/theme/default_100_percent/infobar_send_tab_to_self.png Binary files differ
diff --git a/ios/chrome/app/theme/default_200_percent/infobar_send_tab_to_self.png b/ios/chrome/app/theme/default_200_percent/infobar_send_tab_to_self.png new file mode 100644 index 0000000..cfc109d --- /dev/null +++ b/ios/chrome/app/theme/default_200_percent/infobar_send_tab_to_self.png Binary files differ
diff --git a/ios/chrome/app/theme/default_300_percent/infobar_send_tab_to_self.png b/ios/chrome/app/theme/default_300_percent/infobar_send_tab_to_self.png new file mode 100644 index 0000000..37c150e7 --- /dev/null +++ b/ios/chrome/app/theme/default_300_percent/infobar_send_tab_to_self.png Binary files differ
diff --git a/ios/chrome/app/theme/ios_theme_resources.grd b/ios/chrome/app/theme/ios_theme_resources.grd index 08e3bae..28dd7cb 100644 --- a/ios/chrome/app/theme/ios_theme_resources.grd +++ b/ios/chrome/app/theme/ios_theme_resources.grd
@@ -32,6 +32,7 @@ <structure type="chrome_scaled_image" name="IDR_IOS_INFOBAR_CLOSE" file="infobar_close.png" /> <structure type="chrome_scaled_image" name="IDR_IOS_INFOBAR_RESTORE_SESSION" file="infobar_restore_session.png" /> <structure type="chrome_scaled_image" name="IDR_IOS_INFOBAR_SAVE_PASSWORD" file="infobar_save_password.png" /> + <structure type="chrome_scaled_image" name="IDR_IOS_INFOBAR_SEND_TAB_TO_SELF" file="infobar_send_tab_to_self.png" /> <structure type="chrome_scaled_image" name="IDR_IOS_INFOBAR_TRANSLATE" file="infobar_translate.png" /> <structure type="chrome_scaled_image" name="IDR_IOS_LOCATION_BAR_HTTP" file="omnibox_http.png" /> <structure type="chrome_scaled_image" name="IDR_IOS_OMNIBOX_CALCULATOR" file="omnibox_calculator.png" />
diff --git a/ios/chrome/browser/BUILD.gn b/ios/chrome/browser/BUILD.gn index c4b89bf..ae885c6 100644 --- a/ios/chrome/browser/BUILD.gn +++ b/ios/chrome/browser/BUILD.gn
@@ -213,6 +213,7 @@ "//ios/chrome/browser/open_from_clipboard", "//ios/chrome/browser/prefs", "//ios/chrome/browser/prefs:browser_prefs", + "//ios/chrome/browser/send_tab_to_self", "//ios/chrome/browser/translate", "//ios/chrome/browser/ui:feature_flags", "//ios/chrome/browser/update_client",
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state_impl.cc b/ios/chrome/browser/browser_state/chrome_browser_state_impl.cc index 76d6df45..055daa4 100644 --- a/ios/chrome/browser/browser_state/chrome_browser_state_impl.cc +++ b/ios/chrome/browser/browser_state/chrome_browser_state_impl.cc
@@ -31,6 +31,7 @@ #include "ios/chrome/browser/pref_names.h" #include "ios/chrome/browser/prefs/browser_prefs.h" #include "ios/chrome/browser/prefs/ios_chrome_pref_service_factory.h" +#include "ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_factory.h" #include "ios/chrome/browser/signin/identity_service_creator.h" #include "ios/web/public/web_thread.h" #include "services/identity/public/mojom/constants.mojom.h" @@ -131,6 +132,8 @@ bookmarks::BookmarkModel* model = ios::BookmarkModelFactory::GetForBrowserState(this); model->AddObserver(new BookmarkModelLoadedObserver(this)); + + send_tab_to_self::SendTabToSelfClientServiceFactory::GetForBrowserState(this); } ChromeBrowserStateImpl::~ChromeBrowserStateImpl() {
diff --git a/ios/chrome/browser/crash_report/breakpad_helper.h b/ios/chrome/browser/crash_report/breakpad_helper.h index 609c07d..ce37e434 100644 --- a/ios/chrome/browser/crash_report/breakpad_helper.h +++ b/ios/chrome/browser/crash_report/breakpad_helper.h
@@ -21,8 +21,12 @@ // Enable/Disable uploading crash reports. void SetUploadingEnabled(bool enabled); -// Returns true if uploading crash reports is enabled. -bool IsUploadingEnabled(); +// Sets the user preferences related to Breakpad and cache them to be used on +// next startup to check if safe mode must be started. +void SetUserEnabledUploading(bool enabled); + +// Returns true if uploading crash reports is enabled in the settings. +bool UserEnabledUploading(); // Cleans up all stored crash reports. void CleanupCrashReports();
diff --git a/ios/chrome/browser/crash_report/breakpad_helper.mm b/ios/chrome/browser/crash_report/breakpad_helper.mm index acf4512..2ecb37d4 100644 --- a/ios/chrome/browser/crash_report/breakpad_helper.mm +++ b/ios/chrome/browser/crash_report/breakpad_helper.mm
@@ -112,14 +112,6 @@ return false; } -// Caches the uploading flag in NSUserDefaults, so that we can access the value -// in safe mode. -void CacheUploadingEnabled(bool uploading_enabled) { - NSUserDefaults* user_defaults = [NSUserDefaults standardUserDefaults]; - [user_defaults setBool:uploading_enabled ? YES : NO - forKey:kCrashReportsUploadingEnabledKey]; -} - } // namespace void Start(const std::string& channel_name) { @@ -155,18 +147,23 @@ [[BreakpadController sharedInstance] start:NO]; } else { [[BreakpadController sharedInstance] stop]; - CacheUploadingEnabled(false); } } void SetBreakpadUploadingEnabled(bool enabled) { - CacheUploadingEnabled(g_crash_reporter_enabled && enabled); - if (!g_crash_reporter_enabled) return; [[BreakpadController sharedInstance] setUploadingEnabled:enabled]; } +// Caches the uploading flag in NSUserDefaults, so that we can access the value +// in safe mode. +void SetUserEnabledUploading(bool uploading_enabled) { + [[NSUserDefaults standardUserDefaults] + setBool:uploading_enabled ? YES : NO + forKey:kCrashReportsUploadingEnabledKey]; +} + void SetUploadingEnabled(bool enabled) { if (enabled && [UIApplication sharedApplication].applicationState == @@ -185,8 +182,7 @@ } } -bool IsUploadingEnabled() { - // Return the value cached by CacheUploadingEnabled(). +bool UserEnabledUploading() { return [[NSUserDefaults standardUserDefaults] boolForKey:kCrashReportsUploadingEnabledKey]; }
diff --git a/ios/chrome/browser/crash_report/breakpad_helper_unittest.mm b/ios/chrome/browser/crash_report/breakpad_helper_unittest.mm index a4e9ecf..8cd8b0b 100644 --- a/ios/chrome/browser/crash_report/breakpad_helper_unittest.mm +++ b/ios/chrome/browser/crash_report/breakpad_helper_unittest.mm
@@ -19,19 +19,6 @@ namespace { -// Wait for the UTE crash processing. This is needed the first time -// |breakpad_helper::SetUploadingEnabled| is called. -void WaitMainThreadFreezeCrashProcessingIfNeeded() { - if (! - [MainThreadFreezeDetector sharedInstance].canUploadBreakpadCrashReports) { - EXPECT_TRUE(base::test::ios::WaitUntilConditionOrTimeout( - base::test::ios::kWaitForActionTimeout, ^bool { - return [MainThreadFreezeDetector sharedInstance] - .canUploadBreakpadCrashReports; - })); - } -} - const int kCrashReportCount = 3; NSString* const kUploadedInRecoveryMode = @"uploaded_in_recovery_mode"; @@ -102,33 +89,22 @@ } TEST_F(BreakpadHelperTest, IsUploadingEnabled) { - // Test when crash reporter is disabled. + breakpad_helper::SetUserEnabledUploading(true); + EXPECT_TRUE(breakpad_helper::UserEnabledUploading()); breakpad_helper::SetEnabled(false); - - EXPECT_FALSE(breakpad_helper::IsUploadingEnabled()); - - breakpad_helper::SetUploadingEnabled(false); - WaitMainThreadFreezeCrashProcessingIfNeeded(); - EXPECT_FALSE(breakpad_helper::IsUploadingEnabled()); - - breakpad_helper::SetUploadingEnabled(true); - EXPECT_FALSE(breakpad_helper::IsUploadingEnabled()); - - // Test when crash reporter is enabled. + EXPECT_TRUE(breakpad_helper::UserEnabledUploading()); [[mock_breakpad_controller_ expect] start:NO]; breakpad_helper::SetEnabled(true); - EXPECT_FALSE(breakpad_helper::IsUploadingEnabled()); - EXPECT_OCMOCK_VERIFY(mock_breakpad_controller_); + EXPECT_TRUE(breakpad_helper::UserEnabledUploading()); - [[mock_breakpad_controller_ expect] setUploadingEnabled:NO]; - breakpad_helper::SetUploadingEnabled(false); - EXPECT_FALSE(breakpad_helper::IsUploadingEnabled()); - EXPECT_OCMOCK_VERIFY(mock_breakpad_controller_); - - [[mock_breakpad_controller_ expect] setUploadingEnabled:YES]; - breakpad_helper::SetUploadingEnabled(true); - EXPECT_TRUE(breakpad_helper::IsUploadingEnabled()); - EXPECT_OCMOCK_VERIFY(mock_breakpad_controller_); + breakpad_helper::SetUserEnabledUploading(false); + EXPECT_FALSE(breakpad_helper::UserEnabledUploading()); + [[mock_breakpad_controller_ expect] stop]; + breakpad_helper::SetEnabled(false); + EXPECT_FALSE(breakpad_helper::UserEnabledUploading()); + [[mock_breakpad_controller_ expect] start:NO]; + breakpad_helper::SetEnabled(true); + EXPECT_FALSE(breakpad_helper::UserEnabledUploading()); } TEST_F(BreakpadHelperTest, StartUploadingReportsInRecoveryMode) {
diff --git a/ios/chrome/browser/feature_engagement/BUILD.gn b/ios/chrome/browser/feature_engagement/BUILD.gn index e2719988..ce01551 100644 --- a/ios/chrome/browser/feature_engagement/BUILD.gn +++ b/ios/chrome/browser/feature_engagement/BUILD.gn
@@ -40,6 +40,7 @@ "//base/test:test_support", "//components/feature_engagement/public", "//components/feature_engagement/test:test_support", + "//components/translate/core/browser", "//ios/chrome/app/strings", "//ios/chrome/browser", "//ios/chrome/browser/browser_state",
diff --git a/ios/chrome/browser/feature_engagement/feature_engagement_egtest.mm b/ios/chrome/browser/feature_engagement/feature_engagement_egtest.mm index d6f6be8..7088e97 100644 --- a/ios/chrome/browser/feature_engagement/feature_engagement_egtest.mm +++ b/ios/chrome/browser/feature_engagement/feature_engagement_egtest.mm
@@ -13,6 +13,7 @@ #include "components/feature_engagement/public/feature_constants.h" #include "components/feature_engagement/public/tracker.h" #include "components/feature_engagement/test/test_tracker.h" +#include "components/translate/core/browser/translate_prefs.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/feature_engagement/tracker_factory.h" #include "ios/chrome/browser/system_flags.h" @@ -26,6 +27,9 @@ #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" #import "ios/chrome/test/earl_grey/chrome_matchers.h" #import "ios/chrome/test/earl_grey/chrome_test_case.h" +#include "net/test/embedded_test_server/embedded_test_server.h" +#include "net/test/embedded_test_server/http_response.h" +#include "net/test/embedded_test_server/request_handler_util.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util_mac.h" #include "url/gurl.h" @@ -47,6 +51,9 @@ // Tip to be shown. const int kMinChromeOpensRequiredForNewTabTip = 3; +// URL path for a page with text in French. +const char kFrenchPageURLPath[] = "/french"; + // Matcher for the Reading List Text Badge. id<GREYMatcher> ReadingListTextBadge() { return grey_allOf( @@ -56,6 +63,19 @@ nil); } +// Matcher for the Translate Manual Trigger button. +id<GREYMatcher> TranslateManualTriggerButton() { + return grey_allOf(grey_accessibilityID(kToolsMenuTranslateId), + grey_sufficientlyVisible(), nil); +} + +// Matcher for the Translate Manual Trigger badge. +id<GREYMatcher> TranslateManualTriggerBadge() { + return grey_allOf( + grey_accessibilityID(@"kToolsMenuTextBadgeAccessibilityIdentifier"), + grey_ancestor(TranslateManualTriggerButton()), nil); +} + // Matcher for the New Tab Tip Bubble. id<GREYMatcher> NewTabTipBubble() { return grey_accessibilityLabel( @@ -118,6 +138,16 @@ feature_engagement::TrackerFactory::GetInstance()->SetTestingFactory( browserState, base::BindRepeating(&CreateTestFeatureEngagementTracker)); + + // Wait until the feature engagement tracker is initialized. + ConditionBlock condition = ^{ + return feature_engagement::TrackerFactory::GetForBrowserState( + chrome_test_util::GetOriginalBrowserState()) + ->IsInitialized(); + }; + GREYAssert(WaitUntilConditionOrTimeout(base::test::ios::kWaitForActionTimeout, + condition), + @"Feature engagement tracker failed to initialize."); } // Enables the Badged Reading List help to be triggered for |feature_list|. @@ -140,6 +170,25 @@ badged_reading_list_params); } +// Enables the Badged Translate Manual Trigger feature for |feature_list|. +void EnableBadgedTranslateManualTrigger( + base::test::ScopedFeatureList& feature_list) { + std::map<std::string, std::string> badged_translate_manual_trigger_params; + badged_translate_manual_trigger_params["availability"] = "any"; + badged_translate_manual_trigger_params["session_rate"] = "==0"; + badged_translate_manual_trigger_params["event_used"] = + "name:triggered_translate_infobar;comparator:==0;window:360;storage:360"; + badged_translate_manual_trigger_params["event_trigger"] = + "name:badged_translate_manual_trigger_trigger;comparator:==0;window:360;" + "storage:360"; + + feature_list.InitWithFeaturesAndParameters( + {{feature_engagement::kIPHBadgedTranslateManualTriggerFeature, + badged_translate_manual_trigger_params}, + {translate::kTranslateMobileManualTrigger, {}}}, + {}); +} + // Enables the New Tab Tip to be triggered for |feature_list|. void EnableNewTabTipTriggering(base::test::ScopedFeatureList& feature_list) { std::map<std::string, std::string> new_tab_tip_params; @@ -196,6 +245,18 @@ long_press_tip_params); } +// net::EmbeddedTestServer handler for kFrenchPageURLPath. +std::unique_ptr<net::test_server::HttpResponse> LoadFrenchPage( + const net::test_server::HttpRequest& request) { + std::unique_ptr<net::test_server::BasicHttpResponse> http_response( + new net::test_server::BasicHttpResponse); + http_response->set_content_type("text/html"); + http_response->set_content( + "Maître Corbeau, sur un arbre perché, Tenait en son bec un fromage. " + "Maître Renard, par l’odeur alléché, Lui tint à peu près ce langage"); + return std::move(http_response); +} + } // namespace // Tests related to the triggering of In Product Help features. @@ -303,6 +364,88 @@ assertWithMatcher:grey_notVisible()]; } +// Verifies that the Badged Manual Translate Trigger feature shows only once +// when the triggering conditions are met. +- (void)testBadgedTranslateManualTriggerFeatureShouldShowOnce { + base::test::ScopedFeatureList scoped_feature_list; + EnableBadgedTranslateManualTrigger(scoped_feature_list); + + // Ensure that the FeatureEngagementTracker picks up the new feature + // configuration provided by |scoped_feature_list|. + LoadFeatureEngagementTracker(); + + [ChromeEarlGreyUI openToolsMenu]; + + // Make sure the Manual Translate Trigger entry is visible. + [[[EarlGrey selectElementWithMatcher:TranslateManualTriggerButton()] + usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 150) + onElementWithMatcher:chrome_test_util::ToolsMenuView()] + assertWithMatcher:grey_notNil()]; + + // Make sure the Manual Translate Trigger entry badge is visible. + [[[EarlGrey selectElementWithMatcher:TranslateManualTriggerBadge()] + usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 150) + onElementWithMatcher:chrome_test_util::ToolsMenuView()] + assertWithMatcher:grey_notNil()]; + + // Close tools menu by tapping reload. + [[[EarlGrey selectElementWithMatcher:chrome_test_util::ReloadButton()] + usingSearchAction:grey_scrollInDirection(kGREYDirectionUp, 150) + onElementWithMatcher:chrome_test_util::ToolsMenuView()] + performAction:grey_tap()]; + + [ChromeEarlGreyUI openToolsMenu]; + + // Make sure the Manual Translate Trigger entry is visible. + [[[EarlGrey selectElementWithMatcher:TranslateManualTriggerButton()] + usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 150) + onElementWithMatcher:chrome_test_util::ToolsMenuView()] + assertWithMatcher:grey_notNil()]; + + // Verify that the badge does not appear again. + [[[EarlGrey selectElementWithMatcher:TranslateManualTriggerBadge()] + usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 150) + onElementWithMatcher:chrome_test_util::ToolsMenuView()] + assertWithMatcher:grey_notVisible()]; +} + +// Verifies that the Badged Manual Translate Trigger feature does not show if +// the entry has already been used. +- (void)testBadgedTranslateManualTriggerFeatureAlreadyUsed { + // Set up the test server. + self.testServer->RegisterDefaultHandler(base::BindRepeating( + net::test_server::HandlePrefixedRequest, kFrenchPageURLPath, + base::BindRepeating(&LoadFrenchPage))); + GREYAssertTrue(self.testServer->Start(), @"Test server failed to start"); + + // Load a URL with french text so that language detection is performed. + [ChromeEarlGrey loadURL:self.testServer->GetURL(kFrenchPageURLPath)]; + + base::test::ScopedFeatureList scoped_feature_list; + EnableBadgedTranslateManualTrigger(scoped_feature_list); + + // Ensure that the FeatureEngagementTracker picks up the new feature + // configuration provided by |scoped_feature_list|. + LoadFeatureEngagementTracker(); + + // Simulate using the Manual Translate Trigger entry. + [chrome_test_util::BrowserCommandDispatcherForMainBVC() showTranslate]; + + [ChromeEarlGreyUI openToolsMenu]; + + // Make sure the Manual Translate Trigger entry is visible. + [[[EarlGrey selectElementWithMatcher:TranslateManualTriggerButton()] + usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 150) + onElementWithMatcher:chrome_test_util::ToolsMenuView()] + assertWithMatcher:grey_notNil()]; + + // Verify that the badge does not appear. + [[[EarlGrey selectElementWithMatcher:TranslateManualTriggerBadge()] + usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 150) + onElementWithMatcher:chrome_test_util::ToolsMenuView()] + assertWithMatcher:grey_notVisible()]; +} + // Verifies that the New Tab Tip appears when all conditions are met. - (void)testNewTabTipPromoShouldShow { base::test::ScopedFeatureList scoped_feature_list;
diff --git a/ios/chrome/browser/send_tab_to_self/BUILD.gn b/ios/chrome/browser/send_tab_to_self/BUILD.gn index 91cf9a3..2da9c10 100644 --- a/ios/chrome/browser/send_tab_to_self/BUILD.gn +++ b/ios/chrome/browser/send_tab_to_self/BUILD.gn
@@ -5,19 +5,34 @@ source_set("send_tab_to_self") { configs += [ "//build/config/compiler:enable_arc" ] sources = [ + "ios_send_tab_to_self_infobar_delegate.cc", + "ios_send_tab_to_self_infobar_delegate.h", "send_tab_to_self_client_service_factory.h", "send_tab_to_self_client_service_factory.mm", - "send_tab_to_self_client_service_ios.cc", "send_tab_to_self_client_service_ios.h", + "send_tab_to_self_client_service_ios.mm", ] deps = [ "//base", + "//components/infobars/core", "//components/keyed_service/core", "//components/keyed_service/ios", "//components/send_tab_to_self", "//components/sync", + "//ios/chrome/app/strings", + "//ios/chrome/app/theme:theme_grit", "//ios/chrome/browser", "//ios/chrome/browser/browser_state", + "//ios/chrome/browser/infobars", + "//ios/chrome/browser/infobars:public", "//ios/chrome/browser/sync", + "//ios/chrome/browser/tabs", + "//ios/chrome/browser/ui/infobars:infobars_ui", + "//ios/chrome/browser/ui/util", + "//ios/chrome/browser/web_state_list", + "//ios/web", + "//ui/base", + "//ui/gfx", + "//ui/strings:ui_strings_grit", ] }
diff --git a/ios/chrome/browser/send_tab_to_self/ios_send_tab_to_self_infobar_delegate.cc b/ios/chrome/browser/send_tab_to_self/ios_send_tab_to_self_infobar_delegate.cc new file mode 100644 index 0000000..938efe9 --- /dev/null +++ b/ios/chrome/browser/send_tab_to_self/ios_send_tab_to_self_infobar_delegate.cc
@@ -0,0 +1,83 @@ +// Copyright 2019 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 "ios/chrome/browser/send_tab_to_self/ios_send_tab_to_self_infobar_delegate.h" + +#include "base/memory/ptr_util.h" +#include "base/metrics/histogram_macros.h" +#include "base/strings/utf_string_conversions.h" +#include "components/infobars/core/infobar.h" +#include "components/send_tab_to_self/send_tab_to_self_entry.h" +#include "ios/chrome/grit/ios_theme_resources.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/strings/grit/ui_strings.h" + +namespace send_tab_to_self { + +// static +std::unique_ptr<IOSSendTabToSelfInfoBarDelegate> +IOSSendTabToSelfInfoBarDelegate::Create(const SendTabToSelfEntry* entry) { + return base::WrapUnique(new IOSSendTabToSelfInfoBarDelegate(entry)); +} + +IOSSendTabToSelfInfoBarDelegate::~IOSSendTabToSelfInfoBarDelegate() {} + +IOSSendTabToSelfInfoBarDelegate::IOSSendTabToSelfInfoBarDelegate( + const SendTabToSelfEntry* entry) { + DCHECK(entry); + entry_ = entry; +} + +infobars::InfoBarDelegate::InfoBarIdentifier +IOSSendTabToSelfInfoBarDelegate::GetIdentifier() const { + return SEND_TAB_TO_SELF_INFOBAR_DELEGATE; +} + +int IOSSendTabToSelfInfoBarDelegate::GetButtons() const { + return BUTTON_NONE; +} + +int IOSSendTabToSelfInfoBarDelegate::GetIconId() const { + return IDR_IOS_INFOBAR_SEND_TAB_TO_SELF; +} + +void IOSSendTabToSelfInfoBarDelegate::InfoBarDismissed() { + Cancel(); +} + +base::string16 IOSSendTabToSelfInfoBarDelegate::GetMessageText() const { + // The iOS confirm infobar controller requires the message to also include the + // link text. + return l10n_util::GetStringUTF16(IDS_SEND_TAB_TO_SELF_INFOBAR_MESSAGE) + + base::UTF8ToUTF16(" ") + + l10n_util::GetStringUTF16(IDS_SEND_TAB_TO_SELF_INFOBAR_MESSAGE_URL); +} + +base::string16 IOSSendTabToSelfInfoBarDelegate::GetLinkText() const { + return l10n_util::GetStringUTF16(IDS_SEND_TAB_TO_SELF_INFOBAR_MESSAGE_URL); +} + +GURL IOSSendTabToSelfInfoBarDelegate::GetLinkURL() const { + return entry_->GetURL(); +} + +bool IOSSendTabToSelfInfoBarDelegate::LinkClicked( + WindowOpenDisposition disposition) { + infobar()->owner()->OpenURL(GetLinkURL(), disposition); + return true; +} + +bool IOSSendTabToSelfInfoBarDelegate::Accept() { + // TODO(crbug.com/944602): Implement. + NOTIMPLEMENTED(); + return true; +} + +bool IOSSendTabToSelfInfoBarDelegate::Cancel() { + // TODO(crbug.com/944602): Implement. + NOTIMPLEMENTED(); + return true; +} + +} // namespace send_tab_to_self
diff --git a/ios/chrome/browser/send_tab_to_self/ios_send_tab_to_self_infobar_delegate.h b/ios/chrome/browser/send_tab_to_self/ios_send_tab_to_self_infobar_delegate.h new file mode 100644 index 0000000..847e23e5 --- /dev/null +++ b/ios/chrome/browser/send_tab_to_self/ios_send_tab_to_self_infobar_delegate.h
@@ -0,0 +1,49 @@ +// Copyright 2019 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 IOS_CHROME_BROWSER_SEND_TAB_TO_SELF_IOS_SEND_TAB_TO_SELF_INFOBAR_DELEGATE_H_ +#define IOS_CHROME_BROWSER_SEND_TAB_TO_SELF_IOS_SEND_TAB_TO_SELF_INFOBAR_DELEGATE_H_ + +#include <memory> + +#include "base/macros.h" +#include "base/strings/string16.h" +#include "components/infobars/core/confirm_infobar_delegate.h" +#include "url/gurl.h" + +namespace send_tab_to_self { + +class SendTabToSelfEntry; + +class IOSSendTabToSelfInfoBarDelegate : public ConfirmInfoBarDelegate { + public: + static std::unique_ptr<IOSSendTabToSelfInfoBarDelegate> Create( + const SendTabToSelfEntry* entry); + + ~IOSSendTabToSelfInfoBarDelegate() override; + + private: + IOSSendTabToSelfInfoBarDelegate(const SendTabToSelfEntry* entry); + + // ConfirmInfoBarDelegate: + infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier() const override; + int GetButtons() const override; + int GetIconId() const override; + void InfoBarDismissed() override; + base::string16 GetMessageText() const override; + base::string16 GetLinkText() const override; + GURL GetLinkURL() const override; + bool LinkClicked(WindowOpenDisposition disposition) override; + bool Accept() override; + bool Cancel() override; + + // The entry that was share to this device. Must outlive this instance. + const SendTabToSelfEntry* entry_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(IOSSendTabToSelfInfoBarDelegate); +}; + +} // namespace send_tab_to_self + +#endif // IOS_CHROME_BROWSER_SEND_TAB_TO_SELF_IOS_SEND_TAB_TO_SELF_INFOBAR_DELEGATE_H_ \ No newline at end of file
diff --git a/ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_ios.cc b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_ios.cc deleted file mode 100644 index e6f066fd..0000000 --- a/ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_ios.cc +++ /dev/null
@@ -1,51 +0,0 @@ -// Copyright 2019 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 "ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_ios.h" - -#include <memory> -#include <string> -#include <vector> - -#include "base/feature_list.h" -#include "base/logging.h" -#include "components/sync/driver/sync_driver_switches.h" -#include "ios/chrome/browser/browser_state/chrome_browser_state.h" - -namespace send_tab_to_self { - -SendTabToSelfClientServiceIOS::SendTabToSelfClientServiceIOS( - ios::ChromeBrowserState* browser_state, - SendTabToSelfModel* model) - : model_(model) { - model_->AddObserver(this); -} - -SendTabToSelfClientServiceIOS::~SendTabToSelfClientServiceIOS() { - model_->RemoveObserver(this); - model_ = nullptr; -} - -void SendTabToSelfClientServiceIOS::SendTabToSelfModelLoaded() { - // TODO(crbug.com/949756): Push changes that happened before the model was - // loaded. -} - -void SendTabToSelfClientServiceIOS::EntriesAddedRemotely( - const std::vector<const SendTabToSelfEntry*>& new_entries) { - if (!base::FeatureList::IsEnabled(switches::kSyncSendTabToSelf)) { - return; - } - NOTIMPLEMENTED(); -} - -void SendTabToSelfClientServiceIOS::EntriesRemovedRemotely( - const std::vector<std::string>& guids) { - if (!base::FeatureList::IsEnabled(switches::kSyncSendTabToSelf)) { - return; - } - NOTIMPLEMENTED(); -} - -} // namespace send_tab_to_self
diff --git a/ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_ios.h b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_ios.h index ad3ac30..bcc9e0f 100644 --- a/ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_ios.h +++ b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_ios.h
@@ -45,6 +45,9 @@ // Owned by the SendTabToSelfSyncService which should outlive this class SendTabToSelfModel* model_; + // The current browser state. Must outlive this object. + ios::ChromeBrowserState* browser_state_; + DISALLOW_COPY_AND_ASSIGN(SendTabToSelfClientServiceIOS); };
diff --git a/ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_ios.mm b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_ios.mm new file mode 100644 index 0000000..52dc7e0 --- /dev/null +++ b/ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_ios.mm
@@ -0,0 +1,100 @@ +// Copyright 2019 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 "ios/chrome/browser/send_tab_to_self/send_tab_to_self_client_service_ios.h" + +#include <memory> +#include <string> +#include <vector> + +#import <Foundation/Foundation.h> + +#include "base/logging.h" +#include "components/infobars/core/infobar.h" +#include "components/infobars/core/infobar_manager.h" +#include "components/sync/driver/sync_driver_switches.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/chrome/browser/infobars/infobar.h" +#include "ios/chrome/browser/infobars/infobar_manager_impl.h" +#import "ios/chrome/browser/infobars/infobar_utils.h" +#include "ios/chrome/browser/send_tab_to_self/ios_send_tab_to_self_infobar_delegate.h" +#import "ios/chrome/browser/tabs/tab_model.h" +#import "ios/chrome/browser/tabs/tab_model_list.h" +#import "ios/chrome/browser/web_state_list/web_state_list.h" +#import "ios/web/public/web_state/web_state.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace send_tab_to_self { + +SendTabToSelfClientServiceIOS::SendTabToSelfClientServiceIOS( + ios::ChromeBrowserState* browser_state, + SendTabToSelfModel* model) + : model_(model), browser_state_(browser_state) { + model_->AddObserver(this); +} + +SendTabToSelfClientServiceIOS::~SendTabToSelfClientServiceIOS() { + model_->RemoveObserver(this); + model_ = nullptr; +} + +void SendTabToSelfClientServiceIOS::SendTabToSelfModelLoaded() { + // TODO(crbug.com/949756): Push changes that happened before the model was + // loaded. +} + +void SendTabToSelfClientServiceIOS::EntriesAddedRemotely( + const std::vector<const SendTabToSelfEntry*>& new_entries) { + // TODO(crbug.com/953513): Use utils file instead. + if (!base::FeatureList::IsEnabled(switches::kSyncSendTabToSelf)) { + return; + } + + if (new_entries.empty()) { + return; + } + + TabModel* tab_model = + TabModelList::GetLastActiveTabModelForChromeBrowserState(browser_state_); + if (!tab_model) { + return; + } + + WebStateList* web_state_list = tab_model.webStateList; + if (!web_state_list) { + return; + } + + // If there is no web state or it is not visible, we cannot add an infobar to + // it. + // TODO(crbug.com/944602): Wait until a web state is active and add the info + // bar then. + web::WebState* web_state = web_state_list->GetActiveWebState(); + if (!web_state || !web_state->IsVisible()) { + NOTIMPLEMENTED(); + return; + } + + infobars::InfoBarManager* infobar_manager = + InfoBarManagerImpl::FromWebState(web_state); + + // Since we can only show one infobar at the time, pick the most recent entry. + // TODO(crbug.com/944602): Create a function that returns the most recently + // shared entry. + infobar_manager->AddInfoBar(CreateConfirmInfoBar( + IOSSendTabToSelfInfoBarDelegate::Create(new_entries.back()))); +} + +void SendTabToSelfClientServiceIOS::EntriesRemovedRemotely( + const std::vector<std::string>& guids) { + if (!base::FeatureList::IsEnabled(switches::kSyncSendTabToSelf)) { + return; + } + NOTIMPLEMENTED(); +} + +} // namespace send_tab_to_self
diff --git a/ios/chrome/browser/sync/OWNERS b/ios/chrome/browser/sync/OWNERS index 5dde3db56..c0c578e 100644 --- a/ios/chrome/browser/sync/OWNERS +++ b/ios/chrome/browser/sync/OWNERS
@@ -7,3 +7,4 @@ # TEAM: ios-directory-owners@chromium.org # OS: iOS +# COMPONENT: Services>Sync
diff --git a/ios/chrome/browser/sync/sync_setup_service.cc b/ios/chrome/browser/sync/sync_setup_service.cc index 277b8b78..1c598646 100644 --- a/ios/chrome/browser/sync/sync_setup_service.cc +++ b/ios/chrome/browser/sync/sync_setup_service.cc
@@ -9,6 +9,7 @@ #include "base/metrics/histogram_macros.h" #include "base/stl_util.h" #include "components/sync/base/stop_source.h" +#include "components/sync/base/user_selectable_type.h" #include "components/sync/driver/sync_service.h" #include "components/sync/driver/sync_user_settings.h" #include "components/unified_consent/feature.h" @@ -27,9 +28,6 @@ SyncSetupService::SyncSetupService(syncer::SyncService* sync_service) : sync_service_(sync_service) { DCHECK(sync_service_); - for (unsigned int i = 0; i < base::size(kDataTypes); ++i) { - user_selectable_types_.Put(kDataTypes[i]); - } } SyncSetupService::~SyncSetupService() { @@ -56,16 +54,23 @@ bool enabled) { if (!sync_blocker_) sync_blocker_ = sync_service_->GetSetupInProgressHandle(); - syncer::ModelTypeSet types = GetPreferredDataTypes(); + syncer::ModelTypeSet model_types = GetPreferredDataTypes(); if (enabled) - types.Put(datatype); + model_types.Put(datatype); else - types.Remove(datatype); - types.RetainAll(user_selectable_types_); + model_types.Remove(datatype); + // TODO(crbug.com/950874): support syncer::UserSelectableType in ios code, + // get rid of this workaround and consider getting rid of SyncableDatatype. + syncer::UserSelectableTypeSet selected_types; + for (syncer::UserSelectableType type : syncer::UserSelectableTypeSet::All()) { + if (model_types.Has(syncer::UserSelectableTypeToCanonicalModelType(type))) { + selected_types.Put(type); + } + } if (enabled && !IsSyncEnabled()) SetSyncEnabledWithoutChangingDatatypes(true); - sync_service_->GetUserSettings()->SetChosenDataTypes(IsSyncingAllDataTypes(), - types); + sync_service_->GetUserSettings()->SetSelectedTypes(IsSyncingAllDataTypes(), + selected_types); if (GetPreferredDataTypes().Empty()) SetSyncEnabled(false); } @@ -101,9 +106,8 @@ sync_blocker_ = sync_service_->GetSetupInProgressHandle(); if (sync_all && !IsSyncEnabled()) SetSyncEnabled(true); - sync_service_->GetUserSettings()->SetChosenDataTypes( - sync_all, - Intersection(GetPreferredDataTypes(), syncer::UserSelectableTypes())); + sync_service_->GetUserSettings()->SetSelectedTypes( + sync_all, sync_service_->GetUserSettings()->GetSelectedTypes()); } bool SyncSetupService::IsSyncEnabled() const {
diff --git a/ios/chrome/browser/sync/sync_setup_service.h b/ios/chrome/browser/sync/sync_setup_service.h index b807044..18c2204e 100644 --- a/ios/chrome/browser/sync/sync_setup_service.h +++ b/ios/chrome/browser/sync/sync_setup_service.h
@@ -123,7 +123,6 @@ void SetSyncEnabledWithoutChangingDatatypes(bool sync_enabled); syncer::SyncService* const sync_service_; - syncer::ModelTypeSet user_selectable_types_; // Prevents Sync from running until configuration is complete. std::unique_ptr<syncer::SyncSetupInProgressHandle> sync_blocker_;
diff --git a/ios/chrome/browser/ui/alert_view_controller/BUILD.gn b/ios/chrome/browser/ui/alert_view_controller/BUILD.gn index 772e3bc..7f360bb 100644 --- a/ios/chrome/browser/ui/alert_view_controller/BUILD.gn +++ b/ios/chrome/browser/ui/alert_view_controller/BUILD.gn
@@ -7,7 +7,9 @@ "alert_view_controller.h", "alert_view_controller.mm", ] - deps = [] + deps = [ + "//ios/chrome/common/ui_util", + ] libs = [ "UIKit.framework" ] configs += [ "//build/config/compiler:enable_arc" ] }
diff --git a/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.mm b/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.mm index 7ee218c..7a9a4cc6 100644 --- a/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.mm +++ b/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.mm
@@ -184,3 +184,5 @@ [stackView addArrangedSubview:button]; } } + +@end
diff --git a/ios/chrome/browser/ui/browser_view/BUILD.gn b/ios/chrome/browser/ui/browser_view/BUILD.gn index b4fe1e1..269cd571 100644 --- a/ios/chrome/browser/ui/browser_view/BUILD.gn +++ b/ios/chrome/browser/ui/browser_view/BUILD.gn
@@ -19,6 +19,7 @@ "//base", "//base:i18n", "//components/bookmarks/browser", + "//components/feature_engagement/public", "//components/image_fetcher/ios", "//components/language/ios/browser", "//components/omnibox/browser",
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm index a42e98c..7bdbf0e 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -21,6 +21,8 @@ #include "base/metrics/user_metrics_action.h" #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" +#include "components/feature_engagement/public/event_constants.h" +#include "components/feature_engagement/public/tracker.h" #import "components/language/ios/browser/ios_language_detection_tab_helper.h" #include "components/omnibox/browser/location_bar_model_impl.h" #include "components/reading_list/core/reading_list_model.h" @@ -38,6 +40,7 @@ #include "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/chrome_url_constants.h" #import "ios/chrome/browser/download/download_manager_tab_helper.h" +#include "ios/chrome/browser/feature_engagement/tracker_factory.h" #include "ios/chrome/browser/feature_engagement/tracker_util.h" #import "ios/chrome/browser/find_in_page/find_tab_helper.h" #include "ios/chrome/browser/first_run/first_run.h" @@ -4189,6 +4192,11 @@ #endif // !defined(NDEBUG) - (void)showTranslate { + feature_engagement::Tracker* engagement_tracker = + feature_engagement::TrackerFactory::GetForBrowserState(self.browserState); + engagement_tracker->NotifyEvent( + feature_engagement::events::kTriggeredTranslateInfobar); + DCHECK(self.currentWebState); ChromeIOSTranslateClient* translateClient = ChromeIOSTranslateClient::FromWebState(self.currentWebState);
diff --git a/ios/chrome/browser/ui/main/tab_switcher.h b/ios/chrome/browser/ui/main/tab_switcher.h index 9586453..16ddcb74 100644 --- a/ios/chrome/browser/ui/main/tab_switcher.h +++ b/ios/chrome/browser/ui/main/tab_switcher.h
@@ -16,6 +16,7 @@ @class TabModel; @protocol TabSwitcher; @protocol ToolbarCommands; +struct UrlLoadParams; // This delegate is used to drive the TabSwitcher dismissal and execute code // when the presentation and dismmiss animations finishes. The main controller @@ -67,10 +68,8 @@ // |-tabSwitcherDismissTransitionDidEnd:| // to inform the delegate when this animation begins and ends. - (Tab*)dismissWithNewTabAnimationToModel:(TabModel*)targetModel - withURL:(const GURL&)url - virtualURL:(const GURL&)virtualURL - atIndex:(NSUInteger)position - transition:(ui::PageTransition)transition; + withUrlLoadParams:(const UrlLoadParams&)urlLoadParams + atIndex:(NSUInteger)position; // Updates the OTR (Off The Record) tab model. Should only be called when both // the current OTR tab model and the new OTR tab model are either nil or contain
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_left_image_consumer.h b/ios/chrome/browser/ui/omnibox/omnibox_left_image_consumer.h index bdda045..452d999 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_left_image_consumer.h +++ b/ios/chrome/browser/ui/omnibox/omnibox_left_image_consumer.h
@@ -7,15 +7,23 @@ #import <UIKit/UIKit.h> +#include "base/optional.h" #include "components/omnibox/browser/autocomplete_match_type.h" +#include "components/omnibox/browser/suggestion_answer.h" // Describes an object that accepts a left image for the omnibox. The left image // is used for showing the current selected suggestion icon, when the // suggestions popup is visible. @protocol OmniboxLeftImageConsumer -// The |imageId| is a resource id. -- (void)setLeftImageForAutocompleteType:(AutocompleteMatchType::Type)type; +// The suggestion icon can either be determined by |matchType|, or, in new UI, +// answer icons will be used instead, if available (i.e. the match is an +// answer). Favicons are only used for non-search match types. +- (void)setLeftImageForAutocompleteType:(AutocompleteMatchType::Type)matchType + answerType: + (base::Optional<SuggestionAnswer::AnswerType>) + answerType + faviconURL:(GURL)faviconURL; @end
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_mediator.mm b/ios/chrome/browser/ui/omnibox/omnibox_mediator.mm index 25e0b52..aed5006 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_mediator.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_mediator.mm
@@ -70,9 +70,13 @@ #pragma mark - OmniboxLeftImageConsumer -- (void)setLeftImageForAutocompleteType:(AutocompleteMatchType::Type)type { +- (void)setLeftImageForAutocompleteType:(AutocompleteMatchType::Type)matchType + answerType: + (base::Optional<SuggestionAnswer::AnswerType>) + answerType + faviconURL:(GURL)faviconURL { UIImage* image = GetOmniboxSuggestionIconForAutocompleteMatchType( - type, /* is_starred */ false); + matchType, /* is_starred */ false); [self.consumer updateAutocompleteIcon:image]; }
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.h b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.h index e689dfe..7a994f1 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.h +++ b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.h
@@ -106,7 +106,9 @@ // OmniboxPopupViewSuggestionsDelegate methods void OnTopmostSuggestionImageChanged( - AutocompleteMatchType::Type type) override; + AutocompleteMatchType::Type match_type, + base::Optional<SuggestionAnswer::AnswerType> answer_type, + GURL favicon_url) override; void OnResultsChanged(const AutocompleteResult& result) override; void OnPopupDidScroll() override; void OnSelectedMatchForAppending(const base::string16& str) override;
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm index c574a7d0..1123d83 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm
@@ -815,8 +815,12 @@ #pragma mark - OmniboxPopupViewSuggestionsDelegate void OmniboxViewIOS::OnTopmostSuggestionImageChanged( - AutocompleteMatchType::Type type) { - [left_image_consumer_ setLeftImageForAutocompleteType:type]; + AutocompleteMatchType::Type match_type, + base::Optional<SuggestionAnswer::AnswerType> answer_type, + GURL favicon_url) { + [left_image_consumer_ setLeftImageForAutocompleteType:match_type + answerType:answer_type + faviconURL:favicon_url]; } void OmniboxViewIOS::OnResultsChanged(const AutocompleteResult& result) {
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_ios.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_ios.mm index f3c9b1bd..2cff38b 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_ios.mm +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_ios.mm
@@ -51,7 +51,16 @@ void OmniboxPopupViewIOS::UpdateEditViewIcon() { const AutocompleteResult& result = model_->result(); const AutocompleteMatch& match = result.match_at(model_->selected_line()); - delegate_->OnTopmostSuggestionImageChanged(match.type); + + base::Optional<SuggestionAnswer::AnswerType> optAnswerType = base::nullopt; + if (match.answer && match.answer->type() > 0 && + match.answer->type() < + SuggestionAnswer::AnswerType::ANSWER_TYPE_TOTAL_COUNT) { + optAnswerType = + static_cast<SuggestionAnswer::AnswerType>(match.answer->type()); + } + delegate_->OnTopmostSuggestionImageChanged(match.type, optAnswerType, + match.destination_url); } void OmniboxPopupViewIOS::UpdatePopupAppearance() {
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_suggestions_delegate.h b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_suggestions_delegate.h index f96186e3d6..5cc3b14 100644 --- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_suggestions_delegate.h +++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_view_suggestions_delegate.h
@@ -5,6 +5,9 @@ #ifndef IOS_CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_POPUP_VIEW_SUGGESTIONS_DELEGATE_H_ #define IOS_CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_POPUP_VIEW_SUGGESTIONS_DELEGATE_H_ +#include "base/optional.h" +#include "components/omnibox/browser/suggestion_answer.h" + struct AutocompleteMatch; class AutocompleteResult; class GURL; @@ -13,8 +16,13 @@ class OmniboxPopupViewSuggestionsDelegate { public: // Called whenever the topmost suggestion image has changed. + // Current UI should only use |matchType|; new UI may use |answerType| and + // |faviconURL| if available. virtual void OnTopmostSuggestionImageChanged( - AutocompleteMatchType::Type type) = 0; + AutocompleteMatchType::Type match_type, + base::Optional<SuggestionAnswer::AnswerType> answer_type, + GURL favicon_url) = 0; + // Called when results are updated. virtual void OnResultsChanged(const AutocompleteResult& result) = 0; // Called whenever the popup is scrolled.
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_action_handler.h b/ios/chrome/browser/ui/popup_menu/popup_menu_action_handler.h index ea0f1a7..eb06d4d2 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_action_handler.h +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_action_handler.h
@@ -9,9 +9,6 @@ #import "ios/chrome/browser/ui/popup_menu/public/popup_menu_table_view_controller_delegate.h" -namespace feature_engagement { -class Tracker; -} @protocol ApplicationCommands; @protocol BrowserCommands; @protocol LoadQueryCommands; @@ -27,11 +24,6 @@ // Command handler. @property(nonatomic, weak) id<PopupMenuActionHandlerCommands> commandHandler; -// Records events for the use menu items with in-product help. This instance -// does not take ownership of tracker. Tracker must not be destroyed during -// lifetime of this instance. -@property(nonatomic, assign) feature_engagement::Tracker* engagementTracker; - // Dispatcher. @property(nonatomic, weak) id<ApplicationCommands, BrowserCommands, LoadQueryCommands>
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_action_handler.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_action_handler.mm index 317e2c6..c6b04a19 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_action_handler.mm +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_action_handler.mm
@@ -9,8 +9,6 @@ #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" #include "base/strings/sys_string_conversions.h" -#include "components/feature_engagement/public/event_constants.h" -#include "components/feature_engagement/public/tracker.h" #include "components/open_from_clipboard/clipboard_recent_content.h" #import "ios/chrome/browser/ui/commands/application_commands.h" #import "ios/chrome/browser/ui/commands/browser_commands.h" @@ -70,12 +68,6 @@ break; case PopupMenuActionTranslate: base::RecordAction(UserMetricsAction("MobileMenuTranslate")); - // Send the "Triggered Translate Infobar" event to the - // feature_engagement::Tracker when the user selects the menu item. - if (self.engagementTracker) { - self.engagementTracker->NotifyEvent( - feature_engagement::events::kTriggeredTranslateInfobar); - } [self.dispatcher showTranslate]; break; case PopupMenuActionFindInPage:
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm index b96e5e1..89e1dad 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.mm
@@ -239,8 +239,6 @@ self.mediator.popupMenu = tableViewController; self.actionHandler = [[PopupMenuActionHandler alloc] init]; - self.actionHandler.engagementTracker = - feature_engagement::TrackerFactory::GetForBrowserState(self.browserState); self.actionHandler.baseViewController = self.baseViewController; self.actionHandler.dispatcher = static_cast<id<ApplicationCommands, BrowserCommands, LoadQueryCommands>>(
diff --git a/ios/chrome/browser/ui/qr_scanner/camera_controller.mm b/ios/chrome/browser/ui/qr_scanner/camera_controller.mm index bcc0227..e83efbe 100644 --- a/ios/chrome/browser/ui/qr_scanner/camera_controller.mm +++ b/ios/chrome/browser/ui/qr_scanner/camera_controller.mm
@@ -14,17 +14,13 @@ #endif @interface CameraController ()<AVCaptureMetadataOutputObjectsDelegate> { - // The capture session for recording video and detecting QR codes. - AVCaptureSession* _captureSession; - // The metadata output attached to the capture session. - AVCaptureMetadataOutput* _metadataOutput; - // The delegate which receives the scanned result. All methods of this - // delegate should be called on the main queue. - __weak id<CameraControllerDelegate> _delegate; // The queue for dispatching calls to |_captureSession|. dispatch_queue_t _sessionQueue; } +// The delegate which receives the scanned result. All methods of this +// delegate should be called on the main queue. +@property(nonatomic, readwrite, weak) id<CameraControllerDelegate> delegate; // The current state of the camera. The state is set to CAMERA_NOT_LOADED before // the camera is first loaded, and afterwards it is never CAMERA_NOT_LOADED. @property(nonatomic, readwrite, assign) qr_scanner::CameraState cameraState; @@ -33,6 +29,11 @@ // The current availability of the torch. @property(nonatomic, readwrite, assign, getter=isTorchAvailable) BOOL torchAvailable; +// The capture session for recording video and detecting QR codes. +@property(nonatomic, readwrite) AVCaptureSession* captureSession; +// The metadata output attached to the capture session. +@property(nonatomic, readwrite) AVCaptureMetadataOutput* metadataOutput; +@property(nonatomic, readwrite, assign) CGRect viewportRect; // Initializes the controller with the |delegate|. - (instancetype)initWithDelegate:(id<CameraControllerDelegate>)delegate @@ -53,12 +54,7 @@ @end -@implementation CameraController { - qr_scanner::CameraState _cameraState; - BOOL _torchActive; - BOOL _torchAvailable; - CGRect _viewportRect; -} +@implementation CameraController #pragma mark lifecycle @@ -73,16 +69,16 @@ self = [super init]; if (self) { DCHECK(delegate); - _cameraState = qr_scanner::CAMERA_NOT_LOADED; + self.cameraState = qr_scanner::CAMERA_NOT_LOADED; _delegate = delegate; std::string queueName = base::StringPrintf("%s.chrome.ios.QRScannerCaptureSessionQueue", BUILDFLAG(IOS_APP_BUNDLE_ID_PREFIX)); _sessionQueue = dispatch_queue_create(queueName.c_str(), DISPATCH_QUEUE_SERIAL); - _torchAvailable = NO; - _torchActive = NO; - _viewportRect = CGRectNull; + self.torchAvailable = NO; + self.torchActive = NO; + self.viewportRect = CGRectNull; } return self; } @@ -101,22 +97,29 @@ (AVCaptureVideoPreviewLayer*)previewLayer { DCHECK(previewLayer); DCHECK([self getAuthorizationStatus] == AVAuthorizationStatusNotDetermined); + __weak CameraController* weakSelf = self; [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^void(BOOL granted) { if (!granted) { - [self setCameraState:qr_scanner::CAMERA_PERMISSION_DENIED]; + [weakSelf + setCameraState:qr_scanner::CAMERA_PERMISSION_DENIED]; } else { - [self loadCaptureSession:previewLayer]; + [weakSelf loadCaptureSession:previewLayer]; } }]; } - (void)setViewport:(CGRect)viewportRect { + __weak CameraController* weakSelf = self; dispatch_async(_sessionQueue, ^{ - _viewportRect = viewportRect; - if (_metadataOutput) { - [_metadataOutput setRectOfInterest:_viewportRect]; + CameraController* strongSelf = weakSelf; + if (!strongSelf) { + return; + } + strongSelf.viewportRect = viewportRect; + if (strongSelf.metadataOutput) { + [strongSelf.metadataOutput setRectOfInterest:_viewportRect]; } }); } @@ -131,31 +134,42 @@ } - (void)startRecording { + __weak CameraController* weakSelf = self; dispatch_async(_sessionQueue, ^{ - if ([self isCameraAvailable]) { - if (![_captureSession isRunning]) { - [_captureSession startRunning]; + CameraController* strongSelf = weakSelf; + if (!strongSelf) { + return; + } + if ([strongSelf isCameraAvailable]) { + if (![strongSelf.captureSession isRunning]) { + [strongSelf.captureSession startRunning]; } } }); } - (void)stopRecording { + __weak CameraController* weakSelf = self; dispatch_async(_sessionQueue, ^{ - if ([self isCameraAvailable]) { - if ([_captureSession isRunning]) { - [_captureSession stopRunning]; - } + CameraController* strongSelf = weakSelf; + if (!strongSelf) { + return; + } + if ([strongSelf isCameraAvailable] && + [strongSelf.captureSession isRunning]) { + [strongSelf.captureSession stopRunning]; } }); } - (void)setTorchMode:(AVCaptureTorchMode)mode { + __weak CameraController* weakSelf = self; dispatch_async(_sessionQueue, ^{ - if (![self isCameraAvailable]) { + CameraController* strongSelf = weakSelf; + if (!strongSelf || ![strongSelf isCameraAvailable]) { return; } - AVCaptureDevice* camera = [self getCamera]; + AVCaptureDevice* camera = [strongSelf getCamera]; if (![camera isTorchModeSupported:mode]) { return; } @@ -179,87 +193,97 @@ DCHECK(previewLayer); DCHECK([self cameraState] == qr_scanner::CAMERA_NOT_LOADED); DCHECK([self getAuthorizationStatus] == AVAuthorizationStatusAuthorized); + __weak CameraController* weakSelf = self; dispatch_async(_sessionQueue, ^{ - // Get the back camera. - NSArray* videoCaptureDevices = nil; - NSString* cameraType = @"AVCaptureDeviceTypeBuiltInWideAngleCamera"; - AVCaptureDeviceDiscoverySession* discoverySession = - [AVCaptureDeviceDiscoverySession - discoverySessionWithDeviceTypes:@[ cameraType ] - mediaType:AVMediaTypeVideo - position:AVCaptureDevicePositionBack]; - videoCaptureDevices = [discoverySession devices]; - if ([videoCaptureDevices count] == 0) { - [self setCameraState:qr_scanner::CAMERA_UNAVAILABLE]; - return; - } + [weakSelf continueLoadCaptureSession:previewLayer]; + }); +} - NSUInteger cameraIndex = [videoCaptureDevices - indexOfObjectPassingTest:^BOOL(AVCaptureDevice* device, NSUInteger idx, - BOOL* stop) { - return device.position == AVCaptureDevicePositionBack; - }]; +- (void)continueLoadCaptureSession:(AVCaptureVideoPreviewLayer*)previewLayer { + // Get the back camera. + NSArray* videoCaptureDevices = nil; + NSString* cameraType = @"AVCaptureDeviceTypeBuiltInWideAngleCamera"; + AVCaptureDeviceDiscoverySession* discoverySession = + [AVCaptureDeviceDiscoverySession + discoverySessionWithDeviceTypes:@[ cameraType ] + mediaType:AVMediaTypeVideo + position:AVCaptureDevicePositionBack]; + videoCaptureDevices = [discoverySession devices]; + if ([videoCaptureDevices count] == 0) { + [self setCameraState:qr_scanner::CAMERA_UNAVAILABLE]; + return; + } - // Allow only the back camera. - if (cameraIndex == NSNotFound) { - [self setCameraState:qr_scanner::CAMERA_UNAVAILABLE]; - return; - } - AVCaptureDevice* camera = videoCaptureDevices[cameraIndex]; + NSUInteger cameraIndex = [videoCaptureDevices + indexOfObjectPassingTest:^BOOL(AVCaptureDevice* device, NSUInteger idx, + BOOL* stop) { + return device.position == AVCaptureDevicePositionBack; + }]; - // Configure camera input. - NSError* error = nil; - AVCaptureDeviceInput* videoInput = - [AVCaptureDeviceInput deviceInputWithDevice:camera error:&error]; - if (error || !videoInput) { - [self setCameraState:qr_scanner::CAMERA_UNAVAILABLE]; - return; - } + // Allow only the back camera. + if (cameraIndex == NSNotFound) { + [self setCameraState:qr_scanner::CAMERA_UNAVAILABLE]; + return; + } + AVCaptureDevice* camera = videoCaptureDevices[cameraIndex]; - AVCaptureSession* session = [[AVCaptureSession alloc] init]; - if (![session canAddInput:videoInput]) { - [self setCameraState:qr_scanner::CAMERA_UNAVAILABLE]; - return; - } - [session addInput:videoInput]; + // Configure camera input. + NSError* error = nil; + AVCaptureDeviceInput* videoInput = + [AVCaptureDeviceInput deviceInputWithDevice:camera error:&error]; + if (error || !videoInput) { + [self setCameraState:qr_scanner::CAMERA_UNAVAILABLE]; + return; + } - // Configure metadata output. - AVCaptureMetadataOutput* metadataOutput = - [[AVCaptureMetadataOutput alloc] init]; - [metadataOutput setMetadataObjectsDelegate:self - queue:dispatch_get_main_queue()]; - if (![session canAddOutput:metadataOutput]) { - [self setCameraState:qr_scanner::CAMERA_UNAVAILABLE]; - return; - } - [session addOutput:metadataOutput]; - NSArray* availableCodeTypes = [metadataOutput availableMetadataObjectTypes]; + AVCaptureSession* session = [[AVCaptureSession alloc] init]; + if (![session canAddInput:videoInput]) { + [self setCameraState:qr_scanner::CAMERA_UNAVAILABLE]; + return; + } + [session addInput:videoInput]; - // Require QR code recognition to be available. - if (![availableCodeTypes containsObject:AVMetadataObjectTypeQRCode]) { - [self setCameraState:qr_scanner::CAMERA_UNAVAILABLE]; - return; - } - [metadataOutput setMetadataObjectTypes:availableCodeTypes]; - _metadataOutput = metadataOutput; + // Configure metadata output. + AVCaptureMetadataOutput* metadataOutput = + [[AVCaptureMetadataOutput alloc] init]; + [metadataOutput setMetadataObjectsDelegate:self + queue:dispatch_get_main_queue()]; + if (![session canAddOutput:metadataOutput]) { + [self setCameraState:qr_scanner::CAMERA_UNAVAILABLE]; + return; + } + [session addOutput:metadataOutput]; + NSArray* availableCodeTypes = [metadataOutput availableMetadataObjectTypes]; - _captureSession = session; - [self setCameraState:qr_scanner::CAMERA_AVAILABLE]; - // Setup torchAvailable. - [self - setTorchAvailable:[camera hasTorch] && + // Require QR code recognition to be available. + if (![availableCodeTypes containsObject:AVMetadataObjectTypeQRCode]) { + [self setCameraState:qr_scanner::CAMERA_UNAVAILABLE]; + return; + } + [metadataOutput setMetadataObjectTypes:availableCodeTypes]; + _metadataOutput = metadataOutput; + + _captureSession = session; + [self setCameraState:qr_scanner::CAMERA_AVAILABLE]; + // Setup torchAvailable. + [self setTorchAvailable:[camera hasTorch] && [camera isTorchModeSupported:AVCaptureTorchModeOn] && [camera isTorchModeSupported:AVCaptureTorchModeOff]]; - [previewLayer setSession:_captureSession]; - [previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; - dispatch_async(dispatch_get_main_queue(), ^{ - [self resetVideoOrientation:previewLayer]; - [_delegate captureSessionIsConnected]; - [self startRecording]; - }); - [self startReceivingNotifications]; + [previewLayer setSession:_captureSession]; + [previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill]; + __weak CameraController* weakSelf = self; + dispatch_async(dispatch_get_main_queue(), ^{ + [weakSelf + captureSessionConnected:(AVCaptureVideoPreviewLayer*)previewLayer]; }); + [self startReceivingNotifications]; +} + +- (void)captureSessionConnected:(AVCaptureVideoPreviewLayer*)previewLayer { + [self resetVideoOrientation:previewLayer]; + [_delegate captureSessionIsConnected]; + [self startRecording]; } - (void)startReceivingNotifications { @@ -342,12 +366,14 @@ #pragma mark notification handlers - (void)handleAVCaptureSessionRuntimeError:(NSNotification*)notification { + __weak CameraController* weakSelf = self; dispatch_async(_sessionQueue, ^{ - [self setCameraState:qr_scanner::CAMERA_UNAVAILABLE]; + [weakSelf setCameraState:qr_scanner::CAMERA_UNAVAILABLE]; }); } - (void)handleAVCaptureSessionWasInterrupted:(NSNotification*)notification { + __weak CameraController* weakSelf = self; dispatch_async(_sessionQueue, ^{ AVCaptureSessionInterruptionReason reason = (AVCaptureSessionInterruptionReason)[[[notification userInfo] @@ -358,13 +384,15 @@ // is backgrounded and foregrounded. break; case AVCaptureSessionInterruptionReasonVideoDeviceInUseByAnotherClient: - [self setCameraState:qr_scanner::CAMERA_IN_USE_BY_ANOTHER_APPLICATION]; + [weakSelf + setCameraState:qr_scanner::CAMERA_IN_USE_BY_ANOTHER_APPLICATION]; break; case AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableWithMultipleForegroundApps: - [self setCameraState:qr_scanner::MULTIPLE_FOREGROUND_APPS]; + [weakSelf setCameraState:qr_scanner::MULTIPLE_FOREGROUND_APPS]; break; case AVCaptureSessionInterruptionReasonVideoDeviceNotAvailableDueToSystemPressure: - [self setCameraState:qr_scanner::CAMERA_UNAVAILABLE_DUE_TO_SYSTEM_PRESSURE]; + [weakSelf setCameraState:qr_scanner:: + CAMERA_UNAVAILABLE_DUE_TO_SYSTEM_PRESSURE]; break; case AVCaptureSessionInterruptionReasonAudioDeviceInUseByAnotherClient: NOTREACHED(); @@ -374,16 +402,19 @@ } - (void)handleAVCaptureSessionInterruptionEnded:(NSNotification*)notification { + __weak CameraController* weakSelf = self; dispatch_async(_sessionQueue, ^{ - if ([_captureSession isRunning]) { - [self setCameraState:qr_scanner::CAMERA_AVAILABLE]; + CameraController* strongSelf = weakSelf; + if (strongSelf && [strongSelf.captureSession isRunning]) { + [strongSelf setCameraState:qr_scanner::CAMERA_AVAILABLE]; } }); } - (void)handleAVCaptureDeviceWasDisconnected:(NSNotification*)notification { + __weak CameraController* weakSelf = self; dispatch_async(_sessionQueue, ^{ - [self setCameraState:qr_scanner::CAMERA_UNAVAILABLE]; + [weakSelf setCameraState:qr_scanner::CAMERA_UNAVAILABLE]; }); } @@ -402,45 +433,36 @@ #pragma mark property implementation -- (qr_scanner::CameraState)cameraState { - return _cameraState; -} - - (void)setCameraState:(qr_scanner::CameraState)state { if (state == _cameraState) { return; } _cameraState = state; + __weak CameraController* weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ - [_delegate cameraStateChanged:state]; + [weakSelf.delegate cameraStateChanged:state]; }); } -- (BOOL)isTorchAvailable { - return _torchAvailable; -} - - (void)setTorchAvailable:(BOOL)available { if (available == _torchAvailable) { return; } _torchAvailable = available; + __weak CameraController* weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ - [_delegate torchAvailabilityChanged:available]; + [weakSelf.delegate torchAvailabilityChanged:available]; }); } -- (BOOL)isTorchActive { - return _torchActive; -} - - (void)setTorchActive:(BOOL)active { if (active == _torchActive) { return; } _torchActive = active; + __weak CameraController* weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ - [_delegate torchStateChanged:active]; + [weakSelf.delegate torchStateChanged:active]; }); } @@ -460,10 +482,11 @@ if (resultString.length == 0) { return; } - + __weak CameraController* weakSelf = self; dispatch_async(_sessionQueue, ^{ - if ([_captureSession isRunning]) { - [_captureSession stopRunning]; + CameraController* strongSelf = weakSelf; + if (strongSelf && [strongSelf.captureSession isRunning]) { + [strongSelf.captureSession stopRunning]; } });
diff --git a/ios/chrome/browser/ui/safe_mode/safe_mode_view_controller.mm b/ios/chrome/browser/ui/safe_mode/safe_mode_view_controller.mm index 22dbd77c..75a2d7d5 100644 --- a/ios/chrome/browser/ui/safe_mode/safe_mode_view_controller.mm +++ b/ios/chrome/browser/ui/safe_mode/safe_mode_view_controller.mm
@@ -79,7 +79,7 @@ // If uploading is enabled and more than one report has stacked up, then we // assume that the app may be in a state that is preventing crash report // uploads before crashing again. - return breakpad_helper::IsUploadingEnabled() && + return breakpad_helper::UserEnabledUploading() && breakpad_helper::GetCrashReportCount() > 1; }
diff --git a/ios/chrome/browser/ui/safe_mode/safe_mode_view_controller_unittest.mm b/ios/chrome/browser/ui/safe_mode/safe_mode_view_controller_unittest.mm index bd68e5e0..44bf68b 100644 --- a/ios/chrome/browser/ui/safe_mode/safe_mode_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/safe_mode/safe_mode_view_controller_unittest.mm
@@ -54,12 +54,13 @@ }; // Verify that +[SafeModeViewController hasSuggestions] returns YES if and only -// if crash reporter and crash report uploading are enabled and there are -// multiple crash reports to upload. +// if crash reporting is enabled by the user and there are multiple crash +// reports to upload. +[SafeModeViewController hasSuggestions] does not depend +// on the value of breakpad_helper::IsEnabled or +// breakpad_helper::IsUploadingEnabled. TEST_F(SafeModeViewControllerTest, HasSuggestions) { // Test when crash reporter is disabled. - breakpad_helper::SetEnabled(false); - EXPECT_OCMOCK_VERIFY(mock_breakpad_controller_); + breakpad_helper::SetUserEnabledUploading(false); EXPECT_FALSE([SafeModeViewController hasSuggestions]); breakpad_helper::SetUploadingEnabled(false); @@ -85,15 +86,29 @@ EXPECT_FALSE([SafeModeViewController hasSuggestions]); // Test when crash reporter is enabled. + breakpad_helper::SetUserEnabledUploading(true); + EXPECT_OCMOCK_VERIFY(mock_breakpad_controller_); + [mock_breakpad_controller_ cr_expectGetCrashReportCount:0]; + EXPECT_FALSE([SafeModeViewController hasSuggestions]); + EXPECT_OCMOCK_VERIFY(mock_breakpad_controller_); + + [mock_breakpad_controller_ cr_expectGetCrashReportCount:kCrashReportCount]; + EXPECT_TRUE([SafeModeViewController hasSuggestions]); + EXPECT_OCMOCK_VERIFY(mock_breakpad_controller_); + [[mock_breakpad_controller_ expect] start:NO]; breakpad_helper::SetEnabled(true); - EXPECT_OCMOCK_VERIFY(mock_breakpad_controller_); - EXPECT_FALSE([SafeModeViewController hasSuggestions]); [[mock_breakpad_controller_ expect] setUploadingEnabled:NO]; breakpad_helper::SetUploadingEnabled(false); EXPECT_OCMOCK_VERIFY(mock_breakpad_controller_); + [mock_breakpad_controller_ cr_expectGetCrashReportCount:0]; EXPECT_FALSE([SafeModeViewController hasSuggestions]); + EXPECT_OCMOCK_VERIFY(mock_breakpad_controller_); + + [mock_breakpad_controller_ cr_expectGetCrashReportCount:kCrashReportCount]; + EXPECT_TRUE([SafeModeViewController hasSuggestions]); + EXPECT_OCMOCK_VERIFY(mock_breakpad_controller_); // Test when crash reporter and crash report uploading are enabled. [[mock_breakpad_controller_ expect] setUploadingEnabled:YES];
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_adaptor.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_adaptor.mm index 509646d..0076dfd 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_adaptor.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_adaptor.mm
@@ -8,6 +8,7 @@ #import "ios/chrome/browser/tabs/tab_model.h" #import "ios/chrome/browser/ui/main/view_controller_swapping.h" #import "ios/chrome/browser/ui/tab_grid/tab_grid_paging.h" +#import "ios/chrome/browser/url_loading/url_loading_params.h" #import "ios/web/public/navigation_manager.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -42,20 +43,14 @@ } - (Tab*)dismissWithNewTabAnimationToModel:(TabModel*)targetModel - withURL:(const GURL&)URL - virtualURL:(const GURL&)virtualURL - atIndex:(NSUInteger)position - transition:(ui::PageTransition)transition { + withUrlLoadParams:(const UrlLoadParams&)urlLoadParams + atIndex:(NSUInteger)position { NSUInteger tabIndex = position; if (position > targetModel.count) tabIndex = targetModel.count; - web::NavigationManager::WebLoadParams loadParams(URL); - loadParams.transition_type = transition; - loadParams.virtual_url = virtualURL; - // Create the new tab. - Tab* tab = [targetModel insertTabWithLoadParams:loadParams + Tab* tab = [targetModel insertTabWithLoadParams:urlLoadParams.web_params opener:nil openedByDOM:NO atIndex:tabIndex
diff --git a/ios/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc b/ios/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc index fca7ed97..95dc557 100644 --- a/ios/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc +++ b/ios/chrome/browser/ui/webui/sync_internals/sync_internals_message_handler.cc
@@ -197,7 +197,7 @@ syncer::SyncService* service = GetSyncService(); if (service) { - service->GetAllNodes( + service->GetAllNodesForDebugging( base::Bind(&SyncInternalsMessageHandler::OnReceivedAllNodes, weak_ptr_factory_.GetWeakPtr(), request_id)); }
diff --git a/ios/chrome/browser/url_loading/app_url_loading_service.h b/ios/chrome/browser/url_loading/app_url_loading_service.h index da48c4c..c2b2d540 100644 --- a/ios/chrome/browser/url_loading/app_url_loading_service.h +++ b/ios/chrome/browser/url_loading/app_url_loading_service.h
@@ -12,7 +12,6 @@ #include "ios/chrome/app/application_mode.h" #include "ui/base/page_transition_types.h" -class GURL; struct UrlLoadParams; @class Tab; @@ -40,9 +39,7 @@ // |completion| is executed after the tab is opened. After Tab is open the // virtual URL is set to the pending navigation item. - (Tab*)openSelectedTabInMode:(ApplicationMode)targetMode - withURL:(const GURL&)url - virtualURL:(const GURL&)virtualURL - transition:(ui::PageTransition)transition + withUrlLoadParams:(const UrlLoadParams&)urlLoadParams completion:(ProceduralBlock)completion; // Opens a new tab as if originating from |originPoint| and |focusOmnibox|.
diff --git a/ios/chrome/browser/url_loading/app_url_loading_service.mm b/ios/chrome/browser/url_loading/app_url_loading_service.mm index 2d75d44..d04cb3f 100644 --- a/ios/chrome/browser/url_loading/app_url_loading_service.mm +++ b/ios/chrome/browser/url_loading/app_url_loading_service.mm
@@ -29,14 +29,13 @@ if (params.web_params.url.is_valid()) { UrlLoadParams saved_params = params; + saved_params.web_params.transition_type = ui::PAGE_TRANSITION_TYPED; if (params.from_chrome) { [delegate_ dismissModalDialogsWithCompletion:^{ [delegate_ openSelectedTabInMode:ApplicationMode::NORMAL - withURL:saved_params.web_params.url - virtualURL:saved_params.web_params.virtual_url - transition:ui::PAGE_TRANSITION_TYPED + withUrlLoadParams:saved_params completion:nil]; } dismissOmnibox:YES];
diff --git a/ios/chrome/test/app/BUILD.gn b/ios/chrome/test/app/BUILD.gn index 0e70d94b..7ee64e3 100644 --- a/ios/chrome/test/app/BUILD.gn +++ b/ios/chrome/test/app/BUILD.gn
@@ -80,6 +80,7 @@ "//ios/chrome/browser/ui/tabs", "//ios/chrome/browser/ui/util", "//ios/chrome/browser/ui/util", + "//ios/chrome/browser/url_loading", "//ios/chrome/browser/web_state_list", "//ios/chrome/browser/web_state_list/web_usage_enabler", "//ios/public/provider/chrome/browser",
diff --git a/ios/chrome/test/app/tab_test_util.mm b/ios/chrome/test/app/tab_test_util.mm index cf015927..c8945d5 100644 --- a/ios/chrome/test/app/tab_test_util.mm +++ b/ios/chrome/test/app/tab_test_util.mm
@@ -16,6 +16,7 @@ #import "ios/chrome/browser/ui/commands/browser_commands.h" #import "ios/chrome/browser/ui/commands/open_new_tab_command.h" #import "ios/chrome/browser/ui/main/tab_switcher.h" +#import "ios/chrome/browser/url_loading/url_loading_params.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/browser/web_state_list/web_usage_enabler/web_state_list_web_usage_enabler.h" #import "ios/chrome/browser/web_state_list/web_usage_enabler/web_state_list_web_usage_enabler_factory.h" @@ -52,12 +53,11 @@ // The TabGrid is currently presented. TabModel* tabModel = GetMainController().interfaceProvider.mainInterface.tabModel; + UrlLoadParams params = UrlLoadParams::InNewTab(GURL(kChromeUINewTabURL)); [GetMainController().tabSwitcher dismissWithNewTabAnimationToModel:tabModel - withURL:GURL(kChromeUINewTabURL) - virtualURL:GURL::EmptyGURL() - atIndex:NSNotFound - transition:ui::PAGE_TRANSITION_TYPED]; + withUrlLoadParams:params + atIndex:NSNotFound]; } } @@ -73,12 +73,11 @@ // The TabGrid is currently presented. TabModel* tabModel = GetMainController().interfaceProvider.incognitoInterface.tabModel; + UrlLoadParams params = UrlLoadParams::InNewTab(GURL(kChromeUINewTabURL)); [GetMainController().tabSwitcher dismissWithNewTabAnimationToModel:tabModel - withURL:GURL(kChromeUINewTabURL) - virtualURL:GURL::EmptyGURL() - atIndex:NSNotFound - transition:ui::PAGE_TRANSITION_TYPED]; + withUrlLoadParams:params + atIndex:NSNotFound]; } }
diff --git a/ios/web/navigation/navigation_item_impl.mm b/ios/web/navigation/navigation_item_impl.mm index ad6ccd1e..0722101 100644 --- a/ios/web/navigation/navigation_item_impl.mm +++ b/ios/web/navigation/navigation_item_impl.mm
@@ -150,8 +150,9 @@ if (!cached_display_title_.empty()) return cached_display_title_; - cached_display_title_ = - NavigationItemImpl::GetDisplayTitleForURL(GetVirtualURL()); + // File urls have different display rules, so use one if it is present. + cached_display_title_ = NavigationItemImpl::GetDisplayTitleForURL( + GetURL().SchemeIsFile() ? GetURL() : GetVirtualURL()); return cached_display_title_; }
diff --git a/ios/web/navigation/navigation_item_impl_unittest.mm b/ios/web/navigation/navigation_item_impl_unittest.mm index e0129789..b70e27f 100644 --- a/ios/web/navigation/navigation_item_impl_unittest.mm +++ b/ios/web/navigation/navigation_item_impl_unittest.mm
@@ -175,5 +175,17 @@ EXPECT_EQ("1.gz", base::UTF16ToUTF8(title)); } +// Tests NavigationItemImpl::GetTitleForDisplay method +TEST_F(NavigationItemTest, GetTitleForDisplay) { + item_->SetURL(GURL("file://foo/test.pdf")); + item_->SetVirtualURL(GURL("testappspecific://foo/")); + EXPECT_EQ("test.pdf", base::UTF16ToUTF8(item_->GetTitleForDisplay())); + + item_->SetURL(GURL("testappspecific://foo/test.pdf")); + item_->SetVirtualURL(GURL("testappspecific://foo/test.pdf")); + EXPECT_EQ("testappspecific://foo/test.pdf", + base::UTF16ToUTF8(item_->GetTitleForDisplay())); +} + } // namespace } // namespace web
diff --git a/ios/web/navigation/navigation_manager_impl.mm b/ios/web/navigation/navigation_manager_impl.mm index dd2911b..1e79b66 100644 --- a/ios/web/navigation/navigation_manager_impl.mm +++ b/ios/web/navigation/navigation_manager_impl.mm
@@ -31,6 +31,7 @@ NavigationManager::WebLoadParams::WebLoadParams(const WebLoadParams& other) : url(other.url), + virtual_url(other.virtual_url), referrer(other.referrer), transition_type(other.transition_type), user_agent_override_option(other.user_agent_override_option), @@ -41,6 +42,7 @@ NavigationManager::WebLoadParams& NavigationManager::WebLoadParams::operator=( const WebLoadParams& other) { url = other.url; + virtual_url = other.virtual_url; referrer = other.referrer; is_renderer_initiated = other.is_renderer_initiated; transition_type = other.transition_type;
diff --git a/ios/web/navigation/wk_based_navigation_manager_impl.mm b/ios/web/navigation/wk_based_navigation_manager_impl.mm index 3b68986..27df334 100644 --- a/ios/web/navigation/wk_based_navigation_manager_impl.mm +++ b/ios/web/navigation/wk_based_navigation_manager_impl.mm
@@ -663,6 +663,7 @@ void WKBasedNavigationManagerImpl::LoadIfNecessary() { if (!web_view_cache_.IsAttachedToWebView()) { // Loading from detached mode is equivalent to restoring cached history. + // This can happen after clearing browsing data by removing the web view. Restore(web_view_cache_.GetCurrentItemIndex(), web_view_cache_.ReleaseCachedItems()); DCHECK(web_view_cache_.IsAttachedToWebView()); @@ -817,6 +818,13 @@ for (size_t index = 0; index < GetBackForwardListItemCount(); index++) { cached_items_[index].reset(new NavigationItemImpl( *GetNavigationItemImplAtIndex(index, true /* create_if_missing */))); + // Don't put restore URL's into |cached_items|, extract them first. + GURL url = cached_items_[index]->GetURL(); + if (wk_navigation_util::IsRestoreSessionUrl(url)) { + GURL extracted_url; + if (wk_navigation_util::ExtractTargetURL(url, &extracted_url)) + cached_items_[index]->SetURL(extracted_url); + } } } attached_to_web_view_ = false;
diff --git a/ios/web/navigation/wk_based_navigation_manager_impl_unittest.mm b/ios/web/navigation/wk_based_navigation_manager_impl_unittest.mm index 2a7e9200..d199983 100644 --- a/ios/web/navigation/wk_based_navigation_manager_impl_unittest.mm +++ b/ios/web/navigation/wk_based_navigation_manager_impl_unittest.mm
@@ -858,6 +858,11 @@ ASSERT_EQ(url2_, manager_->GetItemAtIndex(2)->GetURL()); } + NSString* CreateRedirectUrlForWKList(GURL url) { + GURL redirect_url = wk_navigation_util::CreateRedirectUrl(url); + return base::SysUTF8ToNSString(redirect_url.spec()); + } + GURL url0_; GURL url1_; GURL url2_; @@ -1002,4 +1007,16 @@ histogram_tester_.ExpectBucketCount(kRestoreNavigationItemCount, 3, 1); } +// Tests that detaching placeholder urls are cleaned before being cached. +TEST_F(WKBasedNavigationManagerDetachedModeTest, CachedPlaceholders) { + [mock_wk_list_ setCurrentURL:CreateRedirectUrlForWKList(url1_) + backListURLs:@[ CreateRedirectUrlForWKList(url0_) ] + forwardListURLs:@[ CreateRedirectUrlForWKList(url2_) ]]; + manager_->DetachFromWebView(); + + EXPECT_EQ(url0_, manager_->GetNavigationItemImplAtIndex(0)->GetURL()); + EXPECT_EQ(url1_, manager_->GetNavigationItemImplAtIndex(1)->GetURL()); + EXPECT_EQ(url2_, manager_->GetNavigationItemImplAtIndex(2)->GetURL()); +} + } // namespace web
diff --git a/ios/web/web_state/error_page_inttest.mm b/ios/web/web_state/error_page_inttest.mm index e42f4a7..1a4aace 100644 --- a/ios/web/web_state/error_page_inttest.mm +++ b/ios/web/web_state/error_page_inttest.mm
@@ -134,7 +134,7 @@ // Tests that the error page is correctly displayed after navigating back to it // multiple times. See http://crbug.com/944037 . -TEST_P(ErrorPageTest, BackForwardErrorPage) { +TEST_P(ErrorPageTest, FLAKY_BackForwardErrorPage) { test::LoadUrl(web_state(), server_.GetURL("/close-socket")); ASSERT_TRUE(WaitForErrorText(web_state(), server_.GetURL("/close-socket")));
diff --git a/ios/web/web_state/web_state_observer_inttest.mm b/ios/web/web_state/web_state_observer_inttest.mm index 54f34d0..f8194a3 100644 --- a/ios/web/web_state/web_state_observer_inttest.mm +++ b/ios/web/web_state/web_state_observer_inttest.mm
@@ -2034,7 +2034,7 @@ } // Tests failed load after the navigation is sucessfully finished. -TEST_P(WebStateObserverTest, FailedLoad) { +TEST_P(WebStateObserverTest, FLAKY_FailedLoad) { GURL url = test_server_->GetURL("/exabyte_response"); NavigationContext* context = nullptr;
diff --git a/media/gpu/test/video_player/test_vda_video_decoder.cc b/media/gpu/test/video_player/test_vda_video_decoder.cc index 45566062..c39cac31 100644 --- a/media/gpu/test/video_player/test_vda_video_decoder.cc +++ b/media/gpu/test/video_player/test_vda_video_decoder.cc
@@ -27,6 +27,11 @@ namespace media { namespace test { +namespace { +// Size of the timestamp cache, needs to be large enough for frame-reordering. +constexpr size_t kTimestampCacheSize = 128; +} // namespace + TestVDAVideoDecoder::TestVDAVideoDecoder( AllocationMode allocation_mode, const gfx::ColorSpace& target_color_space, @@ -36,6 +41,7 @@ : VideoDecodeAccelerator::Config::OutputMode::IMPORT), target_color_space_(target_color_space), frame_renderer_(frame_renderer), + decode_start_timestamps_(kTimestampCacheSize), weak_this_factory_(this) { DETACH_FROM_SEQUENCE(vda_wrapper_sequence_checker_); @@ -137,6 +143,13 @@ int32_t bitstream_buffer_id = GetNextBitstreamBufferId(); decode_cbs_[bitstream_buffer_id] = decode_cb; + // Record picture buffer decode start time. A cache is used because not each + // bitstream buffer decode will result in a call to PictureReady(). Pictures + // can be delivered in a different order than the decode operations, so we + // don't know when it's safe to purge old decode timestamps. Instead we use + // a cache with a large enough size to account for frame reordering. + decode_start_timestamps_.Put(bitstream_buffer_id, buffer->timestamp()); + decoder_->Decode(std::move(buffer), bitstream_buffer_id); } @@ -242,6 +255,12 @@ LOG_ASSERT(it != video_frames_.end()); scoped_refptr<VideoFrame> video_frame = it->second; + // Look up the time at which the decode started. + auto timestamp_it = + decode_start_timestamps_.Peek(picture.bitstream_buffer_id()); + ASSERT_NE(timestamp_it, decode_start_timestamps_.end()); + video_frame->set_timestamp(timestamp_it->second); + // When using import mode, we wrap the video frame in another video frame that // calls ReusePictureBufferTask() upon destruction. When the renderer and // video frame processors are done using the video frame, the associated
diff --git a/media/gpu/test/video_player/test_vda_video_decoder.h b/media/gpu/test/video_player/test_vda_video_decoder.h index ba4aa930..d6af363 100644 --- a/media/gpu/test/video_player/test_vda_video_decoder.h +++ b/media/gpu/test/video_player/test_vda_video_decoder.h
@@ -10,6 +10,7 @@ #include <memory> #include <string> +#include "base/containers/mru_cache.h" #include "base/macros.h" #include "base/sequence_checker.h" #include "media/base/video_decoder.h" @@ -94,8 +95,10 @@ // Map of video frames the decoder uses as output, keyed on picture buffer id. std::map<int32_t, scoped_refptr<VideoFrame>> video_frames_; - // Map of video frame decoded callbacks, keyed on picture buffer id. + // Map of video frame decoded callbacks, keyed on bitstream buffer id. std::map<int32_t, DecodeCB> decode_cbs_; + // Records the time at which each bitstream buffer decode operation started. + base::MRUCache<int32_t, base::TimeDelta> decode_start_timestamps_; int32_t next_bitstream_buffer_id_ = 0; int32_t next_picture_buffer_id_ = 0;
diff --git a/media/gpu/test/video_player/video_decoder_client.cc b/media/gpu/test/video_player/video_decoder_client.cc index c894f02..2be4ca0 100644 --- a/media/gpu/test/video_player/video_decoder_client.cc +++ b/media/gpu/test/video_player/video_decoder_client.cc
@@ -234,6 +234,7 @@ scoped_refptr<DecoderBuffer> bitstream_buffer = DecoderBuffer::CopyFrom( reinterpret_cast<const uint8_t*>(fragment_bytes.data()), fragment_size); + bitstream_buffer->set_timestamp(base::TimeTicks::Now().since_origin()); VideoDecoder::DecodeCB decode_cb = BindToCurrentLoop( base::BindRepeating(&VideoDecoderClient::DecodeDoneTask, weak_this_));
diff --git a/media/gpu/video_decode_accelerator_perf_tests.cc b/media/gpu/video_decode_accelerator_perf_tests.cc index 3b10ab6c..27f3559 100644 --- a/media/gpu/video_decode_accelerator_perf_tests.cc +++ b/media/gpu/video_decode_accelerator_perf_tests.cc
@@ -59,8 +59,10 @@ size_t frame_decoded_count_ = 0; // The overall number of frames decoded per second. double frames_per_second_ = 0.0; - // The average time it took to decode a frame. - double avg_frame_decode_time_ms_ = 0.0; + // The average time between subsequent frame deliveries. + double avg_frame_delivery_time_ms_ = 0.0; + // The median time between decode start and frame delivery. + double median_frame_decode_time_ms_ = 0.0; }; // The performance evaluator can be plugged into the video player to collect @@ -85,11 +87,14 @@ // Start/end time of the measurement period. base::TimeTicks start_time_; base::TimeTicks end_time_; - // Time at which the previous frame was decoded. - base::TimeTicks prev_frame_decoded_time_; - // List of all frame decode times. + // Time at which the previous frame was delivered. + base::TimeTicks prev_frame_delivery_time_; + // List of times between subsequent frame deliveries. + std::vector<double> frame_delivery_times_; + // List of times between decode start and frame delivery. std::vector<double> frame_decode_times_; + // Collection of various performance metrics. PerformanceMetrics perf_metrics_; }; @@ -98,15 +103,20 @@ scoped_refptr<const VideoFrame> video_frame, size_t frame_index) { base::TimeTicks now = base::TimeTicks::Now(); - frame_decode_times_.push_back( - (now - prev_frame_decoded_time_).InMillisecondsF()); - prev_frame_decoded_time_ = now; + + base::TimeDelta delivery_time = (now - prev_frame_delivery_time_); + frame_delivery_times_.push_back(delivery_time.InMillisecondsF()); + prev_frame_delivery_time_ = now; + + base::TimeDelta decode_time = now.since_origin() - video_frame->timestamp(); + frame_decode_times_.push_back(decode_time.InMillisecondsF()); + perf_metrics_.frame_decoded_count_++; } void PerformanceEvaluator::StartMeasuring() { start_time_ = base::TimeTicks::Now(); - prev_frame_decoded_time_ = start_time_; + prev_frame_delivery_time_ = start_time_; } void PerformanceEvaluator::StopMeasuring() { @@ -114,26 +124,39 @@ perf_metrics_.total_duration_ = end_time_ - start_time_; perf_metrics_.frames_per_second_ = perf_metrics_.frame_decoded_count_ / perf_metrics_.total_duration_.InSecondsF(); - perf_metrics_.avg_frame_decode_time_ms_ = + + perf_metrics_.avg_frame_delivery_time_ms_ = perf_metrics_.total_duration_.InMillisecondsF() / perf_metrics_.frame_decoded_count_; + std::sort(frame_decode_times_.begin(), frame_decode_times_.end()); + size_t median_index = frame_decode_times_.size() / 2; + perf_metrics_.median_frame_decode_time_ms_ = + (frame_decode_times_.size() % 2 != 0) + ? frame_decode_times_[median_index] + : (frame_decode_times_[median_index - 1] + + frame_decode_times_[median_index]) / + 2.0; + VLOG(0) << "Number of frames decoded: " << perf_metrics_.frame_decoded_count_; VLOG(0) << "Total duration: " << perf_metrics_.total_duration_.InMillisecondsF() << "ms"; VLOG(0) << "FPS: " << perf_metrics_.frames_per_second_; - VLOG(0) << "Avg. frame decode time: " - << perf_metrics_.avg_frame_decode_time_ms_ << "ms"; + VLOG(0) << "Avg. frame delivery time: " + << perf_metrics_.avg_frame_delivery_time_ms_ << "ms"; + VLOG(0) << "Median frame decode time: " + << perf_metrics_.median_frame_decode_time_ms_ << "ms"; } void PerformanceEvaluator::WriteMetricsToFile() const { std::string str = base::StringPrintf( "Number of frames decoded: %zu\nTotal duration: %fms\nFPS: %f\nAvg. " - "frame decode time: %fms\n", + "frame delivery time: %fms\nMedian frame decode time: %fms\n", perf_metrics_.frame_decoded_count_, perf_metrics_.total_duration_.InMillisecondsF(), perf_metrics_.frames_per_second_, - perf_metrics_.avg_frame_decode_time_ms_); + perf_metrics_.avg_frame_delivery_time_ms_, + perf_metrics_.median_frame_decode_time_ms_); // Write performance metrics to file. base::FilePath output_folder_path = base::FilePath(kDefaultOutputFolder); @@ -154,7 +177,7 @@ base::File decode_times_output_file( base::FilePath(decode_times_file_path), base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); - for (double frame_decoded_time : frame_decode_times_) { + for (double frame_decoded_time : frame_delivery_times_) { std::string decode_time_str = base::StringPrintf("%f\n", frame_decoded_time); decode_times_output_file.WriteAtCurrentPos(decode_time_str.data(),
diff --git a/mojo/public/cpp/system/platform_handle.cc b/mojo/public/cpp/system/platform_handle.cc index 9e55f550..f00df808 100644 --- a/mojo/public/cpp/system/platform_handle.cc +++ b/mojo/public/cpp/system/platform_handle.cc
@@ -33,6 +33,8 @@ #endif } +} // namespace + ScopedSharedBufferHandle WrapPlatformSharedMemoryRegion( base::subtle::PlatformSharedMemoryRegion region) { if (!region.IsValid()) @@ -177,8 +179,6 @@ base::UnguessableToken::Deserialize(mojo_guid.high, mojo_guid.low)); } -} // namespace - ScopedHandle WrapPlatformHandle(PlatformHandle handle) { MojoPlatformHandle platform_handle; PlatformHandle::ToMojoPlatformHandle(std::move(handle), &platform_handle);
diff --git a/mojo/public/cpp/system/platform_handle.h b/mojo/public/cpp/system/platform_handle.h index b18ceaf..5134275 100644 --- a/mojo/public/cpp/system/platform_handle.h +++ b/mojo/public/cpp/system/platform_handle.h
@@ -76,6 +76,14 @@ kReadOnly, }; +// Wraps and unwraps base::subtle::PlatformSharedMemoryRegions. This should be +// used only while transitioning from the legacy shared memory API. In new code +// only base::*SharedMemoryRegion should be used instead. +ScopedSharedBufferHandle WrapPlatformSharedMemoryRegion( + base::subtle::PlatformSharedMemoryRegion region); +base::subtle::PlatformSharedMemoryRegion UnwrapPlatformSharedMemoryRegion( + ScopedSharedBufferHandle mojo_handle); + // Wraps a PlatformHandle from the C++ platform support library as a Mojo // handle. MOJO_CPP_SYSTEM_EXPORT ScopedHandle WrapPlatformHandle(PlatformHandle handle);
diff --git a/net/cookies/canonical_cookie.cc b/net/cookies/canonical_cookie.cc index aec043d3..63c98e3b8 100644 --- a/net/cookies/canonical_cookie.cc +++ b/net/cookies/canonical_cookie.cc
@@ -203,13 +203,14 @@ ParsedCookie parsed_cookie(cookie_line); if (!parsed_cookie.IsValid()) { - VLOG(net::cookie_util::kVlogSetCookies) << "WARNING: Couldn't parse cookie"; + DVLOG(net::cookie_util::kVlogSetCookies) + << "WARNING: Couldn't parse cookie"; *status = CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE; return nullptr; } if (options.exclude_httponly() && parsed_cookie.IsHttpOnly()) { - VLOG(net::cookie_util::kVlogSetCookies) + DVLOG(net::cookie_util::kVlogSetCookies) << "Create() is not creating a httponly cookie"; *status = CookieInclusionStatus::EXCLUDE_HTTP_ONLY; return nullptr; @@ -217,7 +218,7 @@ std::string cookie_domain; if (!GetCookieDomain(url, parsed_cookie, &cookie_domain)) { - VLOG(net::cookie_util::kVlogSetCookies) + DVLOG(net::cookie_util::kVlogSetCookies) << "Create() failed to get a cookie domain"; *status = CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN; return nullptr; @@ -228,7 +229,7 @@ // URL does not have a secure scheme, the cookie should be thrown away. // https://tools.ietf.org/html/draft-ietf-httpbis-cookie-alone if (parsed_cookie.IsSecure() && !url.SchemeIsCryptographic()) { - VLOG(net::cookie_util::kVlogSetCookies) + DVLOG(net::cookie_util::kVlogSetCookies) << "Create() is trying to create a secure cookie from an insecure URL"; *status = CookieInclusionStatus::EXCLUDE_SECURE_ONLY; return nullptr; @@ -250,7 +251,7 @@ bool is_cookie_valid = IsCookiePrefixValid(prefix, url, parsed_cookie); RecordCookiePrefixMetrics(prefix, is_cookie_valid); if (!is_cookie_valid) { - VLOG(net::cookie_util::kVlogSetCookies) + DVLOG(net::cookie_util::kVlogSetCookies) << "Create() failed because the cookie violated prefix rules."; *status = CookieInclusionStatus::EXCLUDE_INVALID_PREFIX; return nullptr;
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc index e77e478..6fefab00 100644 --- a/net/cookies/cookie_monster.cc +++ b/net/cookies/cookie_monster.cc
@@ -689,7 +689,7 @@ return; } - VLOG(net::cookie_util::kVlogSetCookies) + DVLOG(net::cookie_util::kVlogSetCookies) << "SetCookie() line: " << cookie_line; CanonicalCookie::CookieInclusionStatus status; @@ -699,7 +699,7 @@ if (status != CanonicalCookie::CookieInclusionStatus::INCLUDE) { DCHECK(!cc); - VLOG(net::cookie_util::kVlogSetCookies) + DVLOG(net::cookie_util::kVlogSetCookies) << "WARNING: Failed to allocate CanonicalCookie"; MaybeRunCookieCallback(std::move(callback), status); return; @@ -1228,12 +1228,12 @@ "SetCookie() not clobbering httponly cookie or secure cookie for " "insecure scheme"; - VLOG(net::cookie_util::kVlogSetCookies) << error; + DVLOG(net::cookie_util::kVlogSetCookies) << error; MaybeRunCookieCallback(std::move(callback), status); return; } - VLOG(net::cookie_util::kVlogSetCookies) + DVLOG(net::cookie_util::kVlogSetCookies) << "SetCookie() key: " << key << " cc: " << cc->DebugString(); // Realize that we might be setting an expired cookie, and the only point @@ -1266,7 +1266,7 @@ InternalInsertCookie(key, std::move(cc), true); } else { - VLOG(net::cookie_util::kVlogSetCookies) + DVLOG(net::cookie_util::kVlogSetCookies) << "SetCookie() not storing already expired cookie."; } @@ -1345,7 +1345,7 @@ "kChangeCauseMapping size should match DeletionCause size"); CanonicalCookie* cc = it->second.get(); - VLOG(net::cookie_util::kVlogSetCookies) + DVLOG(net::cookie_util::kVlogSetCookies) << "InternalDeleteCookie()" << ", cause:" << deletion_cause << ", cc: " << cc->DebugString(); @@ -1375,7 +1375,7 @@ // Collect garbage for this key, minding cookie priorities. if (cookies_.count(key) > kDomainMaxCookies) { - VLOG(net::cookie_util::kVlogGarbageCollection) + DVLOG(net::cookie_util::kVlogGarbageCollection) << "GarbageCollect() key: " << key; CookieItVector* cookie_its; @@ -1386,7 +1386,7 @@ GarbageCollectExpired(current, cookies_.equal_range(key), cookie_its); if (cookie_its->size() > kDomainMaxCookies) { - VLOG(net::cookie_util::kVlogGarbageCollection) + DVLOG(net::cookie_util::kVlogGarbageCollection) << "Deep Garbage Collect domain."; size_t purge_goal = cookie_its->size() - (kDomainMaxCookies - kDomainPurgeCookies); @@ -1465,7 +1465,7 @@ // Collect garbage for everything. With firefox style we want to preserve // cookies accessed in kSafeFromGlobalPurgeDays, otherwise evict. if (cookies_.size() > kMaxCookies && earliest_access_time_ < safe_date) { - VLOG(net::cookie_util::kVlogGarbageCollection) + DVLOG(net::cookie_util::kVlogGarbageCollection) << "GarbageCollect() everything"; CookieItVector cookie_its; @@ -1474,7 +1474,7 @@ &cookie_its); if (cookie_its.size() > kMaxCookies) { - VLOG(net::cookie_util::kVlogGarbageCollection) + DVLOG(net::cookie_util::kVlogGarbageCollection) << "Deep Garbage Collect everything."; size_t purge_goal = cookie_its.size() - (kMaxCookies - kPurgeCookies); DCHECK(purge_goal > kPurgeCookies); @@ -1691,7 +1691,7 @@ } // The scheme didn't match any in our whitelist. - VLOG(net::cookie_util::kVlogPerCookieMonster) + DVLOG(net::cookie_util::kVlogPerCookieMonster) << "WARNING: Unsupported cookie scheme: " << url.scheme(); return false; }
diff --git a/net/cookies/parsed_cookie.cc b/net/cookies/parsed_cookie.cc index d5bc286..d8e6d621 100644 --- a/net/cookies/parsed_cookie.cc +++ b/net/cookies/parsed_cookie.cc
@@ -138,7 +138,7 @@ same_site_index_(0), priority_index_(0) { if (cookie_line.size() > kMaxCookieSize) { - VLOG(1) << "Not parsing cookie, too large: " << cookie_line.size(); + DVLOG(1) << "Not parsing cookie, too large: " << cookie_line.size(); return; }
diff --git a/net/quic/quic_flags_list.h b/net/quic/quic_flags_list.h index 2516f6a9..f739eb5 100644 --- a/net/quic/quic_flags_list.h +++ b/net/quic/quic_flags_list.h
@@ -325,3 +325,6 @@ QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_ignore_tlpr_if_sending_ping, true) + +// If true, non-ASCII QUIC tags are printed as hex instead of integers." +QUIC_FLAG(bool, FLAGS_quic_reloadable_flag_quic_print_tag_hex, false)
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc index 2570dfe..aaefe03 100644 --- a/net/spdy/spdy_network_transaction_unittest.cc +++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -7817,6 +7817,129 @@ /* expected_count = */ 1); } +// Make sure that a WebSocket job doesn't pick up a newly created SpdySession +// that doesn't support WebSockets through +// HttpStreamFactory::Job::OnSpdySessionAvailable(). +TEST_F(SpdyNetworkTransactionTest, + WebSocketDoesUseNewH2SessionWithoutWebSocketSupport) { + base::HistogramTester histogram_tester; + auto session_deps = std::make_unique<SpdySessionDependencies>(); + session_deps->enable_websocket_over_http2 = true; + NormalSpdyTransactionHelper helper(request_, HIGHEST, log_, + std::move(session_deps)); + helper.RunPreTestSetup(); + + spdy::SpdySerializedFrame req( + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST)); + + MockWrite writes[] = {CreateMockWrite(req, 0)}; + + spdy::SpdySerializedFrame resp1( + spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); + spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true)); + MockRead reads[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2), + MockRead(SYNCHRONOUS, ERR_IO_PENDING, 3)}; + + SequencedSocketData data( + // Just as with other operations, this means to pause during connection + // establishment. + MockConnect(ASYNC, ERR_IO_PENDING), reads, writes); + helper.AddData(&data); + + MockWrite writes2[] = { + MockWrite(SYNCHRONOUS, 0, + "GET / HTTP/1.1\r\n" + "Host: www.example.org\r\n" + "Connection: Upgrade\r\n" + "Upgrade: websocket\r\n" + "Origin: http://www.example.org\r\n" + "Sec-WebSocket-Version: 13\r\n" + "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" + "Sec-WebSocket-Extensions: permessage-deflate; " + "client_max_window_bits\r\n\r\n")}; + + MockRead reads2[] = { + MockRead(SYNCHRONOUS, 1, + "HTTP/1.1 101 Switching Protocols\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n" + "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n\r\n")}; + SequencedSocketData data2(MockConnect(ASYNC, ERR_IO_PENDING), reads2, + writes2); + auto ssl_provider2 = std::make_unique<SSLSocketDataProvider>(ASYNC, OK); + // Test that request has empty |alpn_protos|, that is, HTTP/2 is disabled. + ssl_provider2->next_protos_expected_in_ssl_config = NextProtoVector{}; + // Force socket to use HTTP/1.1, the default protocol without ALPN. + ssl_provider2->next_proto = kProtoHTTP11; + // ssl_provider2->ssl_info.cert = + // ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"); + helper.AddDataWithSSLSocketDataProvider(&data2, std::move(ssl_provider2)); + + TestCompletionCallback callback1; + int rv = helper.trans()->Start(&request_, callback1.callback(), log_); + ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); + + // Create HTTP/2 connection. + base::RunLoop().RunUntilIdle(); + + HttpRequestInfo request2; + request2.method = "GET"; + request2.url = GURL("wss://www.example.org/"); + request2.traffic_annotation = + net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS); + EXPECT_TRUE(HostPortPair::FromURL(request_.url) + .Equals(HostPortPair::FromURL(request2.url))); + request2.extra_headers.SetHeader("Connection", "Upgrade"); + request2.extra_headers.SetHeader("Upgrade", "websocket"); + request2.extra_headers.SetHeader("Origin", "http://www.example.org"); + request2.extra_headers.SetHeader("Sec-WebSocket-Version", "13"); + + TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper; + + HttpNetworkTransaction trans2(MEDIUM, helper.session()); + trans2.SetWebSocketHandshakeStreamCreateHelper( + &websocket_stream_create_helper); + + TestCompletionCallback callback2; + rv = trans2.Start(&request2, callback2.callback(), log_); + ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); + + // Run until waiting on both connections. + base::RunLoop().RunUntilIdle(); + + // The H2 connection completes. + data.socket()->OnConnectComplete(MockConnect(SYNCHRONOUS, OK)); + EXPECT_EQ(OK, callback1.WaitForResult()); + const HttpResponseInfo* response = helper.trans()->GetResponseInfo(); + ASSERT_TRUE(response->headers); + EXPECT_TRUE(response->was_fetched_via_spdy); + EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine()); + std::string response_data; + rv = ReadTransaction(helper.trans(), &response_data); + EXPECT_THAT(rv, IsOk()); + EXPECT_EQ("hello!", response_data); + + SpdySessionKey key(HostPortPair::FromURL(request_.url), ProxyServer::Direct(), + PRIVACY_MODE_DISABLED, + SpdySessionKey::IsProxySession::kFalse, SocketTag()); + + base::WeakPtr<SpdySession> spdy_session = + helper.session()->spdy_session_pool()->FindAvailableSession( + key, /* enable_ip_based_pooling = */ true, + /* is_websocket = */ false, log_); + ASSERT_TRUE(spdy_session); + EXPECT_FALSE(spdy_session->support_websocket()); + + EXPECT_FALSE(callback2.have_result()); + + // Create WebSocket stream. + data2.socket()->OnConnectComplete(MockConnect(SYNCHRONOUS, OK)); + + rv = callback2.WaitForResult(); + ASSERT_THAT(rv, IsOk()); + helper.VerifyDataConsumed(); +} + TEST_F(SpdyNetworkTransactionTest, WebSocketOverHTTP2) { base::HistogramTester histogram_tester; auto session_deps = std::make_unique<SpdySessionDependencies>();
diff --git a/net/spdy/spdy_session_pool.cc b/net/spdy/spdy_session_pool.cc index 1fa0c7a..f12fc4c2 100644 --- a/net/spdy/spdy_session_pool.cc +++ b/net/spdy/spdy_session_pool.cc
@@ -54,9 +54,13 @@ SpdySessionPool::SpdySessionRequest::SpdySessionRequest( const SpdySessionKey& key, + bool is_websocket, Delegate* delegate, SpdySessionPool* spdy_session_pool) - : key_(key), delegate_(delegate), spdy_session_pool_(spdy_session_pool) {} + : key_(key), + is_websocket_(is_websocket), + delegate_(delegate), + spdy_session_pool_(spdy_session_pool) {} SpdySessionPool::SpdySessionRequest::~SpdySessionRequest() { if (spdy_session_pool_) @@ -330,7 +334,7 @@ RequestSet* request_set = &spdy_session_request_map_[key]; *is_first_request_for_session = request_set->empty(); *spdy_session_request = - std::make_unique<SpdySessionRequest>(key, delegate, this); + std::make_unique<SpdySessionRequest>(key, is_websocket, delegate, this); request_set->insert(spdy_session_request->get()); if (on_request_destroyed_callback && !*is_first_request_for_session) { @@ -642,11 +646,21 @@ if (iter == spdy_session_request_map_.end()) break; RequestSet* request_set = &iter->second; - RequestSet::iterator request = request_set->begin(); + // Find a request that can use the socket, if any. + RequestSet::iterator request; + for (request = request_set->begin(); request != request_set->end(); + ++request) { + // If the request is for use with websockets, and the session doesn't + // support websockets, skip over the request. + if ((*request)->is_websocket() && !new_session->support_websocket()) + continue; + break; + } + if (request == request_set->end()) + break; + SpdySessionRequest::Delegate* delegate = (*request)->delegate(); - RemoveRequestInternal(iter, request); - delegate->OnSpdySessionAvailable(new_session); } }
diff --git a/net/spdy/spdy_session_pool.h b/net/spdy/spdy_session_pool.h index 8e18e28..2afe8e42 100644 --- a/net/spdy/spdy_session_pool.h +++ b/net/spdy/spdy_session_pool.h
@@ -100,6 +100,7 @@ // Constructor - this is called by the SpdySessionPool. SpdySessionRequest(const SpdySessionKey& key, + bool is_websocket, Delegate* delegate, SpdySessionPool* spdy_session_pool); @@ -110,6 +111,7 @@ void OnRemovedFromPool(); const SpdySessionKey& key() const { return key_; } + bool is_websocket() const { return is_websocket_; } Delegate* delegate() { return delegate_; } // The associated SpdySessionPool, or nullptr if OnRemovedFromPool() has @@ -118,6 +120,7 @@ private: const SpdySessionKey key_; + const bool is_websocket_; Delegate* const delegate_; SpdySessionPool* spdy_session_pool_;
diff --git a/services/device/bluetooth/bluetooth_system_unittest.cc b/services/device/bluetooth/bluetooth_system_unittest.cc index d6e96e2..a9a01f1a 100644 --- a/services/device/bluetooth/bluetooth_system_unittest.cc +++ b/services/device/bluetooth/bluetooth_system_unittest.cc
@@ -117,10 +117,11 @@ ++set_powered_call_count_; last_set_powered_value_ = powered.GetSetValueForTesting(); if (next_set_powered_response_) { - callback.Run(GetValueAndReset(&next_set_powered_response_)); + std::move(callback).Run( + GetValueAndReset(&next_set_powered_response_)); return; } - set_powered_callbacks_.push_back(callback); + set_powered_callbacks_.push_back(std::move(callback)); } else { NOTIMPLEMENTED(); }
diff --git a/services/image_annotation/annotator.cc b/services/image_annotation/annotator.cc index 924becc..d2681da6 100644 --- a/services/image_annotation/annotator.cc +++ b/services/image_annotation/annotator.cc
@@ -164,8 +164,7 @@ continue; const base::Value* const score = desc.FindKey("score"); - if (!score || (!score->is_double() && !score->is_int()) || - score->GetDouble() < 0.0 || score->GetDouble() > 1.0) + if (!score || (!score->is_double() && !score->is_int())) continue; const base::Value* const text = desc.FindKey("text"); @@ -175,9 +174,13 @@ ReportDescAnnotation(type_lookup->second, score->GetDouble(), text->GetString().empty()); - // Empty text is valid for OCR, but not for labels or captions. + // For OCR, we allow empty text and unusual scores; at the time of writing, + // a score of -1 is always returned for OCR. + // + // For other annotation types, we do not allow these cases. if (type_lookup->second != mojom::AnnotationType::kOcr && - text->GetString().empty()) + (text->GetString().empty() || score->GetDouble() < 0.0 || + score->GetDouble() > 1.0)) continue; results.push_back(mojom::Annotation::New(
diff --git a/services/network/network_context.cc b/services/network/network_context.cc index e2a57fa..9d6f7b9 100644 --- a/services/network/network_context.cc +++ b/services/network/network_context.cc
@@ -1867,12 +1867,9 @@ *params_->transport_security_persister_path); } - // TODO(jam): we should stop using the network service for data scheme, since - // the clients shouldn't have to process hop to the network process to load a - // URL that doesn't go over the network. When changing this though need to - // make sure that loading data URLs for PAC still works. - // http://crbug.com/939871 - builder->set_data_enabled(true); + // With the network service data URLs are handled by clients directly. + if (!base::FeatureList::IsEnabled(features::kNetworkService)) + builder->set_data_enabled(true); #if !BUILDFLAG(DISABLE_FTP_SUPPORT) builder->set_ftp_enabled(params_->enable_ftp_url_support);
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc index 2a84df3..e352bcdc 100644 --- a/services/network/network_context_unittest.cc +++ b/services/network/network_context_unittest.cc
@@ -581,12 +581,13 @@ .quic_user_agent_id); } -TEST_F(NetworkContextTest, DataUrlSupportEnabled) { +TEST_F(NetworkContextTest, DataUrlSupport) { mojom::NetworkContextParamsPtr context_params = CreateContextParams(); std::unique_ptr<NetworkContext> network_context = CreateContextWithParams(std::move(context_params)); - EXPECT_TRUE( - network_context->url_request_context()->job_factory()->IsHandledProtocol( + EXPECT_EQ( + base::FeatureList::IsEnabled(features::kNetworkService), + !network_context->url_request_context()->job_factory()->IsHandledProtocol( url::kDataScheme)); }
diff --git a/services/network/public/cpp/simple_url_loader_unittest.cc b/services/network/public/cpp/simple_url_loader_unittest.cc index a8004ae..4165904e 100644 --- a/services/network/public/cpp/simple_url_loader_unittest.cc +++ b/services/network/public/cpp/simple_url_loader_unittest.cc
@@ -689,23 +689,6 @@ } } -// Test that SimpleURLLoader handles data URLs, which don't have headers. -TEST_P(SimpleURLLoaderTest, DataURL) { - std::unique_ptr<SimpleLoaderTestHelper> test_helper = - CreateHelperForURL(GURL("data:text/plain,foo")); - test_helper->StartSimpleLoaderAndWait(url_loader_factory_.get()); - - EXPECT_EQ(net::OK, test_helper->simple_url_loader()->NetError()); - ASSERT_TRUE(test_helper->simple_url_loader()->ResponseInfo()); - EXPECT_FALSE(test_helper->simple_url_loader()->ResponseInfo()->headers); - - if (GetParam() != SimpleLoaderTestHelper::DownloadType::HEADERS_ONLY) { - ASSERT_TRUE(test_helper->response_body()); - EXPECT_EQ("foo", *test_helper->response_body()); - EXPECT_EQ(3, test_helper->simple_url_loader()->GetContentSize()); - } -} - // Make sure the class works when the size of the encoded and decoded bodies are // different. TEST_P(SimpleURLLoaderTest, GzipBody) { @@ -2815,7 +2798,7 @@ TEST_F(SimpleURLLoaderFileTest, OverwriteFile) { std::string junk_data(100, '!'); std::unique_ptr<SimpleLoaderTestHelper> test_helper = - CreateHelperForURL(GURL("data:text/plain,foo")); + CreateHelperForURL(test_server_.GetURL("/echo")); { base::ScopedAllowBlockingForTesting allow_blocking; ASSERT_EQ(static_cast<int>(junk_data.size()), @@ -2829,13 +2812,13 @@ EXPECT_EQ(net::OK, test_helper->simple_url_loader()->NetError()); ASSERT_TRUE(test_helper->simple_url_loader()->ResponseInfo()); ASSERT_TRUE(test_helper->response_body()); - EXPECT_EQ("foo", *test_helper->response_body()); + EXPECT_EQ("Echo", *test_helper->response_body()); } // Make sure that file creation errors are handled correctly. TEST_F(SimpleURLLoaderFileTest, FileCreateError) { std::unique_ptr<SimpleLoaderTestHelper> test_helper = - CreateHelperForURL(GURL("data:text/plain,foo")); + CreateHelperForURL(test_server_.GetURL("/echo")); { base::ScopedAllowBlockingForTesting allow_blocking; ASSERT_TRUE(base::CreateDirectory(test_helper->dest_path()));
diff --git a/services/resource_coordinator/public/mojom/coordination_unit.mojom b/services/resource_coordinator/public/mojom/coordination_unit.mojom index 99e2196..bdd1412 100644 --- a/services/resource_coordinator/public/mojom/coordination_unit.mojom +++ b/services/resource_coordinator/public/mojom/coordination_unit.mojom
@@ -69,10 +69,4 @@ // Property signals. SetExpectedTaskQueueingDuration(mojo_base.mojom.TimeDelta duration); SetMainThreadTaskLoadIsLow(bool main_thread_task_load_is_low); - - // Event signals. - - // Fired when one of the renderer heaps is about to exceed its limit. - // If nothing is done, then the renderer is likely to crash with OOM. - OnRendererIsBloated(); };
diff --git a/services/resource_coordinator/public/mojom/page_signal.mojom b/services/resource_coordinator/public/mojom/page_signal.mojom index ecb2c2c..ed05212 100644 --- a/services/resource_coordinator/public/mojom/page_signal.mojom +++ b/services/resource_coordinator/public/mojom/page_signal.mojom
@@ -35,7 +35,6 @@ // PageSignalGenerator::AddReceiver. interface PageSignalReceiver { NotifyPageAlmostIdle(PageNavigationIdentity page_navigation_id); - NotifyRendererIsBloated(PageNavigationIdentity page_navigation_id); SetExpectedTaskQueueingDuration(PageNavigationIdentity page_navigation_id, mojo_base.mojom.TimeDelta duration); SetLifecycleState(PageNavigationIdentity page_navigation_id,
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index 4b9a5c0..eb4de5e 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -5939,35 +5939,6 @@ }, { "args": [ - "--enable-gpu", - "--test-launcher-bot-mode", - "--test-launcher-jobs=1", - "--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter", - "--enable-features=VizDisplayCompositor,UseSkiaRenderer,UiGpuRasterization", - "--use-gl=any", - "--enable-oop-rasterization", - "--enable-vulkan", - "--enable-gpu-rasterization", - "--force-gpu-rasterization", - "--disable-software-compositing-fallback", - "--disable-vulkan-fallback-to-gl-for-testing", - "--no-xvfb" - ], - "name": "vulkan_content_browsertests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "nvidia-quadro-p400-ubuntu-stable", - "os": "Ubuntu", - "pool": "Chrome-GPU" - } - ] - }, - "test": "content_browsertests" - }, - { - "args": [ "--use-gpu-in-tests", "--test-launcher-retry-limit=0" ], @@ -6880,35 +6851,6 @@ }, { "args": [ - "--enable-gpu", - "--test-launcher-bot-mode", - "--test-launcher-jobs=1", - "--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter", - "--enable-features=VizDisplayCompositor,UseSkiaRenderer,UiGpuRasterization", - "--use-gl=any", - "--enable-oop-rasterization", - "--enable-vulkan", - "--enable-gpu-rasterization", - "--force-gpu-rasterization", - "--disable-software-compositing-fallback", - "--disable-vulkan-fallback-to-gl-for-testing", - "--no-xvfb" - ], - "name": "vulkan_content_browsertests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "10de:1cb3-410.78", - "os": "Ubuntu", - "pool": "Chrome-GPU" - } - ] - }, - "test": "content_browsertests" - }, - { - "args": [ "--use-gpu-in-tests", "--test-launcher-retry-limit=0" ], @@ -8112,9 +8054,9 @@ "--enable-oop-rasterization", "--enable-vulkan", "--enable-gpu-rasterization", + "--enable-raster-to-sk-image", "--force-gpu-rasterization", "--disable-software-compositing-fallback", - "--disable-vulkan-fallback-to-gl-for-testing", "--no-xvfb" ], "name": "vulkan_content_browsertests", @@ -8690,35 +8632,6 @@ }, { "args": [ - "--enable-gpu", - "--test-launcher-bot-mode", - "--test-launcher-jobs=1", - "--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter", - "--enable-features=VizDisplayCompositor,UseSkiaRenderer,UiGpuRasterization", - "--use-gl=any", - "--enable-oop-rasterization", - "--enable-vulkan", - "--enable-gpu-rasterization", - "--force-gpu-rasterization", - "--disable-software-compositing-fallback", - "--disable-vulkan-fallback-to-gl-for-testing", - "--no-xvfb" - ], - "name": "vulkan_content_browsertests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "nvidia-quadro-p400-ubuntu-stable", - "os": "Ubuntu", - "pool": "Chrome-GPU" - } - ] - }, - "test": "content_browsertests" - }, - { - "args": [ "--use-gpu-in-tests", "--test-launcher-retry-limit=0" ], @@ -9302,35 +9215,6 @@ }, { "args": [ - "--enable-gpu", - "--test-launcher-bot-mode", - "--test-launcher-jobs=1", - "--test-launcher-filter-file=../../testing/buildbot/filters/vulkan.content_browsertests.filter", - "--enable-features=VizDisplayCompositor,UseSkiaRenderer,UiGpuRasterization", - "--use-gl=any", - "--enable-oop-rasterization", - "--enable-vulkan", - "--enable-gpu-rasterization", - "--force-gpu-rasterization", - "--disable-software-compositing-fallback", - "--disable-vulkan-fallback-to-gl-for-testing", - "--no-xvfb" - ], - "name": "vulkan_content_browsertests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "gpu": "nvidia-quadro-p400-ubuntu-stable", - "os": "Ubuntu", - "pool": "Chrome-GPU" - } - ] - }, - "test": "content_browsertests" - }, - { - "args": [ "--use-gpu-in-tests", "--test-launcher-retry-limit=0" ], @@ -16812,9 +16696,9 @@ "--enable-oop-rasterization", "--enable-vulkan", "--enable-gpu-rasterization", + "--enable-raster-to-sk-image", "--force-gpu-rasterization", "--disable-software-compositing-fallback", - "--disable-vulkan-fallback-to-gl-for-testing", "--no-xvfb" ], "name": "vulkan_content_browsertests", @@ -17082,9 +16966,9 @@ "--enable-oop-rasterization", "--enable-vulkan", "--enable-gpu-rasterization", + "--enable-raster-to-sk-image", "--force-gpu-rasterization", "--disable-software-compositing-fallback", - "--disable-vulkan-fallback-to-gl-for-testing", "--no-xvfb" ], "name": "vulkan_content_browsertests",
diff --git a/testing/buildbot/filters/vulkan.content_browsertests.filter b/testing/buildbot/filters/vulkan.content_browsertests.filter index 54d5943..8125f51 100644 --- a/testing/buildbot/filters/vulkan.content_browsertests.filter +++ b/testing/buildbot/filters/vulkan.content_browsertests.filter
@@ -1,4 +1,5 @@ -AuraWindowVideoCaptureDeviceBrowserTest.ErrorsOutIfWindowHasGoneBeforeDeviceStart +# Times out crbug.com/930943 +#AuraWindowVideoCaptureDeviceBrowserTest.ErrorsOutIfWindowHasGoneBeforeDeviceStart AuraWindowVideoCaptureDeviceBrowserTest.ErrorsOutWhenWindowIsDestroyed AuraWindowVideoCaptureDeviceBrowserTest.DeliversRefreshFramesUponRequest AuraWindowVideoCaptureDeviceBrowserTest.SuspendsAndResumes
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 62984488..308a05e 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -1476,8 +1476,11 @@ 'remove_from': [ # Flaky hangs crbug.com/940723 'Linux FYI GPU TSAN Release', - # Low capacity both with obsolete graphics card. 'Linux FYI Release (AMD R7 240)', + 'Linux FYI Debug (NVIDIA)', + 'Linux FYI Experimental Release (NVIDIA)', + 'Linux FYI SkiaRenderer Vulkan (NVIDIA)', + 'Linux FYI Release (NVIDIA)', # Consistent hangs crbug.com/940750 'Linux FYI Experimental Release (Intel HD 630)', ],
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 98b1ef7..6d1bcfa 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -3197,9 +3197,9 @@ '--enable-oop-rasterization', '--enable-vulkan', '--enable-gpu-rasterization', + '--enable-raster-to-sk-image', '--force-gpu-rasterization', '--disable-software-compositing-fallback', - '--disable-vulkan-fallback-to-gl-for-testing', ], 'linux_args': [ '--no-xvfb' ], 'test': 'content_browsertests',
diff --git a/third_party/blink/public/common/BUILD.gn b/third_party/blink/public/common/BUILD.gn index e0c7db7..e32e923 100644 --- a/third_party/blink/public/common/BUILD.gn +++ b/third_party/blink/public/common/BUILD.gn
@@ -94,6 +94,7 @@ "page/launching_process_state.h", "prerender/prerender_rel_type.h", "privacy_preferences.h", + "scheduler/web_scheduler_tracked_feature.h", "screen_orientation/web_screen_orientation_lock_type.h", "screen_orientation/web_screen_orientation_type.h", "service_worker/service_worker_status_code.h",
diff --git a/third_party/blink/public/common/scheduler/OWNERS b/third_party/blink/public/common/scheduler/OWNERS new file mode 100644 index 0000000..6f83df0f --- /dev/null +++ b/third_party/blink/public/common/scheduler/OWNERS
@@ -0,0 +1 @@ +file://third_party/blink/renderer/platform/scheduler/OWNERS
diff --git a/third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h b/third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h new file mode 100644 index 0000000..9d637ee --- /dev/null +++ b/third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h
@@ -0,0 +1,38 @@ +// Copyright 2019 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 THIRD_PARTY_BLINK_PUBLIC_COMMON_SCHEDULER_WEB_SCHEDULER_TRACKED_FEATURE_H_ +#define THIRD_PARTY_BLINK_PUBLIC_COMMON_SCHEDULER_WEB_SCHEDULER_TRACKED_FEATURE_H_ + +namespace blink { +namespace scheduler { + +// A list of features which influence scheduling behaviour (throttling / +// freezing / back-forward cache) and which might be sent to the browser process +// for metrics-related purposes. +enum class WebSchedulerTrackedFeature { + kWebSocket = 0, + kWebRTC = 1, + + kMainResourceHasCacheControlNoCache = 2, + kMainResourceHasCacheControlNoStore = 3, + kSubresourceHasCacheControlNoCache = 4, + kSubresourceHasCacheControlNoStore = 5, + + kPageShowEventListener = 6, + kPageHideEventListener = 7, + kBeforeUnloadEventListener = 8, + kUnloadEventListener = 9, + kFreezeEventListener = 10, + kResumeEventListener = 11, + + kContainsPlugins = 12, + + kCount = 13 +}; + +} // namespace scheduler +} // namespace blink + +#endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_SCHEDULER_WEB_SCHEDULER_TRACKED_FEATURE_H_
diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index 51423ac..7a722c66 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom
@@ -1801,7 +1801,6 @@ kGetComputedStyleWebkitAppearance = 2374, kV8LockManager_Request_Method = 2375, kV8LockManager_Query_Method = 2376, - kUserMediaEnableExperimentalHardwareEchoCancellation = 2377, kV8RTCDTMFSender_Track_AttributeGetter = 2378, kV8RTCDTMFSender_Duration_AttributeGetter = 2379, kV8RTCDTMFSender_InterToneGap_AttributeGetter = 2380,
diff --git a/third_party/blink/public/platform/web_url_request.h b/third_party/blink/public/platform/web_url_request.h index ddb1468..7d05a3c 100644 --- a/third_party/blink/public/platform/web_url_request.h +++ b/third_party/blink/public/platform/web_url_request.h
@@ -369,6 +369,11 @@ BLINK_PLATFORM_EXPORT const WebString GetRequestedWithHeader() const; BLINK_PLATFORM_EXPORT void SetRequestedWithHeader(const WebString&); + // Remembers 'Purpose' header value. Blink should not set this header value + // until CORS checks are done to avoid running checks even against headers + // that are internally set. + BLINK_PLATFORM_EXPORT const WebString GetPurposeHeader() const; + // https://fetch.spec.whatwg.org/#concept-request-window // See network::ResourceRequest::fetch_window_id for details. BLINK_PLATFORM_EXPORT const base::UnguessableToken& GetFetchWindowId() const;
diff --git a/third_party/blink/public/web/web_window_features.h b/third_party/blink/public/web/web_window_features.h index 7aa5be6..4f735ad 100644 --- a/third_party/blink/public/web/web_window_features.h +++ b/third_party/blink/public/web/web_window_features.h
@@ -49,9 +49,15 @@ // string, we don't distinguish between the two. bool tool_bar_visible = true; bool scrollbars_visible = true; + + // The members above this line are transferred through mojo + // in the form of |struct WindowFeatures| defined in window_features.mojom, + // to be used across process boundaries. + // Below members are the ones not transferred through mojo. bool resizable = true; bool noopener = false; + bool noreferrer = false; bool background = false; bool persistent = false; };
diff --git a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc index a7349815..1df2ce8 100644 --- a/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc +++ b/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc
@@ -92,94 +92,6 @@ OOM_CRASH(); } -namespace { - -// Set to BloatedRendererDetector::OnNearV8HeapLimitOnMainThread during startup. -static NearV8HeapLimitCallback g_near_heap_limit_on_main_thread_callback_ = - nullptr; - -void Record(NearV8HeapLimitHandling handling, - v8::Isolate* isolate, - size_t heap_limit, - ukm::UkmRecorder* ukm_recorder, - int64_t ukm_source_id) { - UMA_HISTOGRAM_ENUMERATION("BloatedRenderer.V8.NearV8HeapLimitHandling", - handling); - if (ukm_recorder) { - // Record size metrics in MB similar to Memory.Experimental.Renderer2.V8. - const size_t kMB = 1024 * 1024; - v8::HeapStatistics heap_statistics; - isolate->GetHeapStatistics(&heap_statistics); - ukm::builders::BloatedRenderer(ukm_source_id) - .SetV8_NearV8HeapLimitHandling(static_cast<int64_t>(handling)) - .SetV8_Heap(heap_statistics.total_physical_size() / kMB) - .SetV8_Heap_AllocatedObjects(heap_statistics.used_heap_size() / kMB) - .SetV8_Heap_Limit(heap_limit / kMB) - .Record(ukm_recorder); - } -} - -size_t IncreaseV8HeapLimit(size_t v8_heap_limit) { - // The heap limit for a bloated page should be increased to avoid immediate - // OOM crash. The exact amount is not important, it should be sufficiently - // large to give enough time for the browser process to reload the page. - // Increase the heap limit by 25%. - return v8_heap_limit + v8_heap_limit / 4; -} - -size_t NearHeapLimitCallbackOnMainThread(void* data, - size_t current_heap_limit, - size_t initial_heap_limit) { - v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(data); - // Find the main document for UKM recording. - Document* document = nullptr; - int pages = 0; - for (Page* page : Page::OrdinaryPages()) { - if (auto* main_local_frame = DynamicTo<LocalFrame>(page->MainFrame())) { - ++pages; - document = main_local_frame->GetDocument(); - } - } - ukm::UkmRecorder* ukm_recorder = nullptr; - int64_t ukm_source_id = 0; - // Do not record UKM if there are multiple pages as we cannot attribute - // the heap size to a specific page. - if (pages == 1 && document) { - ukm_recorder = document->UkmRecorder(); - ukm_source_id = document->UkmSourceID(); - } - - if (current_heap_limit != initial_heap_limit) { - Record(NearV8HeapLimitHandling::kIgnoredDueToChangedHeapLimit, isolate, - current_heap_limit, ukm_recorder, ukm_source_id); - return current_heap_limit; - } - - NearV8HeapLimitHandling handling = - g_near_heap_limit_on_main_thread_callback_(); - Record(handling, isolate, current_heap_limit, ukm_recorder, ukm_source_id); - return (handling == NearV8HeapLimitHandling::kForwardedToBrowser) - ? IncreaseV8HeapLimit(current_heap_limit) - : current_heap_limit; -} - -size_t NearHeapLimitCallbackOnWorkerThread(void* data, - size_t current_heap_limit, - size_t initial_heap_limit) { - v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(data); - // Do not record UKM on worker thread. - Record(NearV8HeapLimitHandling::kIgnoredDueToWorker, isolate, - current_heap_limit, nullptr, 0); - return current_heap_limit; -} - -} // anonymous namespace - -void V8Initializer::SetNearV8HeapLimitOnMainThreadCallback( - NearV8HeapLimitCallback callback) { - g_near_heap_limit_on_main_thread_callback_ = callback; -} - static String ExtractMessageForConsole(v8::Isolate* isolate, v8::Local<v8::Value> data) { if (V8DOMWrapper::IsWrapper(isolate, data)) { @@ -701,12 +613,6 @@ isolate->SetOOMErrorHandler(ReportOOMErrorInMainThread); - if (RuntimeEnabledFeatures::BloatedRendererDetectionEnabled()) { - DCHECK(g_near_heap_limit_on_main_thread_callback_); - isolate->AddNearHeapLimitCallback(NearHeapLimitCallbackOnMainThread, - isolate); - isolate->AutomaticallyRestoreInitialHeapLimit(); - } isolate->SetFatalErrorHandler(ReportFatalErrorInMainThread); isolate->AddMessageListenerWithErrorLevel( MessageHandlerInMainThread, @@ -759,10 +665,6 @@ isolate->SetStackLimit(WTF::GetCurrentStackPosition() - kWorkerMaxStackSize); isolate->SetPromiseRejectCallback(PromiseRejectHandlerInWorker); - if (RuntimeEnabledFeatures::BloatedRendererDetectionEnabled()) { - isolate->AddNearHeapLimitCallback(NearHeapLimitCallbackOnWorkerThread, - isolate); - } } } // namespace blink
diff --git a/third_party/blink/renderer/bindings/scripts/web_idl/common.py b/third_party/blink/renderer/bindings/scripts/web_idl/common.py index 0113be3..152a27f 100644 --- a/third_party/blink/renderer/bindings/scripts/web_idl/common.py +++ b/third_party/blink/renderer/bindings/scripts/web_idl/common.py
@@ -4,6 +4,10 @@ import exceptions +from .extended_attribute import ExtendedAttributes +from .exposure import Exposure + + Identifier = str @@ -11,13 +15,16 @@ """WithIdentifier class is an interface that indicates the class has an identifier.""" + def __init__(self, identifier): + self._identifier = identifier + @property def identifier(self): """ Returns the identifier. @return Identifier """ - raise exceptions.NotImplementedError() + return self._identifier # ExtendedAttribute and ExtendedAttributes are defined in extended_attribute.py @@ -25,32 +32,47 @@ """WithExtendedAttributes class is an interface that indicates the implemented class can have extended attributes.""" + def __init__(self, extended_attributes=None): + self._extended_attributes = extended_attributes or ExtendedAttributes() + @property def extended_attributes(self): """ Returns the extended attributes. @return ExtendedAttributes """ - raise exceptions.NotImplementedError() + return self._extended_attributes + + +CodeGeneratorInfo = dict class WithCodeGeneratorInfo(object): """WithCodeGeneratorInfo class is an interface that its inheritances can provide some information for code generators.""" + def __init__(self, code_generator_info=None): + self._code_generator_info = code_generator_info or CodeGeneratorInfo() + @property def code_generator_info(self): """ Returns information for code generator. - @return dict(TBD) + @return CodeGeneratorInfo """ - raise exceptions.NotImplementedError() + return self._code_generator_info class WithExposure(object): """WithExposure class is an interface that its inheritances can have Exposed extended attributes.""" + def __init__(self, exposures=None): + assert (exposures is None + or (isinstance(exposures, (list, tuple)) and all( + isinstance(exposure, Exposure) for exposure in exposures))) + self._exposures = tuple(exposures or ()) + @property def exposures(self): """ @@ -58,7 +80,7 @@ https://heycam.github.io/webidl/#Exposed @return tuple(Expsure) """ - raise exceptions.NotImplementedError() + return self._exposures Component = str @@ -75,34 +97,44 @@ 'modules', ) + def __init__(self, components): + self._components = components + @property def components(self): """ Returns a list of components' names where this definition is defined @return tuple(Component) """ - raise exceptions.NotImplementedError() + return self._components class DebugInfo(object): """DebugInfo provides some information for debugging.""" + def __init__(self, filepaths): + self._filepaths = tuple(filepaths) + @property def filepaths(self): """ Returns a list of filepaths where this IDL definition comes from. @return tuple(FilePath) """ - raise exceptions.NotImplementedError() + return self._filepaths class WithDebugInfo(object): """WithDebugInfo class is an interface that its inheritances can have DebugInfo.""" + def __init__(self, debug_info=None): + self._debug_info = debug_info or DebugInfo( + filepaths=('<<unspecified>>', )) + @property def debug_info(self): """Returns DebugInfo.""" - raise exceptions.NotImplementedError() + return self._debug_info class WithOwner(object): @@ -111,10 +143,13 @@ a namespace, a dictionary, and so on. If this object is an argument, it points a function like object.""" + def __init__(self, owner): + self._owner = owner + @property def owner(self): """ Returns the owner of this instance. - @return object(TBD) + @return object """ - raise exceptions.NotImplementedError() + return self._owner
diff --git a/third_party/blink/renderer/controller/BUILD.gn b/third_party/blink/renderer/controller/BUILD.gn index 5a2a6258..c62ad20 100644 --- a/third_party/blink/renderer/controller/BUILD.gn +++ b/third_party/blink/renderer/controller/BUILD.gn
@@ -39,8 +39,6 @@ "blink_initializer.h", "blink_leak_detector.cc", "blink_leak_detector.h", - "bloated_renderer_detector.cc", - "bloated_renderer_detector.h", "controller_export.h", "dev_tools_frontend_impl.cc", "dev_tools_frontend_impl.h", @@ -146,7 +144,6 @@ testonly = true sources = [ - "bloated_renderer_detector_test.cc", "tests/run_all_tests.cc", ] sources += bindings_unittest_files
diff --git a/third_party/blink/renderer/controller/blink_initializer.cc b/third_party/blink/renderer/controller/blink_initializer.cc index 747405c..ae07bcaf 100644 --- a/third_party/blink/renderer/controller/blink_initializer.cc +++ b/third_party/blink/renderer/controller/blink_initializer.cc
@@ -40,7 +40,6 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_initializer.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_context_snapshot_external_references.h" #include "third_party/blink/renderer/controller/blink_leak_detector.h" -#include "third_party/blink/renderer/controller/bloated_renderer_detector.h" #include "third_party/blink/renderer/controller/dev_tools_frontend_impl.h" #include "third_party/blink/renderer/core/animation/animation_clock.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -113,12 +112,6 @@ // BlinkInitializer::Initialize() must be called before InitializeMainThread GetBlinkInitializer().Initialize(); - if (RuntimeEnabledFeatures::BloatedRendererDetectionEnabled()) { - BloatedRendererDetector::Initialize(); - V8Initializer::SetNearV8HeapLimitOnMainThreadCallback( - BloatedRendererDetector::OnNearV8HeapLimitOnMainThread); - } - V8Initializer::InitializeMainThread( V8ContextSnapshotExternalReferences::GetTable());
diff --git a/third_party/blink/renderer/controller/bloated_renderer_detector.cc b/third_party/blink/renderer/controller/bloated_renderer_detector.cc deleted file mode 100644 index 58399c7..0000000 --- a/third_party/blink/renderer/controller/bloated_renderer_detector.cc +++ /dev/null
@@ -1,40 +0,0 @@ -// 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 "third_party/blink/renderer/controller/bloated_renderer_detector.h" - -#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h" -#include "third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.h" - -namespace blink { - -static BloatedRendererDetector* g_bloated_renderer_detector = nullptr; - -void BloatedRendererDetector::Initialize() { - g_bloated_renderer_detector = - new BloatedRendererDetector(WTF::CurrentTimeTicks()); -} - -NearV8HeapLimitHandling -BloatedRendererDetector::OnNearV8HeapLimitOnMainThread() { - return g_bloated_renderer_detector->OnNearV8HeapLimitOnMainThreadImpl(); -} - -NearV8HeapLimitHandling -BloatedRendererDetector::OnNearV8HeapLimitOnMainThreadImpl() { - WTF::TimeTicks now = WTF::CurrentTimeTicks(); - if (!RuntimeEnabledFeatures:: - BloatedRendererDetectionSkipUptimeCheckEnabled()) { - WTF::TimeDelta delta = now - last_detection_time_; - if (delta.InMinutes() < kMinimumCooldownInMinutes) { - return NearV8HeapLimitHandling::kIgnoredDueToCooldownTime; - } - } - last_detection_time_ = now; - if (auto* renderer_resource_coordinator = RendererResourceCoordinator::Get()) - renderer_resource_coordinator->OnRendererIsBloated(); - return NearV8HeapLimitHandling::kForwardedToBrowser; -} - -} // namespace blink
diff --git a/third_party/blink/renderer/controller/bloated_renderer_detector.h b/third_party/blink/renderer/controller/bloated_renderer_detector.h deleted file mode 100644 index c2e4fae..0000000 --- a/third_party/blink/renderer/controller/bloated_renderer_detector.h +++ /dev/null
@@ -1,50 +0,0 @@ -// 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 THIRD_PARTY_BLINK_RENDERER_CONTROLLER_BLOATED_RENDERER_DETECTOR_H_ -#define THIRD_PARTY_BLINK_RENDERER_CONTROLLER_BLOATED_RENDERER_DETECTOR_H_ - -#include "base/gtest_prod_util.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_initializer.h" -#include "third_party/blink/renderer/controller/controller_export.h" -#include "third_party/blink/renderer/platform/wtf/allocator.h" -#include "third_party/blink/renderer/platform/wtf/time.h" - -namespace blink { - -// Singleton class for detecting and handling bloated renderer conditions. -// Different parts of the renderer call the corresponding methods of this -// class to notify about potential bloat conditions. It currently works only -// for V8. In future it will be extended to the whole renderer. -class CONTROLLER_EXPORT BloatedRendererDetector { - USING_FAST_MALLOC(BloatedRendererDetector); - - public: - // Sets up the global singleton instance. - static void Initialize(); - - // Called when the main V8 isolate is close to reach its heap limit. - static NearV8HeapLimitHandling OnNearV8HeapLimitOnMainThread(); - - private: - friend class BloatedRendererDetectorTest; - FRIEND_TEST_ALL_PREFIXES(BloatedRendererDetectorTest, CooldownTime); - FRIEND_TEST_ALL_PREFIXES(BloatedRendererDetectorTest, ForwardToBrowser); - FRIEND_TEST_ALL_PREFIXES(BloatedRendererDetectorTest, MultipleDetections); - - // The time which should pass between 2 successive detections of bloated - // renderer. - static const int kMinimumCooldownInMinutes = 10; - - explicit BloatedRendererDetector(WTF::TimeTicks time) - : last_detection_time_(time) {} - - NearV8HeapLimitHandling OnNearV8HeapLimitOnMainThreadImpl(); - - WTF::TimeTicks last_detection_time_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_CONTROLLER_BLOATED_RENDERER_DETECTOR_H_
diff --git a/third_party/blink/renderer/controller/bloated_renderer_detector_test.cc b/third_party/blink/renderer/controller/bloated_renderer_detector_test.cc deleted file mode 100644 index 72c7734..0000000 --- a/third_party/blink/renderer/controller/bloated_renderer_detector_test.cc +++ /dev/null
@@ -1,54 +0,0 @@ -// 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 "third_party/blink/renderer/controller/bloated_renderer_detector.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/platform/testing/wtf/scoped_mock_clock.h" -#include "third_party/blink/renderer/platform/wtf/time.h" - -namespace blink { - -class BloatedRendererDetectorTest : public testing::Test { - public: - static TimeDelta GetMockAfterCooldown() { - return TimeDelta::FromMinutes( - BloatedRendererDetector::kMinimumCooldownInMinutes + 1); - } - - static TimeDelta GetMockBeforeCooldown() { - return TimeDelta::FromMinutes( - BloatedRendererDetector::kMinimumCooldownInMinutes - 1); - } -}; - -TEST_F(BloatedRendererDetectorTest, ForwardToBrowser) { - WTF::ScopedMockClock clock; - clock.Advance(GetMockAfterCooldown()); - BloatedRendererDetector detector(TimeTicks{}); - EXPECT_EQ(NearV8HeapLimitHandling::kForwardedToBrowser, - detector.OnNearV8HeapLimitOnMainThreadImpl()); -} - -TEST_F(BloatedRendererDetectorTest, CooldownTime) { - WTF::ScopedMockClock clock; - clock.Advance(GetMockBeforeCooldown()); - BloatedRendererDetector detector(TimeTicks{}); - EXPECT_EQ(NearV8HeapLimitHandling::kIgnoredDueToCooldownTime, - detector.OnNearV8HeapLimitOnMainThreadImpl()); -} - -TEST_F(BloatedRendererDetectorTest, MultipleDetections) { - WTF::ScopedMockClock clock; - clock.Advance(GetMockAfterCooldown()); - BloatedRendererDetector detector(TimeTicks{}); - EXPECT_EQ(NearV8HeapLimitHandling::kForwardedToBrowser, - detector.OnNearV8HeapLimitOnMainThreadImpl()); - EXPECT_EQ(NearV8HeapLimitHandling::kIgnoredDueToCooldownTime, - detector.OnNearV8HeapLimitOnMainThreadImpl()); - clock.Advance(GetMockAfterCooldown()); - EXPECT_EQ(NearV8HeapLimitHandling::kForwardedToBrowser, - detector.OnNearV8HeapLimitOnMainThreadImpl()); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/core/css/rule_feature_set_test.cc b/third_party/blink/renderer/core/css/rule_feature_set_test.cc index 06937649..5f83f30 100644 --- a/third_party/blink/renderer/core/css/rule_feature_set_test.cc +++ b/third_party/blink/renderer/core/css/rule_feature_set_test.cc
@@ -16,6 +16,7 @@ #include "third_party/blink/renderer/core/html/html_document.h" #include "third_party/blink/renderer/core/html/html_element.h" #include "third_party/blink/renderer/core/html/html_html_element.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -25,8 +26,8 @@ void SetUp() override { document_ = HTMLDocument::CreateForTest(); - HTMLHtmlElement* html = HTMLHtmlElement::Create(*document_); - html->AppendChild(HTMLBodyElement::Create(*document_)); + auto* html = MakeGarbageCollected<HTMLHtmlElement>(*document_); + html->AppendChild(MakeGarbageCollected<HTMLBodyElement>(*document_)); document_->AppendChild(html); document_->body()->SetInnerHTMLFromString("<b><i></i></b>");
diff --git a/third_party/blink/renderer/core/css/selector_query_test.cc b/third_party/blink/renderer/core/css/selector_query_test.cc index bd11f1cd..1cff998 100644 --- a/third_party/blink/renderer/core/css/selector_query_test.cc +++ b/third_party/blink/renderer/core/css/selector_query_test.cc
@@ -14,6 +14,7 @@ #include "third_party/blink/renderer/core/dom/static_node_list.h" #include "third_party/blink/renderer/core/html/html_document.h" #include "third_party/blink/renderer/core/html/html_html_element.h" +#include "third_party/blink/renderer/platform/heap/heap.h" // Uncomment to run the SelectorQueryTests for stats in a release build. // #define RELEASE_QUERY_STATS @@ -62,7 +63,7 @@ TEST(SelectorQueryTest, NotMatchingPseudoElement) { Document* document = Document::CreateForTest(); - HTMLHtmlElement* html = HTMLHtmlElement::Create(*document); + auto* html = MakeGarbageCollected<HTMLHtmlElement>(*document); document->AppendChild(html); document->documentElement()->SetInnerHTMLFromString( "<body><style>span::before { content: 'X' }</style><span></span></body>"); @@ -91,7 +92,7 @@ TEST(SelectorQueryTest, LastOfTypeNotFinishedParsing) { Document* document = HTMLDocument::CreateForTest(); - HTMLHtmlElement* html = HTMLHtmlElement::Create(*document); + auto* html = MakeGarbageCollected<HTMLHtmlElement>(*document); document->AppendChild(html); document->documentElement()->SetInnerHTMLFromString( "<body><p></p><p id=last></p></body>", ASSERT_NO_EXCEPTION);
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc index 8c00f3f..463c65be 100644 --- a/third_party/blink/renderer/core/css/style_engine_test.cc +++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -291,8 +291,8 @@ ASSERT_EQ(capabilities.slope, FontSelectionRange({ItalicSlopeValue(), ItalicSlopeValue()})); - auto* style_element = - HTMLStyleElement::Create(GetDocument(), CreateElementFlags()); + auto* style_element = MakeGarbageCollected<HTMLStyleElement>( + GetDocument(), CreateElementFlags()); style_element->SetInnerHTMLFromString( "@font-face {" " font-family: 'Cool Font';" @@ -360,7 +360,8 @@ ASSERT_TRUE(keyframes); EXPECT_EQ(1u, keyframes->Keyframes().size()); - style_element = HTMLStyleElement::Create(GetDocument(), CreateElementFlags()); + style_element = MakeGarbageCollected<HTMLStyleElement>(GetDocument(), + CreateElementFlags()); style_element->SetInnerHTMLFromString( "@keyframes dummy-animation { from {} to {} }"); GetDocument().body()->AppendChild(style_element); @@ -661,7 +662,8 @@ } TEST_F(StyleEngineTest, TextToSheetCache) { - auto* element = HTMLStyleElement::Create(GetDocument(), CreateElementFlags()); + auto* element = MakeGarbageCollected<HTMLStyleElement>(GetDocument(), + CreateElementFlags()); String sheet_text("div {}"); TextPosition min_pos = TextPosition::MinimumPosition(); @@ -689,7 +691,8 @@ // StyleSheetContents cache. ThreadState::Current()->CollectAllGarbageForTesting(); - element = HTMLStyleElement::Create(GetDocument(), CreateElementFlags()); + element = MakeGarbageCollected<HTMLStyleElement>(GetDocument(), + CreateElementFlags()); sheet1 = GetStyleEngine().CreateSheet(*element, sheet_text, min_pos, context); // Check that we did not use a cached StyleSheetContents after the garbage
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index a2efa4b..be9cea96 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -934,7 +934,7 @@ // HTMLElement. // 7. Return HTMLUnknownElement. if (CustomElement::IsValidName(qname.LocalName())) - element = HTMLElement::Create(qname, *this); + element = MakeGarbageCollected<HTMLElement>(qname, *this); else element = HTMLUnknownElement::Create(qname, *this); } @@ -1680,7 +1680,7 @@ HTMLElement* head_element = head(); if (!head_element) return; - title_element_ = HTMLTitleElement::Create(*this); + title_element_ = MakeGarbageCollected<HTMLTitleElement>(*this); head_element->AppendChild(title_element_.Get()); } if (auto* html_title = ToHTMLTitleElementOrNull(title_element_))
diff --git a/third_party/blink/renderer/core/dom/document_test.cc b/third_party/blink/renderer/core/dom/document_test.cc index 7aa7675d..3afa424 100644 --- a/third_party/blink/renderer/core/dom/document_test.cc +++ b/third_party/blink/renderer/core/dom/document_test.cc
@@ -59,6 +59,7 @@ #include "third_party/blink/renderer/core/page/validation_message_client.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/mojo/interface_invalidator.h" #include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" #include "third_party/blink/renderer/platform/weborigin/scheme_registry.h" @@ -424,13 +425,15 @@ EXPECT_EQ(nullptr, GetDocument().LinkManifest()); // Check that we use the first manifest with <link rel=manifest> - auto* link = HTMLLinkElement::Create(GetDocument(), CreateElementFlags()); + auto* link = MakeGarbageCollected<HTMLLinkElement>(GetDocument(), + CreateElementFlags()); link->setAttribute(blink::html_names::kRelAttr, "manifest"); link->setAttribute(blink::html_names::kHrefAttr, "foo.json"); GetDocument().head()->AppendChild(link); EXPECT_EQ(link, GetDocument().LinkManifest()); - auto* link2 = HTMLLinkElement::Create(GetDocument(), CreateElementFlags()); + auto* link2 = MakeGarbageCollected<HTMLLinkElement>(GetDocument(), + CreateElementFlags()); link2->setAttribute(blink::html_names::kRelAttr, "manifest"); link2->setAttribute(blink::html_names::kHrefAttr, "bar.json"); GetDocument().head()->InsertBefore(link2, link);
diff --git a/third_party/blink/renderer/core/dom/dom_implementation.cc b/third_party/blink/renderer/core/dom/dom_implementation.cc index 1539758..a616fafe 100644 --- a/third_party/blink/renderer/core/dom/dom_implementation.cc +++ b/third_party/blink/renderer/core/dom/dom_implementation.cc
@@ -53,6 +53,7 @@ #include "third_party/blink/renderer/core/svg_names.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/graphics/image.h" +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/network/mime/content_type.h" #include "third_party/blink/renderer/platform/network/mime/mime_type_registry.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" @@ -212,7 +213,7 @@ if (!title.IsNull()) { HTMLHeadElement* head_element = d->head(); DCHECK(head_element); - HTMLTitleElement* title_element = HTMLTitleElement::Create(*d); + auto* title_element = MakeGarbageCollected<HTMLTitleElement>(*d); head_element->AppendChild(title_element); title_element->AppendChild(d->createTextNode(title), ASSERT_NO_EXCEPTION); }
diff --git a/third_party/blink/renderer/core/dom/events/event_target.cc b/third_party/blink/renderer/core/dom/events/event_target.cc index 5de9d35..6dfea3ee 100644 --- a/third_party/blink/renderer/core/dom/events/event_target.cc +++ b/third_party/blink/renderer/core/dom/events/event_target.cc
@@ -180,7 +180,7 @@ if (feature_for_scheduler) { execution_context->GetScheduler()->RegisterStickyFeature( feature_for_scheduler.value(), - {SchedulingPolicy::DisableBackForwardCache()}); + {SchedulingPolicy::RecordMetricsForBackForwardCache()}); } }
diff --git a/third_party/blink/renderer/core/dom/range.cc b/third_party/blink/renderer/core/dom/range.cc index 1f121cc..904e6a4 100644 --- a/third_party/blink/renderer/core/dom/range.cc +++ b/third_party/blink/renderer/core/dom/range.cc
@@ -1024,7 +1024,7 @@ // is available. element = document.body(); if (!element) - element = HTMLBodyElement::Create(document); + element = MakeGarbageCollected<HTMLBodyElement>(document); } }
diff --git a/third_party/blink/renderer/core/dom/static_range_test.cc b/third_party/blink/renderer/core/dom/static_range_test.cc index 4d5b675..6f44e4cf 100644 --- a/third_party/blink/renderer/core/dom/static_range_test.cc +++ b/third_party/blink/renderer/core/dom/static_range_test.cc
@@ -17,6 +17,7 @@ #include "third_party/blink/renderer/core/html/html_html_element.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" namespace blink { @@ -33,8 +34,8 @@ void StaticRangeTest::SetUp() { document_ = HTMLDocument::CreateForTest(); - HTMLHtmlElement* html = HTMLHtmlElement::Create(*document_); - html->AppendChild(HTMLBodyElement::Create(*document_)); + auto* html = MakeGarbageCollected<HTMLHtmlElement>(*document_); + html->AppendChild(MakeGarbageCollected<HTMLBodyElement>(*document_)); document_->AppendChild(html); }
diff --git a/third_party/blink/renderer/core/editing/commands/apply_block_element_command.cc b/third_party/blink/renderer/core/editing/commands/apply_block_element_command.cc index a616b4c6..20fa4bd 100644 --- a/third_party/blink/renderer/core/editing/commands/apply_block_element_command.cc +++ b/third_party/blink/renderer/core/editing/commands/apply_block_element_command.cc
@@ -39,6 +39,7 @@ #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -146,7 +147,7 @@ InsertNodeAt(blockquote, caret_position, editing_state); if (editing_state->IsAborted()) return; - HTMLBRElement* placeholder = HTMLBRElement::Create(GetDocument()); + auto* placeholder = MakeGarbageCollected<HTMLBRElement>(GetDocument()); AppendNode(placeholder, blockquote, editing_state); if (editing_state->IsAborted()) return;
diff --git a/third_party/blink/renderer/core/editing/commands/apply_style_command.cc b/third_party/blink/renderer/core/editing/commands/apply_style_command.cc index 3dcfaf2..6d4ce45 100644 --- a/third_party/blink/renderer/core/editing/commands/apply_style_command.cc +++ b/third_party/blink/renderer/core/editing/commands/apply_style_command.cc
@@ -55,6 +55,7 @@ #include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/layout/layout_text.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" @@ -1924,7 +1925,7 @@ SetNodeAttribute(font_container, kSizeAttr, AtomicString(style_change.FontSize())); } else { - HTMLFontElement* font_element = HTMLFontElement::Create(GetDocument()); + auto* font_element = MakeGarbageCollected<HTMLFontElement>(GetDocument()); if (style_change.ApplyFontColor()) font_element->setAttribute(kColorAttr, AtomicString(style_change.FontColor())); @@ -1969,47 +1970,50 @@ } if (style_change.ApplyBold()) { - SurroundNodeRangeWithElement(start_node, end_node, - HTMLElement::Create(kBTag, GetDocument()), - editing_state); + SurroundNodeRangeWithElement( + start_node, end_node, + MakeGarbageCollected<HTMLElement>(kBTag, GetDocument()), editing_state); if (editing_state->IsAborted()) return; } if (style_change.ApplyItalic()) { - SurroundNodeRangeWithElement(start_node, end_node, - HTMLElement::Create(kITag, GetDocument()), - editing_state); + SurroundNodeRangeWithElement( + start_node, end_node, + MakeGarbageCollected<HTMLElement>(kITag, GetDocument()), editing_state); if (editing_state->IsAborted()) return; } if (style_change.ApplyUnderline()) { - SurroundNodeRangeWithElement(start_node, end_node, - HTMLElement::Create(kUTag, GetDocument()), - editing_state); + SurroundNodeRangeWithElement( + start_node, end_node, + MakeGarbageCollected<HTMLElement>(kUTag, GetDocument()), editing_state); if (editing_state->IsAborted()) return; } if (style_change.ApplyLineThrough()) { - SurroundNodeRangeWithElement(start_node, end_node, - HTMLElement::Create(kStrikeTag, GetDocument()), - editing_state); + SurroundNodeRangeWithElement( + start_node, end_node, + MakeGarbageCollected<HTMLElement>(kStrikeTag, GetDocument()), + editing_state); if (editing_state->IsAborted()) return; } if (style_change.ApplySubscript()) { - SurroundNodeRangeWithElement(start_node, end_node, - HTMLElement::Create(kSubTag, GetDocument()), - editing_state); + SurroundNodeRangeWithElement( + start_node, end_node, + MakeGarbageCollected<HTMLElement>(kSubTag, GetDocument()), + editing_state); if (editing_state->IsAborted()) return; } else if (style_change.ApplySuperscript()) { - SurroundNodeRangeWithElement(start_node, end_node, - HTMLElement::Create(kSupTag, GetDocument()), - editing_state); + SurroundNodeRangeWithElement( + start_node, end_node, + MakeGarbageCollected<HTMLElement>(kSupTag, GetDocument()), + editing_state); if (editing_state->IsAborted()) return; }
diff --git a/third_party/blink/renderer/core/editing/commands/break_blockquote_command.cc b/third_party/blink/renderer/core/editing/commands/break_blockquote_command.cc index 046a84b..793dc9a 100644 --- a/third_party/blink/renderer/core/editing/commands/break_blockquote_command.cc +++ b/third_party/blink/renderer/core/editing/commands/break_blockquote_command.cc
@@ -39,6 +39,7 @@ #include "third_party/blink/renderer/core/html/html_quote_element.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/layout/layout_list_item.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -126,7 +127,7 @@ if (!top_blockquote || !top_blockquote->parentNode()) return; - HTMLBRElement* break_element = HTMLBRElement::Create(GetDocument()); + auto* break_element = MakeGarbageCollected<HTMLBRElement>(GetDocument()); bool is_last_vis_pos_in_node = IsLastVisiblePositionInNode(visible_pos, top_blockquote);
diff --git a/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc b/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc index 697643174..8bb4f75 100644 --- a/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc +++ b/third_party/blink/renderer/core/editing/commands/composite_edit_command.cc
@@ -81,6 +81,7 @@ #include "third_party/blink/renderer/core/layout/layout_text.h" #include "third_party/blink/renderer/core/layout/line/inline_text_box.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -937,7 +938,7 @@ // 4244964. DCHECK(container->GetLayoutObject()) << container; - HTMLBRElement* placeholder = HTMLBRElement::Create(GetDocument()); + auto* placeholder = MakeGarbageCollected<HTMLBRElement>(GetDocument()); AppendNode(placeholder, container, editing_state); if (editing_state->IsAborted()) return nullptr; @@ -954,7 +955,7 @@ // 4244964. DCHECK(pos.AnchorNode()->GetLayoutObject()) << pos; - HTMLBRElement* placeholder = HTMLBRElement::Create(GetDocument()); + auto* placeholder = MakeGarbageCollected<HTMLBRElement>(GetDocument()); InsertNodeAt(placeholder, pos, editing_state); if (editing_state->IsAborted()) return nullptr; @@ -1002,7 +1003,8 @@ const Position& position, EditingState* editing_state) { HTMLElement* paragraph_element = CreateDefaultParagraphElement(GetDocument()); - paragraph_element->AppendChild(HTMLBRElement::Create(GetDocument())); + paragraph_element->AppendChild( + MakeGarbageCollected<HTMLBRElement>(GetDocument())); InsertNodeAt(paragraph_element, position, editing_state); if (editing_state->IsAborted()) return nullptr; @@ -1362,7 +1364,7 @@ before_paragraph.DeepEquivalent() == after_paragraph.DeepEquivalent())) { // FIXME: Trim text between beforeParagraph and afterParagraph if they // aren't equal. - InsertNodeAt(HTMLBRElement::Create(GetDocument()), + InsertNodeAt(MakeGarbageCollected<HTMLBRElement>(GetDocument()), before_paragraph.DeepEquivalent(), editing_state); } } @@ -1540,7 +1542,7 @@ before_paragraph.DeepEquivalent() == after_paragraph.DeepEquivalent())) { // FIXME: Trim text between beforeParagraph and afterParagraph if they // aren't equal. - InsertNodeAt(HTMLBRElement::Create(GetDocument()), + InsertNodeAt(MakeGarbageCollected<HTMLBRElement>(GetDocument()), before_paragraph.DeepEquivalent(), editing_state); if (editing_state->IsAborted()) return; @@ -1669,13 +1671,13 @@ RemoveNodePreservingChildren(list_node->parentNode(), editing_state); if (editing_state->IsAborted()) return false; - new_block = HTMLLIElement::Create(GetDocument()); + new_block = MakeGarbageCollected<HTMLLIElement>(GetDocument()); } // If listNode does NOT appear at the end of the outer list item, then // behave as if in a regular paragraph. } else if (IsHTMLOListElement(*block_enclosing_list) || IsHTMLUListElement(*block_enclosing_list)) { - new_block = HTMLLIElement::Create(GetDocument()); + new_block = MakeGarbageCollected<HTMLLIElement>(GetDocument()); } } if (!new_block) @@ -1767,7 +1769,7 @@ &IsMailHTMLBlockquoteElement)) return false; - HTMLBRElement* br = HTMLBRElement::Create(GetDocument()); + auto* br = MakeGarbageCollected<HTMLBRElement>(GetDocument()); // We want to replace this quoted paragraph with an unquoted one, so insert a // br to hold the caret before the highest blockquote. InsertNodeBefore(br, highest_blockquote, editing_state); @@ -1781,7 +1783,8 @@ // foo<br><blockquote>...</blockquote> // insert a second one. if (!IsStartOfParagraph(at_br)) { - InsertNodeBefore(HTMLBRElement::Create(GetDocument()), br, editing_state); + InsertNodeBefore(MakeGarbageCollected<HTMLBRElement>(GetDocument()), br, + editing_state); if (editing_state->IsAborted()) return false; GetDocument().UpdateStyleAndLayout();
diff --git a/third_party/blink/renderer/core/editing/commands/create_link_command.cc b/third_party/blink/renderer/core/editing/commands/create_link_command.cc index a33e03b..e7022912 100644 --- a/third_party/blink/renderer/core/editing/commands/create_link_command.cc +++ b/third_party/blink/renderer/core/editing/commands/create_link_command.cc
@@ -29,6 +29,7 @@ #include "third_party/blink/renderer/core/editing/selection_template.h" #include "third_party/blink/renderer/core/editing/visible_selection.h" #include "third_party/blink/renderer/core/html/html_anchor_element.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -41,7 +42,7 @@ if (EndingSelection().IsNone()) return; - HTMLAnchorElement* anchor_element = HTMLAnchorElement::Create(GetDocument()); + auto* anchor_element = MakeGarbageCollected<HTMLAnchorElement>(GetDocument()); anchor_element->SetHref(AtomicString(url_)); if (EndingSelection().IsRange()) {
diff --git a/third_party/blink/renderer/core/editing/commands/delete_selection_command.cc b/third_party/blink/renderer/core/editing/commands/delete_selection_command.cc index f93fec3..3478647 100644 --- a/third_party/blink/renderer/core/editing/commands/delete_selection_command.cc +++ b/third_party/blink/renderer/core/editing/commands/delete_selection_command.cc
@@ -46,6 +46,7 @@ #include "third_party/blink/renderer/core/html/html_table_row_element.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/layout/layout_table_cell.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -858,8 +859,8 @@ (starts_at_empty_line_ && merge_destination.DeepEquivalent() != start_of_paragraph_to_move.DeepEquivalent())) { - InsertNodeAt(HTMLBRElement::Create(GetDocument()), upstream_start_, - editing_state); + InsertNodeAt(MakeGarbageCollected<HTMLBRElement>(GetDocument()), + upstream_start_, editing_state); if (editing_state->IsAborted()) return; GetDocument().UpdateStyleAndLayout(); @@ -1178,8 +1179,9 @@ !line_break_at_end_of_selection_to_delete; } - HTMLBRElement* placeholder = - need_placeholder_ ? HTMLBRElement::Create(GetDocument()) : nullptr; + auto* placeholder = need_placeholder_ + ? MakeGarbageCollected<HTMLBRElement>(GetDocument()) + : nullptr; if (placeholder) { if (options_.IsSanitizeMarkup()) {
diff --git a/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.cc b/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.cc index 7c423af..32424ba 100644 --- a/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.cc +++ b/third_party/blink/renderer/core/editing/commands/editing_commands_utilities.cc
@@ -45,6 +45,7 @@ #include "third_party/blink/renderer/core/html/html_html_element.h" #include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/core/layout/layout_object.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -538,11 +539,12 @@ "is corrected automatically.")); UseCounter::Count(document, WebFeature::kExecCommandAltersHTMLStructure); - Element* const root = HTMLHtmlElement::Create(document); + auto* const root = MakeGarbageCollected<HTMLHtmlElement>(document); if (existing_head) root->AppendChild(existing_head); - Element* const body = - existing_body ? existing_body : HTMLBodyElement::Create(document); + auto* const body = existing_body + ? existing_body + : MakeGarbageCollected<HTMLBodyElement>(document); if (document.documentElement() && body != document.documentElement()) body->AppendChild(document.documentElement()); root->AppendChild(body);
diff --git a/third_party/blink/renderer/core/editing/commands/editing_commands_utilities_test.cc b/third_party/blink/renderer/core/editing/commands/editing_commands_utilities_test.cc index 2c6bc8e..249ea01 100644 --- a/third_party/blink/renderer/core/editing/commands/editing_commands_utilities_test.cc +++ b/third_party/blink/renderer/core/editing/commands/editing_commands_utilities_test.cc
@@ -10,6 +10,7 @@ #include "third_party/blink/renderer/core/html/html_body_element.h" #include "third_party/blink/renderer/core/html/html_div_element.h" #include "third_party/blink/renderer/core/html/html_head_element.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -54,7 +55,7 @@ } TEST_F(EditingCommandsUtilitiesTest, TidyUpHTMLStructureFromBody) { - Element* body = HTMLBodyElement::Create(GetDocument()); + auto* body = MakeGarbageCollected<HTMLBodyElement>(GetDocument()); MakeDocumentEmpty(); GetDocument().setDesignMode("on"); GetDocument().AppendChild(body); @@ -78,7 +79,7 @@ } TEST_F(EditingCommandsUtilitiesTest, TidyUpHTMLStructureFromHead) { - Element* head = HTMLHeadElement::Create(GetDocument()); + auto* head = MakeGarbageCollected<HTMLHeadElement>(GetDocument()); MakeDocumentEmpty(); GetDocument().setDesignMode("on"); GetDocument().AppendChild(head);
diff --git a/third_party/blink/renderer/core/editing/commands/indent_outdent_command.cc b/third_party/blink/renderer/core/editing/commands/indent_outdent_command.cc index 838ea26..e90c3ba 100644 --- a/third_party/blink/renderer/core/editing/commands/indent_outdent_command.cc +++ b/third_party/blink/renderer/core/editing/commands/indent_outdent_command.cc
@@ -38,6 +38,7 @@ #include "third_party/blink/renderer/core/html/html_element.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/layout/layout_object.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -274,7 +275,7 @@ CreateVisiblePosition(visible_start_of_paragraph.DeepEquivalent()); if (visible_start_of_paragraph.IsNotNull() && !IsStartOfParagraph(visible_start_of_paragraph)) { - InsertNodeAt(HTMLBRElement::Create(GetDocument()), + InsertNodeAt(MakeGarbageCollected<HTMLBRElement>(GetDocument()), visible_start_of_paragraph.DeepEquivalent(), editing_state); if (editing_state->IsAborted()) return; @@ -285,7 +286,7 @@ CreateVisiblePosition(visible_end_of_paragraph.DeepEquivalent()); if (visible_end_of_paragraph.IsNotNull() && !IsEndOfParagraph(visible_end_of_paragraph)) - InsertNodeAt(HTMLBRElement::Create(GetDocument()), + InsertNodeAt(MakeGarbageCollected<HTMLBRElement>(GetDocument()), visible_end_of_paragraph.DeepEquivalent(), editing_state); return; } @@ -347,7 +348,7 @@ EndOfParagraph(visible_end_of_paragraph); if (start_of_paragraph_to_move.IsNull() || end_of_paragraph_to_move.IsNull()) return; - HTMLBRElement* placeholder = HTMLBRElement::Create(GetDocument()); + auto* placeholder = MakeGarbageCollected<HTMLBRElement>(GetDocument()); InsertNodeBefore(placeholder, split_blockquote_node, editing_state); if (editing_state->IsAborted()) return;
diff --git a/third_party/blink/renderer/core/editing/commands/insert_commands.cc b/third_party/blink/renderer/core/editing/commands/insert_commands.cc index b4fc117a..93b9e5e 100644 --- a/third_party/blink/renderer/core/editing/commands/insert_commands.cc +++ b/third_party/blink/renderer/core/editing/commands/insert_commands.cc
@@ -41,6 +41,7 @@ #include "third_party/blink/renderer/core/html/html_hr_element.h" #include "third_party/blink/renderer/core/html/html_image_element.h" #include "third_party/blink/renderer/core/input/event_handler.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -91,7 +92,7 @@ EditorCommandSource, const String& value) { DCHECK(frame.GetDocument()); - HTMLHRElement* const rule = HTMLHRElement::Create(*frame.GetDocument()); + auto* const rule = MakeGarbageCollected<HTMLHRElement>(*frame.GetDocument()); if (!value.IsEmpty()) rule->SetIdAttribute(AtomicString(value)); return ExecuteInsertElement(frame, rule);
diff --git a/third_party/blink/renderer/core/editing/commands/insert_line_break_command.cc b/third_party/blink/renderer/core/editing/commands/insert_line_break_command.cc index 60ed97f..a1ef62ef 100644 --- a/third_party/blink/renderer/core/editing/commands/insert_line_break_command.cc +++ b/third_party/blink/renderer/core/editing/commands/insert_line_break_command.cc
@@ -42,6 +42,7 @@ #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/layout/layout_text.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -93,7 +94,7 @@ Node* node_to_insert = nullptr; if (ShouldUseBreakElement(pos)) - node_to_insert = HTMLBRElement::Create(GetDocument()); + node_to_insert = MakeGarbageCollected<HTMLBRElement>(GetDocument()); else node_to_insert = GetDocument().createTextNode("\n");
diff --git a/third_party/blink/renderer/core/editing/commands/insert_list_command.cc b/third_party/blink/renderer/core/editing/commands/insert_list_command.cc index 0b324dec..2876169 100644 --- a/third_party/blink/renderer/core/editing/commands/insert_list_command.cc +++ b/third_party/blink/renderer/core/editing/commands/insert_list_command.cc
@@ -42,6 +42,7 @@ #include "third_party/blink/renderer/core/html/html_ulist_element.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -57,7 +58,7 @@ HTMLUListElement* InsertListCommand::FixOrphanedListChild( Node* node, EditingState* editing_state) { - HTMLUListElement* list_element = HTMLUListElement::Create(GetDocument()); + auto* list_element = MakeGarbageCollected<HTMLUListElement>(GetDocument()); InsertNodeBefore(list_element, node, editing_state); if (editing_state->IsAborted()) return nullptr; @@ -499,12 +500,12 @@ // When removing a list, we must always create a placeholder to act as a point // of insertion for the list content being removed. - HTMLBRElement* placeholder = HTMLBRElement::Create(GetDocument()); + auto* placeholder = MakeGarbageCollected<HTMLBRElement>(GetDocument()); HTMLElement* element_to_insert = placeholder; // If the content of the list item will be moved into another list, put it in // a list item so that we don't create an orphaned list child. if (EnclosingList(list_element)) { - element_to_insert = HTMLLIElement::Create(GetDocument()); + element_to_insert = MakeGarbageCollected<HTMLLIElement>(GetDocument()); AppendNode(placeholder, element_to_insert, editing_state); if (editing_state->IsAborted()) return; @@ -589,7 +590,8 @@ start, NextPositionOf(end, kCannotCrossEditingBoundary), list_tag); if (previous_list || next_list) { // Place list item into adjoining lists. - HTMLLIElement* list_item_element = HTMLLIElement::Create(GetDocument()); + auto* list_item_element = + MakeGarbageCollected<HTMLLIElement>(GetDocument()); if (previous_list) AppendNode(list_item_element, previous_list, editing_state); else @@ -653,7 +655,7 @@ InsertNodeAt(list_element, insertion_pos, editing_state); if (editing_state->IsAborted()) return; - HTMLLIElement* list_item_element = HTMLLIElement::Create(GetDocument()); + auto* list_item_element = MakeGarbageCollected<HTMLLIElement>(GetDocument()); AppendNode(list_item_element, list_element, editing_state); if (editing_state->IsAborted()) return; @@ -685,7 +687,7 @@ HTMLLIElement* list_item_element, EditingState* editing_state) { DCHECK(!list_item_element->HasChildren()); - HTMLBRElement* placeholder = HTMLBRElement::Create(GetDocument()); + auto* placeholder = MakeGarbageCollected<HTMLBRElement>(GetDocument()); AppendNode(placeholder, list_item_element, editing_state); if (editing_state->IsAborted()) return;
diff --git a/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.cc b/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.cc index 9b74042..432da89f 100644 --- a/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.cc +++ b/third_party/blink/renderer/core/editing/commands/insert_paragraph_separator_command.cc
@@ -43,6 +43,7 @@ #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/layout/layout_text.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -435,7 +436,7 @@ // it if visiblePos is at the start of a paragraph so that the // content will move down a line. if (IsStartOfParagraph(visible_pos)) { - HTMLBRElement* br = HTMLBRElement::Create(GetDocument()); + auto* br = MakeGarbageCollected<HTMLBRElement>(GetDocument()); InsertNodeAt(br, insertion_position, editing_state); if (editing_state->IsAborted()) return; @@ -544,8 +545,8 @@ // won't be one that will hold an empty line open, add a br. if (IsEndOfParagraph(visible_pos) && !LineBreakExistsAtVisiblePosition(visible_pos)) { - AppendNode(HTMLBRElement::Create(GetDocument()), block_to_insert, - editing_state); + AppendNode(MakeGarbageCollected<HTMLBRElement>(GetDocument()), + block_to_insert, editing_state); if (editing_state->IsAborted()) return; GetDocument().UpdateStyleAndLayout();
diff --git a/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc b/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc index 19ce46f..d3116ab 100644 --- a/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc +++ b/third_party/blink/renderer/core/editing/commands/replace_selection_command.cc
@@ -65,6 +65,7 @@ #include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/layout/layout_text.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" #include "third_party/blink/renderer/platform/wtf/vector.h" @@ -941,7 +942,7 @@ // To avoid this, we add a placeholder node before the start of the paragraph. if (EndOfParagraph(start_of_paragraph_to_move).DeepEquivalent() == destination.DeepEquivalent()) { - HTMLBRElement* placeholder = HTMLBRElement::Create(GetDocument()); + auto* placeholder = MakeGarbageCollected<HTMLBRElement>(GetDocument()); InsertNodeBefore(placeholder, start_of_paragraph_to_move.DeepEquivalent().AnchorNode(), editing_state); @@ -1418,7 +1419,7 @@ (unsigned)insertion_pos.ComputeEditingOffset() < enclosing_block_of_insertion_pos->NodeIndex() && !IsStartOfParagraph(start_of_inserted_content)) { - InsertNodeAt(HTMLBRElement::Create(GetDocument()), + InsertNodeAt(MakeGarbageCollected<HTMLBRElement>(GetDocument()), start_of_inserted_content.DeepEquivalent(), editing_state); if (editing_state->IsAborted()) return; @@ -1513,7 +1514,7 @@ if (should_merge_end_ && destination_node != EnclosingInline(destination_node) && EnclosingInline(destination_node)->nextSibling()) { - InsertNodeBefore(HTMLBRElement::Create(GetDocument()), + InsertNodeBefore(MakeGarbageCollected<HTMLBRElement>(GetDocument()), inserted_nodes.RefNode(), editing_state); if (editing_state->IsAborted()) return; @@ -1530,7 +1531,7 @@ VisiblePosition end_of_inserted_content = PositionAtEndOfInsertedContent(); if (StartOfParagraph(end_of_inserted_content).DeepEquivalent() == start_of_paragraph_to_move_position.GetPosition()) { - InsertNodeAt(HTMLBRElement::Create(GetDocument()), + InsertNodeAt(MakeGarbageCollected<HTMLBRElement>(GetDocument()), end_of_inserted_content.DeepEquivalent(), editing_state); if (editing_state->IsAborted()) return; @@ -1599,7 +1600,8 @@ Element* enclosing_block_element = EnclosingBlock( end_of_inserted_content.DeepEquivalent().AnchorNode()); if (IsListItem(enclosing_block_element)) { - HTMLLIElement* new_list_item = HTMLLIElement::Create(GetDocument()); + auto* new_list_item = + MakeGarbageCollected<HTMLLIElement>(GetDocument()); InsertNodeAfter(new_list_item, enclosing_block_element, editing_state); if (editing_state->IsAborted())
diff --git a/third_party/blink/renderer/core/editing/commands/unlink_command.cc b/third_party/blink/renderer/core/editing/commands/unlink_command.cc index 80625e3..c65a0d1 100644 --- a/third_party/blink/renderer/core/editing/commands/unlink_command.cc +++ b/third_party/blink/renderer/core/editing/commands/unlink_command.cc
@@ -26,6 +26,7 @@ #include "third_party/blink/renderer/core/editing/commands/unlink_command.h" #include "third_party/blink/renderer/core/html/html_anchor_element.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -40,7 +41,8 @@ if (!EndingSelection().IsRange()) return; - RemoveStyledElement(HTMLAnchorElement::Create(GetDocument()), editing_state); + RemoveStyledElement(MakeGarbageCollected<HTMLAnchorElement>(GetDocument()), + editing_state); } } // namespace blink
diff --git a/third_party/blink/renderer/core/editing/editing_utilities.cc b/third_party/blink/renderer/core/editing/editing_utilities.cc index 5c49f32..e66f1a2 100644 --- a/third_party/blink/renderer/core/editing/editing_utilities.cc +++ b/third_party/blink/renderer/core/editing/editing_utilities.cc
@@ -74,6 +74,7 @@ #include "third_party/blink/renderer/core/layout/layout_table_cell.h" #include "third_party/blink/renderer/core/svg/svg_image_element.h" #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h" +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" @@ -1257,7 +1258,7 @@ case EditorParagraphSeparator::kIsDiv: return HTMLDivElement::Create(document); case EditorParagraphSeparator::kIsP: - return HTMLParagraphElement::Create(document); + return MakeGarbageCollected<HTMLParagraphElement>(document); } NOTREACHED();
diff --git a/third_party/blink/renderer/core/editing/serializers/serialization.cc b/third_party/blink/renderer/core/editing/serializers/serialization.cc index 4a334bcc..89f7d6d5 100644 --- a/third_party/blink/renderer/core/editing/serializers/serialization.cc +++ b/third_party/blink/renderer/core/editing/serializers/serialization.cc
@@ -65,6 +65,7 @@ #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h" #include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h" +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" @@ -338,7 +339,7 @@ ParserContentPolicy parser_content_policy) { // We use a fake body element here to trick the HTML parser to using the // InBody insertion mode. - HTMLBodyElement* fake_body = HTMLBodyElement::Create(document); + auto* fake_body = MakeGarbageCollected<HTMLBodyElement>(document); DocumentFragment* fragment = DocumentFragment::Create(document); fragment->ParseHTML(markup, fake_body, parser_content_policy); @@ -468,7 +469,7 @@ Document& document = paragraph->GetDocument(); if (string.IsEmpty()) { - paragraph->AppendChild(HTMLBRElement::Create(document)); + paragraph->AppendChild(MakeGarbageCollected<HTMLBRElement>(document)); return; } @@ -557,7 +558,7 @@ ShouldPreserveNewline(context)) { fragment->AppendChild(document.createTextNode(string)); if (string.EndsWith('\n')) { - HTMLBRElement* element = HTMLBRElement::Create(document); + auto* element = MakeGarbageCollected<HTMLBRElement>(document); element->setAttribute(kClassAttr, AppleInterchangeNewline); fragment->AppendChild(element); } @@ -587,7 +588,7 @@ Element* element = nullptr; if (s.IsEmpty() && i + 1 == num_lines) { // For last line, use the "magic BR" rather than a P. - element = HTMLBRElement::Create(document); + element = MakeGarbageCollected<HTMLBRElement>(document); element->setAttribute(kClassAttr, AppleInterchangeNewline); } else { if (use_clones_of_enclosing_block) @@ -645,7 +646,7 @@ // Unfortunately, that's an implementation detail of the parser. We achieve // that effect here by passing in a fake body element as context for the // fragment. - HTMLBodyElement* fake_body = HTMLBodyElement::Create(output_doc); + auto* fake_body = MakeGarbageCollected<HTMLBodyElement>(output_doc); fragment->ParseHTML(source_string, fake_body); } else if (source_mime_type == "text/plain") { fragment->ParserAppendChild(Text::Create(output_doc, source_string));
diff --git a/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc b/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc index 56cc969..25c68a09 100644 --- a/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc +++ b/third_party/blink/renderer/core/exported/web_associated_url_loader_impl_test.cc
@@ -635,8 +635,8 @@ } // Test that the loader filters response headers according to the CORS standard. -TEST_F(WebAssociatedURLLoaderTest, CrossOriginHeaderWhitelisting) { - // Test that whitelisted headers are returned without exposing them. +TEST_F(WebAssociatedURLLoaderTest, CrossOriginHeaderSafelisting) { + // Test that safelisted headers are returned without exposing them. EXPECT_TRUE(CheckAccessControlHeaders("cache-control", false)); EXPECT_TRUE(CheckAccessControlHeaders("content-language", false)); EXPECT_TRUE(CheckAccessControlHeaders("content-type", false)); @@ -644,21 +644,21 @@ EXPECT_TRUE(CheckAccessControlHeaders("last-modified", false)); EXPECT_TRUE(CheckAccessControlHeaders("pragma", false)); - // Test that non-whitelisted headers aren't returned. - EXPECT_FALSE(CheckAccessControlHeaders("non-whitelisted", false)); + // Test that non-safelisted headers aren't returned. + EXPECT_FALSE(CheckAccessControlHeaders("non-safelisted", false)); // Test that Set-Cookie headers aren't returned. EXPECT_FALSE(CheckAccessControlHeaders("Set-Cookie", false)); EXPECT_FALSE(CheckAccessControlHeaders("Set-Cookie2", false)); - // Test that exposed headers that aren't whitelisted are returned. - EXPECT_TRUE(CheckAccessControlHeaders("non-whitelisted", true)); + // Test that exposed headers that aren't safelisted are returned. + EXPECT_TRUE(CheckAccessControlHeaders("non-safelisted", true)); // Test that Set-Cookie headers aren't returned, even if exposed. EXPECT_FALSE(CheckAccessControlHeaders("Set-Cookie", true)); } -// Test that the loader can allow non-whitelisted response headers for trusted +// Test that the loader can allow non-safelisted response headers for trusted // CORS loads. TEST_F(WebAssociatedURLLoaderTest, CrossOriginHeaderAllowResponseHeaders) { KURL url = @@ -667,7 +667,7 @@ request.SetFetchRequestMode(network::mojom::FetchRequestMode::kCors); request.SetFetchCredentialsMode(network::mojom::FetchCredentialsMode::kOmit); - WebString header_name_string(WebString::FromUTF8("non-whitelisted")); + WebString header_name_string(WebString::FromUTF8("non-safelisted")); expected_response_ = WebURLResponse(); expected_response_.SetMimeType("text/html"); expected_response_.SetHttpStatusCode(200); @@ -677,8 +677,8 @@ url, expected_response_, frame_file_path_); WebAssociatedURLLoaderOptions options; - options.expose_all_response_headers = - true; // This turns off response whitelisting. + // This turns off response safelisting. + options.expose_all_response_headers = true; expected_loader_ = CreateAssociatedURLLoader(options); EXPECT_TRUE(expected_loader_); expected_loader_->LoadAsynchronously(request, this);
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc index 339210c..f4088be9c 100644 --- a/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc +++ b/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc
@@ -12,6 +12,7 @@ #include "third_party/blink/renderer/core/html/html_script_element.h" #include "third_party/blink/renderer/core/testing/null_execution_context.h" #include "third_party/blink/renderer/platform/crypto.h" +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/loader/fetch/integrity_metadata.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_response.h" @@ -728,8 +729,8 @@ << "`, Nonce: `" << test.nonce << "`"); unsigned expected_reports = test.allowed ? 0u : 1u; - auto* element = - HTMLScriptElement::Create(*document, CreateElementFlags::ByParser()); + auto* element = MakeGarbageCollected<HTMLScriptElement>( + *document, CreateElementFlags::ByParser()); // Enforce 'script-src' Persistent<ContentSecurityPolicy> policy = @@ -1523,8 +1524,8 @@ String context_url; String nonce; OrdinalNumber ordinal_number; - Element* element = - HTMLScriptElement::Create(*document, CreateElementFlags::ByParser()); + auto* element = MakeGarbageCollected<HTMLScriptElement>( + *document, CreateElementFlags::ByParser()); EXPECT_TRUE(csp->Headers().IsEmpty()); EXPECT_TRUE(csp->AllowInline(ContentSecurityPolicy::InlineType::kNavigation,
diff --git a/third_party/blink/renderer/core/frame/local_dom_window.cc b/third_party/blink/renderer/core/frame/local_dom_window.cc index 6b0d4fb..1bc7f3c2 100644 --- a/third_party/blink/renderer/core/frame/local_dom_window.cc +++ b/third_party/blink/renderer/core/frame/local_dom_window.cc
@@ -60,7 +60,6 @@ #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h" #include "third_party/blink/renderer/core/editing/editor.h" #include "third_party/blink/renderer/core/editing/frame_selection.h" -#include "third_party/blink/renderer/core/events/current_input_event.h" #include "third_party/blink/renderer/core/events/hash_change_event.h" #include "third_party/blink/renderer/core/events/message_event.h" #include "third_party/blink/renderer/core/events/page_transition_event.h" @@ -1491,17 +1490,15 @@ // TODO(domfarolino): Stop setting ResourceRequest's HTTP Referrer and store // this is a separate member. See https://crbug.com/850813. frame_request.GetResourceRequest().SetHttpReferrer( - SecurityPolicy::GenerateReferrer(active_document->GetReferrerPolicy(), - completed_url, - active_document->OutgoingReferrer())); + SecurityPolicy::GenerateReferrer( + active_document->GetReferrerPolicy(), completed_url, + window_features.noreferrer ? Referrer::NoReferrer() + : active_document->OutgoingReferrer())); frame_request.GetResourceRequest().SetHasUserGesture( LocalFrame::HasTransientUserActivation(GetFrame())); GetFrame()->MaybeLogAdClickNavigation(); - if (const WebInputEvent* input_event = CurrentInputEvent::Get()) - frame_request.SetInputStartTime(input_event->TimeStamp()); - FrameTree::FindResult result = GetFrame()->Tree().FindOrCreateFrameForNavigation(frame_request); if (!result.frame)
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index d88fe9e..0b1c652 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -62,7 +62,6 @@ #include "third_party/blink/renderer/core/editing/serializers/serialization.h" #include "third_party/blink/renderer/core/editing/spellcheck/spell_checker.h" #include "third_party/blink/renderer/core/editing/suggestion/text_suggestion_controller.h" -#include "third_party/blink/renderer/core/events/current_input_event.h" #include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h" #include "third_party/blink/renderer/core/frame/ad_tracker.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" @@ -543,8 +542,6 @@ nullptr, loader_.ResourceRequestForReload( load_type, ClientRedirectPolicy::kClientRedirect)); request.SetClientRedirect(ClientRedirectPolicy::kClientRedirect); - if (const WebInputEvent* input_event = CurrentInputEvent::Get()) - request.SetInputStartTime(input_event->TimeStamp()); probe::FrameScheduledNavigation(this, request.GetResourceRequest().Url(), 0.0, ClientNavigationReason::kReload); probe::FrameRequestedNavigation(this, request.GetResourceRequest().Url(),
diff --git a/third_party/blink/renderer/core/html/custom/custom_element_definition.cc b/third_party/blink/renderer/core/html/custom/custom_element_definition.cc index ef9e100..ea22881 100644 --- a/third_party/blink/renderer/core/html/custom/custom_element_definition.cc +++ b/third_party/blink/renderer/core/html/custom/custom_element_definition.cc
@@ -17,6 +17,7 @@ #include "third_party/blink/renderer/core/html/html_element.h" #include "third_party/blink/renderer/core/html_element_factory.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -104,10 +105,10 @@ if (element) { element->SetIsValue(Descriptor().GetName()); } else { - element = - HTMLElement::Create(QualifiedName(g_null_atom, Descriptor().LocalName(), - html_names::xhtmlNamespaceURI), - document); + element = MakeGarbageCollected<HTMLElement>( + QualifiedName(g_null_atom, Descriptor().LocalName(), + html_names::xhtmlNamespaceURI), + document); } // TODO(davaajav): write this as one call to setCustomElementState instead of // two @@ -162,7 +163,7 @@ // interface, with no attributes, namespace set to the HTML namespace, // namespace prefix set to prefix, local name set to localName, custom // element state set to "undefined", and node document set to document. - HTMLElement* element = HTMLElement::Create(tag_name, document); + auto* element = MakeGarbageCollected<HTMLElement>(tag_name, document); element->SetCustomElementState(CustomElementState::kUndefined); // 6.2.2. Enqueue a custom element upgrade reaction given result and // definition.
diff --git a/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.cc b/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.cc index eb83881..f1c895d 100644 --- a/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.cc +++ b/third_party/blink/renderer/core/html/custom/v0_custom_element_registration_context.cc
@@ -41,6 +41,7 @@ #include "third_party/blink/renderer/core/svg/svg_unknown_element.h" #include "third_party/blink/renderer/core/svg_names.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -77,7 +78,7 @@ Element* element; if (html_names::xhtmlNamespaceURI == tag_name.NamespaceURI()) { - element = HTMLElement::Create(tag_name, document); + element = MakeGarbageCollected<HTMLElement>(tag_name, document); } else if (svg_names::kNamespaceURI == tag_name.NamespaceURI()) { element = SVGUnknownElement::Create(tag_name, document); } else {
diff --git a/third_party/blink/renderer/core/html/forms/html_form_element.cc b/third_party/blink/renderer/core/html/forms/html_form_element.cc index 4f8ad23..6f13506 100644 --- a/third_party/blink/renderer/core/html/forms/html_form_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_form_element.cc
@@ -39,7 +39,6 @@ #include "third_party/blink/renderer/core/dom/events/scoped_event_queue.h" #include "third_party/blink/renderer/core/dom/node_lists_node_data.h" #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h" -#include "third_party/blink/renderer/core/events/current_input_event.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/local_frame.h" @@ -498,8 +497,6 @@ frame_load_request.SetClientRedirect(ClientRedirectPolicy::kClientRedirect); frame_load_request.GetResourceRequest().SetHasUserGesture( LocalFrame::HasTransientUserActivation(GetDocument().GetFrame())); - if (const WebInputEvent* input_event = CurrentInputEvent::Get()) - frame_load_request.SetInputStartTime(input_event->TimeStamp()); GetDocument().GetFrame()->Navigate(frame_load_request, WebFrameLoadType::kStandard); }
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element_test.cc b/third_party/blink/renderer/core/html/forms/html_input_element_test.cc index 3cf36de5..7816ecd 100644 --- a/third_party/blink/renderer/core/html/forms/html_input_element_test.cc +++ b/third_party/blink/renderer/core/html/forms/html_input_element_test.cc
@@ -20,6 +20,7 @@ #include "third_party/blink/renderer/core/html/html_html_element.h" #include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -96,8 +97,9 @@ TEST_F(HTMLInputElementTest, NoAssertWhenMovedInNewDocument) { Document* document_without_frame = Document::CreateForTest(); EXPECT_EQ(nullptr, document_without_frame->GetPage()); - HTMLHtmlElement* html = HTMLHtmlElement::Create(*document_without_frame); - html->AppendChild(HTMLBodyElement::Create(*document_without_frame)); + auto* html = MakeGarbageCollected<HTMLHtmlElement>(*document_without_frame); + html->AppendChild( + MakeGarbageCollected<HTMLBodyElement>(*document_without_frame)); // Create an input element with type "range" inside a document without frame. ToHTMLBodyElement(html->firstChild())
diff --git a/third_party/blink/renderer/core/html/forms/html_output_element.cc b/third_party/blink/renderer/core/html/forms/html_output_element.cc index a70d64b..900980c 100644 --- a/third_party/blink/renderer/core/html/forms/html_output_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_output_element.cc
@@ -35,7 +35,7 @@ namespace blink { -inline HTMLOutputElement::HTMLOutputElement(Document& document) +HTMLOutputElement::HTMLOutputElement(Document& document) : HTMLFormControlElement(html_names::kOutputTag, document), is_default_value_mode_(true), default_value_(""),
diff --git a/third_party/blink/renderer/core/html/forms/html_output_element_test.cc b/third_party/blink/renderer/core/html/forms/html_output_element_test.cc index 92ab80a..49e6d1e2 100644 --- a/third_party/blink/renderer/core/html/forms/html_output_element_test.cc +++ b/third_party/blink/renderer/core/html/forms/html_output_element_test.cc
@@ -8,13 +8,14 @@ #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_token_list.h" #include "third_party/blink/renderer/core/html_names.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { TEST(HTMLLinkElementSizesAttributeTest, setHTMLForProperty_updatesForAttribute) { Document* document = Document::CreateForTest(); - HTMLOutputElement* element = HTMLOutputElement::Create(*document); + auto* element = MakeGarbageCollected<HTMLOutputElement>(*document); EXPECT_EQ(g_null_atom, element->getAttribute(html_names::kForAttr)); element->htmlFor()->setValue(" strawberry "); EXPECT_EQ(" strawberry ", element->getAttribute(html_names::kForAttr)); @@ -22,7 +23,7 @@ TEST(HTMLOutputElementTest, setForAttribute_updatesHTMLForPropertyValue) { Document* document = Document::CreateForTest(); - HTMLOutputElement* element = HTMLOutputElement::Create(*document); + auto* element = MakeGarbageCollected<HTMLOutputElement>(*document); DOMTokenList* for_tokens = element->htmlFor(); EXPECT_EQ(g_null_atom, for_tokens->value()); element->setAttribute(html_names::kForAttr, "orange grape");
diff --git a/third_party/blink/renderer/core/html/forms/text_control_element.cc b/third_party/blink/renderer/core/html/forms/text_control_element.cc index 03179c3..a747afa 100644 --- a/third_party/blink/renderer/core/html/forms/text_control_element.cc +++ b/third_party/blink/renderer/core/html/forms/text_control_element.cc
@@ -58,6 +58,7 @@ #include "third_party/blink/renderer/platform/bindings/exception_messages.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/heap/handle.h" +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" namespace blink { @@ -786,7 +787,7 @@ } Node* TextControlElement::CreatePlaceholderBreakElement() const { - return HTMLBRElement::Create(GetDocument()); + return MakeGarbageCollected<HTMLBRElement>(GetDocument()); } void TextControlElement::AddPlaceholderBreakElementIfNecessary() {
diff --git a/third_party/blink/renderer/core/html/html_anchor_element.cc b/third_party/blink/renderer/core/html/html_anchor_element.cc index 071cfcab..94733fe 100644 --- a/third_party/blink/renderer/core/html/html_anchor_element.cc +++ b/third_party/blink/renderer/core/html/html_anchor_element.cc
@@ -50,6 +50,7 @@ #include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/trustedtypes/trusted_types_util.h" #include "third_party/blink/renderer/core/trustedtypes/trusted_url.h" +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/weborigin/security_policy.h" @@ -58,6 +59,9 @@ using namespace html_names; +HTMLAnchorElement::HTMLAnchorElement(Document& document) + : HTMLAnchorElement(kATag, document) {} + HTMLAnchorElement::HTMLAnchorElement(const QualifiedName& tag_name, Document& document) : HTMLElement(tag_name, document),
diff --git a/third_party/blink/renderer/core/html/html_anchor_element.h b/third_party/blink/renderer/core/html/html_anchor_element.h index f4ca628..e8346f5 100644 --- a/third_party/blink/renderer/core/html/html_anchor_element.h +++ b/third_party/blink/renderer/core/html/html_anchor_element.h
@@ -67,6 +67,7 @@ public: static HTMLAnchorElement* Create(Document&); + HTMLAnchorElement(Document& document); HTMLAnchorElement(const QualifiedName&, Document&); ~HTMLAnchorElement() override;
diff --git a/third_party/blink/renderer/core/html/html_base_element.cc b/third_party/blink/renderer/core/html/html_base_element.cc index 607a6676..f3010d9 100644 --- a/third_party/blink/renderer/core/html/html_base_element.cc +++ b/third_party/blink/renderer/core/html/html_base_element.cc
@@ -34,7 +34,7 @@ using namespace html_names; -inline HTMLBaseElement::HTMLBaseElement(Document& document) +HTMLBaseElement::HTMLBaseElement(Document& document) : HTMLElement(kBaseTag, document) {} DEFINE_NODE_FACTORY(HTMLBaseElement)
diff --git a/third_party/blink/renderer/core/html/html_body_element.cc b/third_party/blink/renderer/core/html/html_body_element.cc index 0378241..045c453 100644 --- a/third_party/blink/renderer/core/html/html_body_element.cc +++ b/third_party/blink/renderer/core/html/html_body_element.cc
@@ -42,7 +42,7 @@ using namespace html_names; -inline HTMLBodyElement::HTMLBodyElement(Document& document) +HTMLBodyElement::HTMLBodyElement(Document& document) : HTMLElement(kBodyTag, document) {} DEFINE_NODE_FACTORY(HTMLBodyElement)
diff --git a/third_party/blink/renderer/core/html/html_br_element.cc b/third_party/blink/renderer/core/html/html_br_element.cc index 1c654fd..c3938381 100644 --- a/third_party/blink/renderer/core/html/html_br_element.cc +++ b/third_party/blink/renderer/core/html/html_br_element.cc
@@ -31,7 +31,7 @@ using namespace html_names; -inline HTMLBRElement::HTMLBRElement(Document& document) +HTMLBRElement::HTMLBRElement(Document& document) : HTMLElement(kBrTag, document) {} DEFINE_NODE_FACTORY(HTMLBRElement)
diff --git a/third_party/blink/renderer/core/html/html_element.cc b/third_party/blink/renderer/core/html/html_element.cc index b5a0254..8803bea1 100644 --- a/third_party/blink/renderer/core/html/html_element.cc +++ b/third_party/blink/renderer/core/html/html_element.cc
@@ -75,6 +75,7 @@ #include "third_party/blink/renderer/core/trustedtypes/trusted_script.h" #include "third_party/blink/renderer/core/xml_names.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/language.h" #include "third_party/blink/renderer/platform/text/bidi_resolver.h" #include "third_party/blink/renderer/platform/text/bidi_text_run.h" @@ -688,7 +689,7 @@ if (i == length) break; - fragment->AppendChild(HTMLBRElement::Create(GetDocument()), + fragment->AppendChild(MakeGarbageCollected<HTMLBRElement>(GetDocument()), exception_state); if (exception_state.HadException()) return nullptr;
diff --git a/third_party/blink/renderer/core/html/html_element.h b/third_party/blink/renderer/core/html/html_element.h index 75cd11af..7edcee3 100644 --- a/third_party/blink/renderer/core/html/html_element.h +++ b/third_party/blink/renderer/core/html/html_element.h
@@ -53,6 +53,8 @@ public: DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLElement); + HTMLElement(const QualifiedName& tag_name, Document&, ConstructionType); + bool HasTagName(const HTMLQualifiedName& name) const { return HasLocalName(name.LocalName()); } @@ -146,8 +148,6 @@ bool IsFormAssociatedCustomElement() const; protected: - HTMLElement(const QualifiedName& tag_name, Document&, ConstructionType); - enum AllowPercentage { kDontAllowPercentageValues, kAllowPercentageValues }; void AddHTMLLengthToStyle(MutableCSSPropertyValueSet*, CSSPropertyID,
diff --git a/third_party/blink/renderer/core/html/html_font_element.cc b/third_party/blink/renderer/core/html/html_font_element.cc index e2188d3..f0ca10ec 100644 --- a/third_party/blink/renderer/core/html/html_font_element.cc +++ b/third_party/blink/renderer/core/html/html_font_element.cc
@@ -39,7 +39,7 @@ using namespace cssvalue; using namespace html_names; -inline HTMLFontElement::HTMLFontElement(Document& document) +HTMLFontElement::HTMLFontElement(Document& document) : HTMLElement(kFontTag, document) {} DEFINE_NODE_FACTORY(HTMLFontElement)
diff --git a/third_party/blink/renderer/core/html/html_frame_element.cc b/third_party/blink/renderer/core/html/html_frame_element.cc index eddbc7d2..05213b3 100644 --- a/third_party/blink/renderer/core/html/html_frame_element.cc +++ b/third_party/blink/renderer/core/html/html_frame_element.cc
@@ -32,7 +32,7 @@ using namespace html_names; -inline HTMLFrameElement::HTMLFrameElement(Document& document) +HTMLFrameElement::HTMLFrameElement(Document& document) : HTMLFrameElementBase(kFrameTag, document), frame_border_(true), frame_border_set_(false) {}
diff --git a/third_party/blink/renderer/core/html/html_frame_element_test.cc b/third_party/blink/renderer/core/html/html_frame_element_test.cc index 4be6b74..994189d 100644 --- a/third_party/blink/renderer/core/html/html_frame_element_test.cc +++ b/third_party/blink/renderer/core/html/html_frame_element_test.cc
@@ -6,6 +6,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -20,7 +21,7 @@ document->SetURL(document_url); document->UpdateSecurityOrigin(SecurityOrigin::Create(document_url)); - HTMLFrameElement* frame_element = HTMLFrameElement::Create(*document); + auto* frame_element = MakeGarbageCollected<HTMLFrameElement>(*document); frame_element->setAttribute(html_names::kSrcAttr, "http://example.net/"); frame_element->UpdateContainerPolicyForTests();
diff --git a/third_party/blink/renderer/core/html/html_head_element.cc b/third_party/blink/renderer/core/html/html_head_element.cc index e378e21..4695798 100644 --- a/third_party/blink/renderer/core/html/html_head_element.cc +++ b/third_party/blink/renderer/core/html/html_head_element.cc
@@ -29,7 +29,7 @@ using namespace html_names; -inline HTMLHeadElement::HTMLHeadElement(Document& document) +HTMLHeadElement::HTMLHeadElement(Document& document) : HTMLElement(kHeadTag, document) {} DEFINE_NODE_FACTORY(HTMLHeadElement)
diff --git a/third_party/blink/renderer/core/html/html_hr_element.cc b/third_party/blink/renderer/core/html/html_hr_element.cc index debcadbe..6dc2858 100644 --- a/third_party/blink/renderer/core/html/html_hr_element.cc +++ b/third_party/blink/renderer/core/html/html_hr_element.cc
@@ -35,7 +35,7 @@ using namespace cssvalue; using namespace html_names; -inline HTMLHRElement::HTMLHRElement(Document& document) +HTMLHRElement::HTMLHRElement(Document& document) : HTMLElement(kHrTag, document) {} DEFINE_NODE_FACTORY(HTMLHRElement)
diff --git a/third_party/blink/renderer/core/html/html_html_element.cc b/third_party/blink/renderer/core/html/html_html_element.cc index 3a36724..d847e44 100644 --- a/third_party/blink/renderer/core/html/html_html_element.cc +++ b/third_party/blink/renderer/core/html/html_html_element.cc
@@ -38,7 +38,7 @@ using namespace html_names; -inline HTMLHtmlElement::HTMLHtmlElement(Document& document) +HTMLHtmlElement::HTMLHtmlElement(Document& document) : HTMLElement(kHTMLTag, document) {} DEFINE_NODE_FACTORY(HTMLHtmlElement)
diff --git a/third_party/blink/renderer/core/html/html_iframe_element.cc b/third_party/blink/renderer/core/html/html_iframe_element.cc index 601ac65..a6a5518 100644 --- a/third_party/blink/renderer/core/html/html_iframe_element.cc +++ b/third_party/blink/renderer/core/html/html_iframe_element.cc
@@ -44,7 +44,7 @@ using namespace html_names; -inline HTMLIFrameElement::HTMLIFrameElement(Document& document) +HTMLIFrameElement::HTMLIFrameElement(Document& document) : HTMLFrameElementBase(kIFrameTag, document), collapsed_by_client_(false), sandbox_(MakeGarbageCollected<HTMLIFrameElementSandbox>(this)),
diff --git a/third_party/blink/renderer/core/html/html_iframe_element_test.cc b/third_party/blink/renderer/core/html/html_iframe_element_test.cc index 08165325b..9ab7b17 100644 --- a/third_party/blink/renderer/core/html/html_iframe_element_test.cc +++ b/third_party/blink/renderer/core/html/html_iframe_element_test.cc
@@ -7,6 +7,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/feature_policy/feature_policy.h" +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h" namespace blink { @@ -20,144 +21,119 @@ return element->GetOriginForFeaturePolicy(); } + void SetUp() final { + document_ = Document::CreateForTest(); + const KURL document_url("http://example.com"); + document_->SetURL(document_url); + document_->UpdateSecurityOrigin(SecurityOrigin::Create(document_url)); + + frame_element_ = MakeGarbageCollected<HTMLIFrameElement>(*document_); + } + + void TearDown() final { + frame_element_.Clear(); + document_.Clear(); + } + protected: const PolicyValue min_value = PolicyValue(false); const PolicyValue max_value = PolicyValue(true); + + Persistent<Document> document_; + Persistent<HTMLIFrameElement> frame_element_; }; // Test that the correct origin is used when constructing the container policy, // and that frames which should inherit their parent document's origin do so. TEST_F(HTMLIFrameElementTest, FramesUseCorrectOrigin) { - Document* document = Document::CreateForTest(); - const KURL document_url("http://example.com"); - document->SetURL(document_url); - document->UpdateSecurityOrigin(SecurityOrigin::Create(document_url)); - - HTMLIFrameElement* frame_element = HTMLIFrameElement::Create(*document); - - frame_element->setAttribute(html_names::kSrcAttr, "about:blank"); + frame_element_->setAttribute(html_names::kSrcAttr, "about:blank"); scoped_refptr<const SecurityOrigin> effective_origin = - GetOriginForFeaturePolicy(frame_element); + GetOriginForFeaturePolicy(frame_element_); EXPECT_TRUE( - effective_origin->IsSameSchemeHostPort(document->GetSecurityOrigin())); + effective_origin->IsSameSchemeHostPort(document_->GetSecurityOrigin())); - frame_element->setAttribute(html_names::kSrcAttr, - "data:text/html;base64,PHRpdGxlPkFCQzwvdGl0bGU+"); - effective_origin = GetOriginForFeaturePolicy(frame_element); + frame_element_->setAttribute( + html_names::kSrcAttr, "data:text/html;base64,PHRpdGxlPkFCQzwvdGl0bGU+"); + effective_origin = GetOriginForFeaturePolicy(frame_element_); EXPECT_FALSE( - effective_origin->IsSameSchemeHostPort(document->GetSecurityOrigin())); + effective_origin->IsSameSchemeHostPort(document_->GetSecurityOrigin())); EXPECT_TRUE(effective_origin->IsOpaque()); - frame_element->setAttribute(html_names::kSrcAttr, "http://example.net/"); - effective_origin = GetOriginForFeaturePolicy(frame_element); + frame_element_->setAttribute(html_names::kSrcAttr, "http://example.net/"); + effective_origin = GetOriginForFeaturePolicy(frame_element_); EXPECT_FALSE( - effective_origin->IsSameSchemeHostPort(document->GetSecurityOrigin())); + effective_origin->IsSameSchemeHostPort(document_->GetSecurityOrigin())); EXPECT_FALSE(effective_origin->IsOpaque()); } // Test that a unique origin is used when constructing the container policy in a // sandboxed iframe. TEST_F(HTMLIFrameElementTest, SandboxFramesUseCorrectOrigin) { - Document* document = Document::CreateForTest(); - const KURL document_url("http://example.com"); - document->SetURL(document_url); - document->UpdateSecurityOrigin(SecurityOrigin::Create(document_url)); - - HTMLIFrameElement* frame_element = HTMLIFrameElement::Create(*document); - - frame_element->setAttribute(html_names::kSandboxAttr, ""); - frame_element->setAttribute(html_names::kSrcAttr, "http://example.com/"); + frame_element_->setAttribute(html_names::kSandboxAttr, ""); + frame_element_->setAttribute(html_names::kSrcAttr, "http://example.com/"); scoped_refptr<const SecurityOrigin> effective_origin = - GetOriginForFeaturePolicy(frame_element); + GetOriginForFeaturePolicy(frame_element_); EXPECT_FALSE( - effective_origin->IsSameSchemeHostPort(document->GetSecurityOrigin())); + effective_origin->IsSameSchemeHostPort(document_->GetSecurityOrigin())); EXPECT_TRUE(effective_origin->IsOpaque()); - frame_element->setAttribute(html_names::kSrcAttr, "http://example.net/"); - effective_origin = GetOriginForFeaturePolicy(frame_element); + frame_element_->setAttribute(html_names::kSrcAttr, "http://example.net/"); + effective_origin = GetOriginForFeaturePolicy(frame_element_); EXPECT_FALSE( - effective_origin->IsSameSchemeHostPort(document->GetSecurityOrigin())); + effective_origin->IsSameSchemeHostPort(document_->GetSecurityOrigin())); EXPECT_TRUE(effective_origin->IsOpaque()); } // Test that a sandboxed iframe with the allow-same-origin sandbox flag uses the // parent document's origin for the container policy. TEST_F(HTMLIFrameElementTest, SameOriginSandboxFramesUseCorrectOrigin) { - Document* document = Document::CreateForTest(); - const KURL document_url("http://example.com"); - document->SetURL(document_url); - document->UpdateSecurityOrigin(SecurityOrigin::Create(document_url)); - - HTMLIFrameElement* frame_element = HTMLIFrameElement::Create(*document); - - frame_element->setAttribute(html_names::kSandboxAttr, "allow-same-origin"); - frame_element->setAttribute(html_names::kSrcAttr, "http://example.com/"); + frame_element_->setAttribute(html_names::kSandboxAttr, "allow-same-origin"); + frame_element_->setAttribute(html_names::kSrcAttr, "http://example.com/"); scoped_refptr<const SecurityOrigin> effective_origin = - GetOriginForFeaturePolicy(frame_element); + GetOriginForFeaturePolicy(frame_element_); EXPECT_TRUE( - effective_origin->IsSameSchemeHostPort(document->GetSecurityOrigin())); + effective_origin->IsSameSchemeHostPort(document_->GetSecurityOrigin())); EXPECT_FALSE(effective_origin->IsOpaque()); } // Test that the parent document's origin is used when constructing the // container policy in a srcdoc iframe. TEST_F(HTMLIFrameElementTest, SrcdocFramesUseCorrectOrigin) { - Document* document = Document::CreateForTest(); - const KURL document_url("http://example.com"); - document->SetURL(document_url); - document->UpdateSecurityOrigin(SecurityOrigin::Create(document_url)); - - HTMLIFrameElement* frame_element = HTMLIFrameElement::Create(*document); - - frame_element->setAttribute(html_names::kSrcdocAttr, "<title>title</title>"); + frame_element_->setAttribute(html_names::kSrcdocAttr, "<title>title</title>"); scoped_refptr<const SecurityOrigin> effective_origin = - GetOriginForFeaturePolicy(frame_element); + GetOriginForFeaturePolicy(frame_element_); EXPECT_TRUE( - effective_origin->IsSameSchemeHostPort(document->GetSecurityOrigin())); + effective_origin->IsSameSchemeHostPort(document_->GetSecurityOrigin())); } // Test that a unique origin is used when constructing the container policy in a // sandboxed iframe with a srcdoc. TEST_F(HTMLIFrameElementTest, SandboxedSrcdocFramesUseCorrectOrigin) { - Document* document = Document::CreateForTest(); - const KURL document_url("http://example.com"); - document->SetURL(document_url); - document->UpdateSecurityOrigin(SecurityOrigin::Create(document_url)); - - HTMLIFrameElement* frame_element = HTMLIFrameElement::Create(*document); - - frame_element->setAttribute(html_names::kSandboxAttr, ""); - frame_element->setAttribute(html_names::kSrcdocAttr, "<title>title</title>"); + frame_element_->setAttribute(html_names::kSandboxAttr, ""); + frame_element_->setAttribute(html_names::kSrcdocAttr, "<title>title</title>"); scoped_refptr<const SecurityOrigin> effective_origin = - GetOriginForFeaturePolicy(frame_element); + GetOriginForFeaturePolicy(frame_element_); EXPECT_FALSE( - effective_origin->IsSameSchemeHostPort(document->GetSecurityOrigin())); + effective_origin->IsSameSchemeHostPort(document_->GetSecurityOrigin())); EXPECT_TRUE(effective_origin->IsOpaque()); } // Test that iframes with relative src urls correctly construct their origin // relative to the parent document. TEST_F(HTMLIFrameElementTest, RelativeURLsUseCorrectOrigin) { - Document* document = Document::CreateForTest(); - const KURL document_url("http://example.com"); - document->SetURL(document_url); - document->UpdateSecurityOrigin(SecurityOrigin::Create(document_url)); - - HTMLIFrameElement* frame_element = HTMLIFrameElement::Create(*document); - // Host-relative URLs should resolve to the same domain as the parent. - frame_element->setAttribute(html_names::kSrcAttr, "index2.html"); + frame_element_->setAttribute(html_names::kSrcAttr, "index2.html"); scoped_refptr<const SecurityOrigin> effective_origin = - GetOriginForFeaturePolicy(frame_element); + GetOriginForFeaturePolicy(frame_element_); EXPECT_TRUE( - effective_origin->IsSameSchemeHostPort(document->GetSecurityOrigin())); + effective_origin->IsSameSchemeHostPort(document_->GetSecurityOrigin())); // Scheme-relative URLs should not resolve to the same domain as the parent. - frame_element->setAttribute(html_names::kSrcAttr, - "//example.net/index2.html"); - effective_origin = GetOriginForFeaturePolicy(frame_element); + frame_element_->setAttribute(html_names::kSrcAttr, + "//example.net/index2.html"); + effective_origin = GetOriginForFeaturePolicy(frame_element_); EXPECT_FALSE( - effective_origin->IsSameSchemeHostPort(document->GetSecurityOrigin())); + effective_origin->IsSameSchemeHostPort(document_->GetSecurityOrigin())); } // Test that various iframe attribute configurations result in the correct @@ -165,37 +141,23 @@ // Test that the correct container policy is constructed on an iframe element. TEST_F(HTMLIFrameElementTest, DefaultContainerPolicy) { - Document* document = Document::CreateForTest(); - const KURL document_url("http://example.com"); - document->SetURL(document_url); - document->UpdateSecurityOrigin(SecurityOrigin::Create(document_url)); - - HTMLIFrameElement* frame_element = HTMLIFrameElement::Create(*document); - - frame_element->setAttribute(html_names::kSrcAttr, "http://example.net/"); - frame_element->UpdateContainerPolicyForTests(); + frame_element_->setAttribute(html_names::kSrcAttr, "http://example.net/"); + frame_element_->UpdateContainerPolicyForTests(); const ParsedFeaturePolicy& container_policy = - frame_element->GetFramePolicy().container_policy; + frame_element_->GetFramePolicy().container_policy; EXPECT_EQ(0UL, container_policy.size()); } // Test that the allow attribute results in a container policy which is // restricted to the domain in the src attribute. TEST_F(HTMLIFrameElementTest, AllowAttributeContainerPolicy) { - Document* document = Document::CreateForTest(); - const KURL document_url("http://example.com"); - document->SetURL(document_url); - document->UpdateSecurityOrigin(SecurityOrigin::Create(document_url)); - - HTMLIFrameElement* frame_element = HTMLIFrameElement::Create(*document); - - frame_element->setAttribute(html_names::kSrcAttr, "http://example.net/"); - frame_element->setAttribute(html_names::kAllowAttr, "fullscreen"); - frame_element->UpdateContainerPolicyForTests(); + frame_element_->setAttribute(html_names::kSrcAttr, "http://example.net/"); + frame_element_->setAttribute(html_names::kAllowAttr, "fullscreen"); + frame_element_->UpdateContainerPolicyForTests(); const ParsedFeaturePolicy& container_policy1 = - frame_element->GetFramePolicy().container_policy; + frame_element_->GetFramePolicy().container_policy; EXPECT_EQ(1UL, container_policy1.size()); EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, @@ -205,11 +167,11 @@ EXPECT_EQ("http://example.net", container_policy1[0].values.begin()->first.Serialize()); - frame_element->setAttribute(html_names::kAllowAttr, "payment; fullscreen"); - frame_element->UpdateContainerPolicyForTests(); + frame_element_->setAttribute(html_names::kAllowAttr, "payment; fullscreen"); + frame_element_->UpdateContainerPolicyForTests(); const ParsedFeaturePolicy& container_policy2 = - frame_element->GetFramePolicy().container_policy; + frame_element_->GetFramePolicy().container_policy; EXPECT_EQ(2UL, container_policy2.size()); EXPECT_TRUE(container_policy2[0].feature == mojom::FeaturePolicyFeature::kFullscreen || @@ -232,18 +194,11 @@ TEST_F(HTMLIFrameElementTest, SandboxAttributeContainerPolicy) { ASSERT_TRUE(RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()); - Document* document = Document::CreateForTest(); - const KURL document_url("http://example.com"); - document->SetURL(document_url); - document->UpdateSecurityOrigin(SecurityOrigin::Create(document_url)); - - HTMLIFrameElement* frame_element = HTMLIFrameElement::Create(*document); - - frame_element->setAttribute(html_names::kSandboxAttr, ""); - frame_element->UpdateContainerPolicyForTests(); + frame_element_->setAttribute(html_names::kSandboxAttr, ""); + frame_element_->UpdateContainerPolicyForTests(); const ParsedFeaturePolicy& container_policy = - frame_element->GetFramePolicy().container_policy; + frame_element_->GetFramePolicy().container_policy; EXPECT_EQ(expected_number_of_sandbox_features, container_policy.size()); } @@ -252,20 +207,14 @@ // policy which is restricted to a unique origin. TEST_F(HTMLIFrameElementTest, CrossOriginSandboxAttributeContainerPolicy) { ASSERT_TRUE(RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()); - Document* document = Document::CreateForTest(); - const KURL document_url("http://example.com"); - document->SetURL(document_url); - document->UpdateSecurityOrigin(SecurityOrigin::Create(document_url)); - HTMLIFrameElement* frame_element = HTMLIFrameElement::Create(*document); - - frame_element->setAttribute(html_names::kSrcAttr, "http://example.net/"); - frame_element->setAttribute(html_names::kAllowAttr, "fullscreen"); - frame_element->setAttribute(html_names::kSandboxAttr, ""); - frame_element->UpdateContainerPolicyForTests(); + frame_element_->setAttribute(html_names::kSrcAttr, "http://example.net/"); + frame_element_->setAttribute(html_names::kAllowAttr, "fullscreen"); + frame_element_->setAttribute(html_names::kSandboxAttr, ""); + frame_element_->UpdateContainerPolicyForTests(); const ParsedFeaturePolicy& container_policy = - frame_element->GetFramePolicy().container_policy; + frame_element_->GetFramePolicy().container_policy; EXPECT_EQ(expected_number_of_sandbox_features + 1, container_policy.size()); const auto& container_policy_item = std::find_if( @@ -288,20 +237,14 @@ // containing document. TEST_F(HTMLIFrameElementTest, SameOriginSandboxAttributeContainerPolicy) { ASSERT_TRUE(RuntimeEnabledFeatures::FeaturePolicyForSandboxEnabled()); - Document* document = Document::CreateForTest(); - const KURL document_url("http://example.com"); - document->SetURL(document_url); - document->UpdateSecurityOrigin(SecurityOrigin::Create(document_url)); - HTMLIFrameElement* frame_element = HTMLIFrameElement::Create(*document); - - frame_element->setAttribute(html_names::kSrcAttr, "http://example.net/"); - frame_element->setAttribute(html_names::kAllowAttr, "fullscreen"); - frame_element->setAttribute(html_names::kSandboxAttr, "allow-same-origin"); - frame_element->UpdateContainerPolicyForTests(); + frame_element_->setAttribute(html_names::kSrcAttr, "http://example.net/"); + frame_element_->setAttribute(html_names::kAllowAttr, "fullscreen"); + frame_element_->setAttribute(html_names::kSandboxAttr, "allow-same-origin"); + frame_element_->UpdateContainerPolicyForTests(); const ParsedFeaturePolicy& container_policy = - frame_element->GetFramePolicy().container_policy; + frame_element_->GetFramePolicy().container_policy; EXPECT_EQ(expected_number_of_sandbox_features + 1, container_policy.size()); const auto& container_policy_item = std::find_if( @@ -324,55 +267,36 @@ // Test the ConstructContainerPolicy method when no attributes are set on the // iframe element. TEST_F(HTMLIFrameElementTest, ConstructEmptyContainerPolicy) { - Document* document = Document::CreateForTest(); - const KURL document_url("http://example.com"); - document->SetURL(document_url); - document->UpdateSecurityOrigin(SecurityOrigin::Create(document_url)); - - HTMLIFrameElement* frame_element = HTMLIFrameElement::Create(*document); - ParsedFeaturePolicy container_policy = - frame_element->ConstructContainerPolicy(nullptr); + frame_element_->ConstructContainerPolicy(nullptr); EXPECT_EQ(0UL, container_policy.size()); } // Test the ConstructContainerPolicy method when the "allow" attribute is used // to enable features in the frame. TEST_F(HTMLIFrameElementTest, ConstructContainerPolicy) { - Document* document = Document::CreateForTest(); - const KURL document_url("http://example.com"); - document->SetURL(document_url); - document->UpdateSecurityOrigin(SecurityOrigin::Create(document_url)); - - HTMLIFrameElement* frame_element = HTMLIFrameElement::Create(*document); - frame_element->setAttribute(html_names::kAllowAttr, "payment; usb"); + frame_element_->setAttribute(html_names::kAllowAttr, "payment; usb"); ParsedFeaturePolicy container_policy = - frame_element->ConstructContainerPolicy(nullptr); + frame_element_->ConstructContainerPolicy(nullptr); EXPECT_EQ(2UL, container_policy.size()); EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, container_policy[0].feature); EXPECT_GE(min_value, container_policy[0].fallback_value); EXPECT_EQ(1UL, container_policy[0].values.size()); EXPECT_TRUE(container_policy[0].values.begin()->first.IsSameOriginWith( - GetOriginForFeaturePolicy(frame_element)->ToUrlOrigin())); + GetOriginForFeaturePolicy(frame_element_)->ToUrlOrigin())); EXPECT_EQ(mojom::FeaturePolicyFeature::kUsb, container_policy[1].feature); EXPECT_EQ(1UL, container_policy[1].values.size()); EXPECT_TRUE(container_policy[1].values.begin()->first.IsSameOriginWith( - GetOriginForFeaturePolicy(frame_element)->ToUrlOrigin())); + GetOriginForFeaturePolicy(frame_element_)->ToUrlOrigin())); } // Test the ConstructContainerPolicy method when the "allowfullscreen" attribute // is used to enable fullscreen in the frame. TEST_F(HTMLIFrameElementTest, ConstructContainerPolicyWithAllowFullscreen) { - Document* document = Document::CreateForTest(); - const KURL document_url("http://example.com"); - document->SetURL(document_url); - document->UpdateSecurityOrigin(SecurityOrigin::Create(document_url)); - - HTMLIFrameElement* frame_element = HTMLIFrameElement::Create(*document); - frame_element->SetBooleanAttribute(html_names::kAllowfullscreenAttr, true); + frame_element_->SetBooleanAttribute(html_names::kAllowfullscreenAttr, true); ParsedFeaturePolicy container_policy = - frame_element->ConstructContainerPolicy(nullptr); + frame_element_->ConstructContainerPolicy(nullptr); EXPECT_EQ(1UL, container_policy.size()); EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, container_policy[0].feature); @@ -382,24 +306,18 @@ // Test the ConstructContainerPolicy method when the "allowpaymentrequest" // attribute is used to enable the paymentrequest API in the frame. TEST_F(HTMLIFrameElementTest, ConstructContainerPolicyWithAllowPaymentRequest) { - Document* document = Document::CreateForTest(); - const KURL document_url("http://example.com"); - document->SetURL(document_url); - document->UpdateSecurityOrigin(SecurityOrigin::Create(document_url)); - - HTMLIFrameElement* frame_element = HTMLIFrameElement::Create(*document); - frame_element->setAttribute(html_names::kAllowAttr, "usb"); - frame_element->SetBooleanAttribute(html_names::kAllowpaymentrequestAttr, - true); + frame_element_->setAttribute(html_names::kAllowAttr, "usb"); + frame_element_->SetBooleanAttribute(html_names::kAllowpaymentrequestAttr, + true); ParsedFeaturePolicy container_policy = - frame_element->ConstructContainerPolicy(nullptr); + frame_element_->ConstructContainerPolicy(nullptr); EXPECT_EQ(2UL, container_policy.size()); EXPECT_EQ(mojom::FeaturePolicyFeature::kUsb, container_policy[0].feature); EXPECT_GE(min_value, container_policy[0].fallback_value); EXPECT_EQ(1UL, container_policy[0].values.size()); EXPECT_TRUE(container_policy[0].values.begin()->first.IsSameOriginWith( - GetOriginForFeaturePolicy(frame_element)->ToUrlOrigin())); + GetOriginForFeaturePolicy(frame_element_)->ToUrlOrigin())); EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, container_policy[1].feature); } @@ -410,29 +328,23 @@ // only for the frame's origin, (since the allow attribute overrides // allowpaymentrequest,) while fullscreen should be enabled for all origins. TEST_F(HTMLIFrameElementTest, ConstructContainerPolicyWithAllowAttributes) { - Document* document = Document::CreateForTest(); - const KURL document_url("http://example.com"); - document->SetURL(document_url); - document->UpdateSecurityOrigin(SecurityOrigin::Create(document_url)); - - HTMLIFrameElement* frame_element = HTMLIFrameElement::Create(*document); - frame_element->setAttribute(html_names::kAllowAttr, "payment; usb"); - frame_element->SetBooleanAttribute(html_names::kAllowfullscreenAttr, true); - frame_element->SetBooleanAttribute(html_names::kAllowpaymentrequestAttr, - true); + frame_element_->setAttribute(html_names::kAllowAttr, "payment; usb"); + frame_element_->SetBooleanAttribute(html_names::kAllowfullscreenAttr, true); + frame_element_->SetBooleanAttribute(html_names::kAllowpaymentrequestAttr, + true); ParsedFeaturePolicy container_policy = - frame_element->ConstructContainerPolicy(nullptr); + frame_element_->ConstructContainerPolicy(nullptr); EXPECT_EQ(3UL, container_policy.size()); EXPECT_EQ(mojom::FeaturePolicyFeature::kPayment, container_policy[0].feature); EXPECT_GE(min_value, container_policy[0].fallback_value); EXPECT_EQ(1UL, container_policy[0].values.size()); EXPECT_TRUE(container_policy[0].values.begin()->first.IsSameOriginWith( - GetOriginForFeaturePolicy(frame_element)->ToUrlOrigin())); + GetOriginForFeaturePolicy(frame_element_)->ToUrlOrigin())); EXPECT_EQ(mojom::FeaturePolicyFeature::kUsb, container_policy[1].feature); EXPECT_EQ(1UL, container_policy[1].values.size()); EXPECT_TRUE(container_policy[1].values.begin()->first.IsSameOriginWith( - GetOriginForFeaturePolicy(frame_element)->ToUrlOrigin())); + GetOriginForFeaturePolicy(frame_element_)->ToUrlOrigin())); EXPECT_EQ(mojom::FeaturePolicyFeature::kFullscreen, container_policy[2].feature); }
diff --git a/third_party/blink/renderer/core/html/html_li_element.cc b/third_party/blink/renderer/core/html/html_li_element.cc index 832cca38..393150b 100644 --- a/third_party/blink/renderer/core/html/html_li_element.cc +++ b/third_party/blink/renderer/core/html/html_li_element.cc
@@ -34,7 +34,7 @@ using namespace html_names; -inline HTMLLIElement::HTMLLIElement(Document& document) +HTMLLIElement::HTMLLIElement(Document& document) : HTMLElement(kLiTag, document) {} DEFINE_NODE_FACTORY(HTMLLIElement)
diff --git a/third_party/blink/renderer/core/html/html_link_element.cc b/third_party/blink/renderer/core/html/html_link_element.cc index c783641..5ef87c2c 100644 --- a/third_party/blink/renderer/core/html/html_link_element.cc +++ b/third_party/blink/renderer/core/html/html_link_element.cc
@@ -52,8 +52,8 @@ using namespace html_names; -inline HTMLLinkElement::HTMLLinkElement(Document& document, - const CreateElementFlags flags) +HTMLLinkElement::HTMLLinkElement(Document& document, + const CreateElementFlags flags) : HTMLElement(kLinkTag, document), link_loader_(LinkLoader::Create(this)), referrer_policy_(network::mojom::ReferrerPolicy::kDefault),
diff --git a/third_party/blink/renderer/core/html/html_link_element.h b/third_party/blink/renderer/core/html/html_link_element.h index e964a1f..bf662bc 100644 --- a/third_party/blink/renderer/core/html/html_link_element.h +++ b/third_party/blink/renderer/core/html/html_link_element.h
@@ -25,6 +25,7 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_HTML_LINK_ELEMENT_H_ #include <memory> + #include "base/single_thread_task_runner.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/create_element_flags.h"
diff --git a/third_party/blink/renderer/core/html/html_link_element_sizes_attribute_test.cc b/third_party/blink/renderer/core/html/html_link_element_sizes_attribute_test.cc index 5580251..d62321a 100644 --- a/third_party/blink/renderer/core/html/html_link_element_sizes_attribute_test.cc +++ b/third_party/blink/renderer/core/html/html_link_element_sizes_attribute_test.cc
@@ -8,6 +8,7 @@ #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_token_list.h" #include "third_party/blink/renderer/core/html_names.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -16,7 +17,8 @@ TEST(HTMLLinkElementSizesAttributeTest, setSizesPropertyValue_updatesAttribute) { Document* document = Document::CreateForTest(); - auto* link = HTMLLinkElement::Create(*document, CreateElementFlags()); + auto* link = + MakeGarbageCollected<HTMLLinkElement>(*document, CreateElementFlags()); DOMTokenList* sizes = link->sizes(); EXPECT_EQ(g_null_atom, sizes->value()); sizes->setValue(" a b c "); @@ -27,8 +29,8 @@ TEST(HTMLLinkElementSizesAttributeTest, setSizesAttribute_updatesSizesPropertyValue) { Document* document = Document::CreateForTest(); - HTMLLinkElement* link = - HTMLLinkElement::Create(*document, CreateElementFlags()); + auto* link = + MakeGarbageCollected<HTMLLinkElement>(*document, CreateElementFlags()); DOMTokenList* sizes = link->sizes(); EXPECT_EQ(g_null_atom, sizes->value()); link->setAttribute(html_names::kSizesAttr, "y x ");
diff --git a/third_party/blink/renderer/core/html/html_marquee_element.cc b/third_party/blink/renderer/core/html/html_marquee_element.cc index ad3089e..8c1b99b 100644 --- a/third_party/blink/renderer/core/html/html_marquee_element.cc +++ b/third_party/blink/renderer/core/html/html_marquee_element.cc
@@ -47,6 +47,7 @@ #include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -63,7 +64,8 @@ } void HTMLMarqueeElement::DidAddUserAgentShadowRoot(ShadowRoot& shadow_root) { - auto* style = HTMLStyleElement::Create(GetDocument(), CreateElementFlags()); + auto* style = MakeGarbageCollected<HTMLStyleElement>(GetDocument(), + CreateElementFlags()); style->setTextContent( ":host { display: inline-block; overflow: hidden;" "text-align: initial; white-space: nowrap; }"
diff --git a/third_party/blink/renderer/core/html/html_meta_element.cc b/third_party/blink/renderer/core/html/html_meta_element.cc index 90bd176..80738bc 100644 --- a/third_party/blink/renderer/core/html/html_meta_element.cc +++ b/third_party/blink/renderer/core/html/html_meta_element.cc
@@ -43,7 +43,7 @@ using namespace html_names; -inline HTMLMetaElement::HTMLMetaElement(Document& document) +HTMLMetaElement::HTMLMetaElement(Document& document) : HTMLElement(kMetaTag, document) {} DEFINE_NODE_FACTORY(HTMLMetaElement)
diff --git a/third_party/blink/renderer/core/html/html_meta_element_test.cc b/third_party/blink/renderer/core/html/html_meta_element_test.cc index e179eb1..f7e07a4 100644 --- a/third_party/blink/renderer/core/html/html_meta_element_test.cc +++ b/third_party/blink/renderer/core/html/html_meta_element_test.cc
@@ -13,6 +13,7 @@ #include "third_party/blink/renderer/core/frame/viewport_data.h" #include "third_party/blink/renderer/core/html/html_head_element.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { @@ -39,7 +40,7 @@ protected: HTMLMetaElement* CreateSupportedColorSchemesMeta( const AtomicString& content) { - HTMLMetaElement* meta = HTMLMetaElement::Create(GetDocument()); + auto* meta = MakeGarbageCollected<HTMLMetaElement>(GetDocument()); meta->setAttribute(html_names::kNameAttr, "supported-color-schemes"); meta->setAttribute(html_names::kContentAttr, content); return meta;
diff --git a/third_party/blink/renderer/core/html/html_paragraph_element.cc b/third_party/blink/renderer/core/html/html_paragraph_element.cc index 3ad635b..b2fd50e 100644 --- a/third_party/blink/renderer/core/html/html_paragraph_element.cc +++ b/third_party/blink/renderer/core/html/html_paragraph_element.cc
@@ -30,7 +30,7 @@ using namespace html_names; -inline HTMLParagraphElement::HTMLParagraphElement(Document& document) +HTMLParagraphElement::HTMLParagraphElement(Document& document) : HTMLElement(kPTag, document) {} DEFINE_NODE_FACTORY(HTMLParagraphElement)
diff --git a/third_party/blink/renderer/core/html/html_plugin_element.cc b/third_party/blink/renderer/core/html/html_plugin_element.cc index 83765b96..4b9d0d9 100644 --- a/third_party/blink/renderer/core/html/html_plugin_element.cc +++ b/third_party/blink/renderer/core/html/html_plugin_element.cc
@@ -127,7 +127,7 @@ if (doc.GetScheduler()) { doc.GetScheduler()->RegisterStickyFeature( SchedulingPolicy::Feature::kContainsPlugins, - {SchedulingPolicy::DisableBackForwardCache()}); + {SchedulingPolicy::RecordMetricsForBackForwardCache()}); } }
diff --git a/third_party/blink/renderer/core/html/html_script_element.cc b/third_party/blink/renderer/core/html/html_script_element.cc index cfdac45..d9cb90d 100644 --- a/third_party/blink/renderer/core/html/html_script_element.cc +++ b/third_party/blink/renderer/core/html/html_script_element.cc
@@ -45,8 +45,8 @@ using namespace html_names; -inline HTMLScriptElement::HTMLScriptElement(Document& document, - const CreateElementFlags flags) +HTMLScriptElement::HTMLScriptElement(Document& document, + const CreateElementFlags flags) : HTMLElement(kScriptTag, document), loader_(InitializeScriptLoader(flags.IsCreatedByParser(), flags.WasAlreadyStarted())) {}
diff --git a/third_party/blink/renderer/core/html/html_style_element.cc b/third_party/blink/renderer/core/html/html_style_element.cc index 26514ea..72c842f4 100644 --- a/third_party/blink/renderer/core/html/html_style_element.cc +++ b/third_party/blink/renderer/core/html/html_style_element.cc
@@ -36,8 +36,8 @@ using namespace html_names; -inline HTMLStyleElement::HTMLStyleElement(Document& document, - const CreateElementFlags flags) +HTMLStyleElement::HTMLStyleElement(Document& document, + const CreateElementFlags flags) : HTMLElement(kStyleTag, document), StyleElement(&document, flags.IsCreatedByParser()), fired_load_(false),
diff --git a/third_party/blink/renderer/core/html/html_table_caption_element.cc b/third_party/blink/renderer/core/html/html_table_caption_element.cc index 4d8f10f0..b0396a43 100644 --- a/third_party/blink/renderer/core/html/html_table_caption_element.cc +++ b/third_party/blink/renderer/core/html/html_table_caption_element.cc
@@ -31,7 +31,7 @@ using namespace html_names; -inline HTMLTableCaptionElement::HTMLTableCaptionElement(Document& document) +HTMLTableCaptionElement::HTMLTableCaptionElement(Document& document) : HTMLElement(kCaptionTag, document) {} DEFINE_NODE_FACTORY(HTMLTableCaptionElement)
diff --git a/third_party/blink/renderer/core/html/html_table_cell_element.cc b/third_party/blink/renderer/core/html/html_table_cell_element.cc index fa747040..fa7f180 100644 --- a/third_party/blink/renderer/core/html/html_table_cell_element.cc +++ b/third_party/blink/renderer/core/html/html_table_cell_element.cc
@@ -39,8 +39,8 @@ using namespace html_names; -inline HTMLTableCellElement::HTMLTableCellElement(const QualifiedName& tag_name, - Document& document) +HTMLTableCellElement::HTMLTableCellElement(const QualifiedName& tag_name, + Document& document) : HTMLTablePartElement(tag_name, document) {} DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLTableCellElement)
diff --git a/third_party/blink/renderer/core/html/html_table_cell_element.h b/third_party/blink/renderer/core/html/html_table_cell_element.h index c896313..59205312 100644 --- a/third_party/blink/renderer/core/html/html_table_cell_element.h +++ b/third_party/blink/renderer/core/html/html_table_cell_element.h
@@ -37,6 +37,8 @@ public: DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLTableCellElement); + HTMLTableCellElement(const QualifiedName&, Document&); + int cellIndex() const; unsigned colSpan() const; @@ -53,8 +55,6 @@ bool HasNonInBodyInsertionMode() const override { return true; } private: - HTMLTableCellElement(const QualifiedName&, Document&); - void ParseAttribute(const AttributeModificationParams&) override; bool IsPresentationAttribute(const QualifiedName&) const override; void CollectStyleForPresentationAttribute(
diff --git a/third_party/blink/renderer/core/html/html_table_element.cc b/third_party/blink/renderer/core/html/html_table_element.cc index 833a0a5..1690252 100644 --- a/third_party/blink/renderer/core/html/html_table_element.cc +++ b/third_party/blink/renderer/core/html/html_table_element.cc
@@ -44,6 +44,7 @@ #include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/weborigin/referrer.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" @@ -51,7 +52,7 @@ using namespace html_names; -inline HTMLTableElement::HTMLTableElement(Document& document) +HTMLTableElement::HTMLTableElement(Document& document) : HTMLElement(kTableTag, document), border_attr_(false), border_color_attr_(false), @@ -128,8 +129,8 @@ HTMLTableSectionElement* HTMLTableElement::createTHead() { if (HTMLTableSectionElement* existing_head = tHead()) return existing_head; - HTMLTableSectionElement* head = - HTMLTableSectionElement::Create(kTheadTag, GetDocument()); + auto* head = + MakeGarbageCollected<HTMLTableSectionElement>(kTheadTag, GetDocument()); setTHead(head, IGNORE_EXCEPTION_FOR_TESTING); return head; } @@ -141,8 +142,8 @@ HTMLTableSectionElement* HTMLTableElement::createTFoot() { if (HTMLTableSectionElement* existing_foot = tFoot()) return existing_foot; - HTMLTableSectionElement* foot = - HTMLTableSectionElement::Create(kTfootTag, GetDocument()); + auto* foot = + MakeGarbageCollected<HTMLTableSectionElement>(kTfootTag, GetDocument()); setTFoot(foot, IGNORE_EXCEPTION_FOR_TESTING); return foot; } @@ -152,8 +153,8 @@ } HTMLTableSectionElement* HTMLTableElement::createTBody() { - HTMLTableSectionElement* body = - HTMLTableSectionElement::Create(kTbodyTag, GetDocument()); + auto* body = + MakeGarbageCollected<HTMLTableSectionElement>(kTbodyTag, GetDocument()); Node* reference_element = LastBody() ? LastBody()->nextSibling() : nullptr; InsertBefore(body, reference_element); @@ -163,8 +164,7 @@ HTMLTableCaptionElement* HTMLTableElement::createCaption() { if (HTMLTableCaptionElement* existing_caption = caption()) return existing_caption; - HTMLTableCaptionElement* caption = - HTMLTableCaptionElement::Create(GetDocument()); + auto* caption = MakeGarbageCollected<HTMLTableCaptionElement>(GetDocument()); setCaption(caption, IGNORE_EXCEPTION_FOR_TESTING); return caption; } @@ -216,16 +216,16 @@ } else { parent = LastBody(); if (!parent) { - HTMLTableSectionElement* new_body = - HTMLTableSectionElement::Create(kTbodyTag, GetDocument()); - HTMLTableRowElement* new_row = HTMLTableRowElement::Create(GetDocument()); + auto* new_body = MakeGarbageCollected<HTMLTableSectionElement>( + kTbodyTag, GetDocument()); + auto* new_row = MakeGarbageCollected<HTMLTableRowElement>(GetDocument()); new_body->AppendChild(new_row, exception_state); AppendChild(new_body, exception_state); return new_row; } } - HTMLTableRowElement* new_row = HTMLTableRowElement::Create(GetDocument()); + auto* new_row = MakeGarbageCollected<HTMLTableRowElement>(GetDocument()); parent->InsertBefore(new_row, row, exception_state); return new_row; }
diff --git a/third_party/blink/renderer/core/html/html_table_row_element.cc b/third_party/blink/renderer/core/html/html_table_row_element.cc index 12c9272..19e20ce 100644 --- a/third_party/blink/renderer/core/html/html_table_row_element.cc +++ b/third_party/blink/renderer/core/html/html_table_row_element.cc
@@ -34,12 +34,13 @@ #include "third_party/blink/renderer/core/html/html_table_section_element.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { using namespace html_names; -inline HTMLTableRowElement::HTMLTableRowElement(Document& document) +HTMLTableRowElement::HTMLTableRowElement(Document& document) : HTMLTablePartElement(kTrTag, document) {} DEFINE_NODE_FACTORY(HTMLTableRowElement) @@ -102,8 +103,8 @@ return nullptr; } - HTMLTableCellElement* cell = - HTMLTableCellElement::Create(kTdTag, GetDocument()); + auto* cell = + MakeGarbageCollected<HTMLTableCellElement>(kTdTag, GetDocument()); if (num_cells == index || index == -1) AppendChild(cell, exception_state); else
diff --git a/third_party/blink/renderer/core/html/html_table_row_element_test.cc b/third_party/blink/renderer/core/html/html_table_row_element_test.cc index cdf795e..e38d0914 100644 --- a/third_party/blink/renderer/core/html/html_table_row_element_test.cc +++ b/third_party/blink/renderer/core/html/html_table_row_element_test.cc
@@ -8,6 +8,7 @@ #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/html/html_paragraph_element.h" #include "third_party/blink/renderer/core/html/html_table_element.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -16,15 +17,15 @@ TEST(HTMLTableRowElementTest, rowIndex_notInTable) { Document* document = Document::CreateForTest(); - HTMLTableRowElement* row = HTMLTableRowElement::Create(*document); + auto* row = MakeGarbageCollected<HTMLTableRowElement>(*document); EXPECT_EQ(-1, row->rowIndex()) << "rows not in tables should have row index -1"; } TEST(HTMLTableRowElementTest, rowIndex_directChildOfTable) { Document* document = Document::CreateForTest(); - HTMLTableElement* table = HTMLTableElement::Create(*document); - HTMLTableRowElement* row = HTMLTableRowElement::Create(*document); + auto* table = MakeGarbageCollected<HTMLTableElement>(*document); + auto* row = MakeGarbageCollected<HTMLTableRowElement>(*document); table->AppendChild(row); EXPECT_EQ(0, row->rowIndex()) << "rows that are direct children of a table should have a row index"; @@ -32,11 +33,11 @@ TEST(HTMLTableRowElementTest, rowIndex_inUnrelatedElementInTable) { Document* document = Document::CreateForTest(); - HTMLTableElement* table = HTMLTableElement::Create(*document); + auto* table = MakeGarbageCollected<HTMLTableElement>(*document); // Almost any element will do; what's pertinent is that this is not // THEAD, TBODY or TFOOT. - HTMLParagraphElement* paragraph = HTMLParagraphElement::Create(*document); - HTMLTableRowElement* row = HTMLTableRowElement::Create(*document); + auto* paragraph = MakeGarbageCollected<HTMLParagraphElement>(*document); + auto* row = MakeGarbageCollected<HTMLTableRowElement>(*document); table->AppendChild(paragraph); paragraph->AppendChild(row); EXPECT_EQ(-1, row->rowIndex())
diff --git a/third_party/blink/renderer/core/html/html_table_section_element.cc b/third_party/blink/renderer/core/html/html_table_section_element.cc index 1c5a455..8bf5436 100644 --- a/third_party/blink/renderer/core/html/html_table_section_element.cc +++ b/third_party/blink/renderer/core/html/html_table_section_element.cc
@@ -30,12 +30,12 @@ #include "third_party/blink/renderer/core/html/html_table_element.h" #include "third_party/blink/renderer/core/html/html_table_row_element.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { -inline HTMLTableSectionElement::HTMLTableSectionElement( - const QualifiedName& tag_name, - Document& document) +HTMLTableSectionElement::HTMLTableSectionElement(const QualifiedName& tag_name, + Document& document) : HTMLTablePartElement(tag_name, document) {} DEFINE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLTableSectionElement) @@ -62,7 +62,7 @@ return nullptr; } - HTMLTableRowElement* row = HTMLTableRowElement::Create(GetDocument()); + auto* row = MakeGarbageCollected<HTMLTableRowElement>(GetDocument()); if (num_rows == index || index == -1) AppendChild(row, exception_state); else
diff --git a/third_party/blink/renderer/core/html/html_table_section_element.h b/third_party/blink/renderer/core/html/html_table_section_element.h index 151730e..cfedc050 100644 --- a/third_party/blink/renderer/core/html/html_table_section_element.h +++ b/third_party/blink/renderer/core/html/html_table_section_element.h
@@ -38,6 +38,8 @@ public: DECLARE_ELEMENT_FACTORY_WITH_TAGNAME(HTMLTableSectionElement); + HTMLTableSectionElement(const QualifiedName& tag_name, Document&); + HTMLElement* insertRow(int index, ExceptionState&); void deleteRow(int index, ExceptionState&); @@ -46,8 +48,6 @@ bool HasNonInBodyInsertionMode() const override { return true; } private: - HTMLTableSectionElement(const QualifiedName& tag_name, Document&); - const CSSPropertyValueSet* AdditionalPresentationAttributeStyle() override; };
diff --git a/third_party/blink/renderer/core/html/html_title_element.cc b/third_party/blink/renderer/core/html/html_title_element.cc index b54bd60..377052a 100644 --- a/third_party/blink/renderer/core/html/html_title_element.cc +++ b/third_party/blink/renderer/core/html/html_title_element.cc
@@ -34,7 +34,7 @@ using namespace html_names; -inline HTMLTitleElement::HTMLTitleElement(Document& document) +HTMLTitleElement::HTMLTitleElement(Document& document) : HTMLElement(kTitleTag, document), ignore_title_updates_when_children_change_(false) {}
diff --git a/third_party/blink/renderer/core/html/html_ulist_element.cc b/third_party/blink/renderer/core/html/html_ulist_element.cc index 2bef4d5..bb07011f 100644 --- a/third_party/blink/renderer/core/html/html_ulist_element.cc +++ b/third_party/blink/renderer/core/html/html_ulist_element.cc
@@ -29,7 +29,7 @@ using namespace html_names; -inline HTMLUListElement::HTMLUListElement(Document& document) +HTMLUListElement::HTMLUListElement(Document& document) : HTMLElement(kUlTag, document) {} DEFINE_NODE_FACTORY(HTMLUListElement)
diff --git a/third_party/blink/renderer/core/html/html_view_source_document.cc b/third_party/blink/renderer/core/html/html_view_source_document.cc index 4dd94e5..12284bf 100644 --- a/third_party/blink/renderer/core/html/html_view_source_document.cc +++ b/third_party/blink/renderer/core/html/html_view_source_document.cc
@@ -38,6 +38,7 @@ #include "third_party/blink/renderer/core/html/html_table_row_element.h" #include "third_party/blink/renderer/core/html/html_table_section_element.h" #include "third_party/blink/renderer/core/html/parser/html_view_source_parser.h" +#include "third_party/blink/renderer/platform/heap/heap.h" namespace blink { @@ -64,11 +65,11 @@ } void HTMLViewSourceDocument::CreateContainingTable() { - HTMLHtmlElement* html = HTMLHtmlElement::Create(*this); + auto* html = MakeGarbageCollected<HTMLHtmlElement>(*this); ParserAppendChild(html); - HTMLHeadElement* head = HTMLHeadElement::Create(*this); + auto* head = MakeGarbageCollected<HTMLHeadElement>(*this); html->ParserAppendChild(head); - HTMLBodyElement* body = HTMLBodyElement::Create(*this); + auto* body = MakeGarbageCollected<HTMLBodyElement>(*this); html->ParserAppendChild(body); // Create a line gutter div that can be used to make sure the gutter extends @@ -77,9 +78,9 @@ div->setAttribute(kClassAttr, "line-gutter-backdrop"); body->ParserAppendChild(div); - HTMLTableElement* table = HTMLTableElement::Create(*this); + auto* table = MakeGarbageCollected<HTMLTableElement>(*this); body->ParserAppendChild(table); - tbody_ = HTMLTableSectionElement::Create(kTbodyTag, *this); + tbody_ = MakeGarbageCollected<HTMLTableSectionElement>(kTbodyTag, *this); table->ParserAppendChild(tbody_); current_ = tbody_; line_number_ = 0; @@ -206,18 +207,18 @@ void HTMLViewSourceDocument::AddLine(const AtomicString& class_name) { // Create a table row. - HTMLTableRowElement* trow = HTMLTableRowElement::Create(*this); + auto* trow = MakeGarbageCollected<HTMLTableRowElement>(*this); tbody_->ParserAppendChild(trow); // Create a cell that will hold the line number (it is generated in the // stylesheet using counters). - HTMLTableCellElement* td = HTMLTableCellElement::Create(kTdTag, *this); + auto* td = MakeGarbageCollected<HTMLTableCellElement>(kTdTag, *this); td->setAttribute(kClassAttr, "line-number"); td->SetIntegralAttribute(kValueAttr, ++line_number_); trow->ParserAppendChild(td); // Create a second cell for the line contents - td = HTMLTableCellElement::Create(kTdTag, *this); + td = MakeGarbageCollected<HTMLTableCellElement>(kTdTag, *this); td->setAttribute(kClassAttr, "line-content"); trow->ParserAppendChild(td); current_ = td_ = td; @@ -233,7 +234,7 @@ void HTMLViewSourceDocument::FinishLine() { if (!current_->HasChildren()) { - HTMLBRElement* br = HTMLBRElement::Create(*this); + auto* br = MakeGarbageCollected<HTMLBRElement>(*this); current_->ParserAppendChild(br); } current_ = tbody_; @@ -293,7 +294,7 @@ } Element* HTMLViewSourceDocument::AddBase(const AtomicString& href) { - HTMLBaseElement* base = HTMLBaseElement::Create(*this); + auto* base = MakeGarbageCollected<HTMLBaseElement>(*this); base->setAttribute(kHrefAttr, href); current_->ParserAppendChild(base); return base; @@ -305,7 +306,7 @@ AddLine("html-tag"); // Now create a link for the attribute value instead of a span. - HTMLAnchorElement* anchor = HTMLAnchorElement::Create(*this); + auto* anchor = MakeGarbageCollected<HTMLAnchorElement>(*this); const char* class_value; if (is_anchor) class_value = "html-attribute-value html-external-link";
diff --git a/third_party/blink/renderer/core/html/plugin_document.cc b/third_party/blink/renderer/core/html/plugin_document.cc index 9544b95..5e0e58e 100644 --- a/third_party/blink/renderer/core/html/plugin_document.cc +++ b/third_party/blink/renderer/core/html/plugin_document.cc
@@ -195,7 +195,7 @@ if (GetScheduler()) { GetScheduler()->RegisterStickyFeature( SchedulingPolicy::Feature::kContainsPlugins, - {SchedulingPolicy::DisableBackForwardCache()}); + {SchedulingPolicy::RecordMetricsForBackForwardCache()}); } }
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h index 1a3ad6b..4b63469e 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_item.h
@@ -85,6 +85,7 @@ // If this item is "empty" for the purpose of empty block calculation. bool IsEmptyItem() const { return is_empty_item_; } + void SetIsEmptyItem(bool value) { is_empty_item_ = value; } // If this item should create a box fragment. Box fragments can be omitted for // optimization if this is false.
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc index 138e7bb..d05f2ce 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc
@@ -246,6 +246,20 @@ is_empty_inline_ = false; // text item is not empty. } +// Empty text items are not needed for the layout purposes, but all LayoutObject +// must be captured in NGInlineItemsData to maintain states of LayoutObject in +// this inline formatting context. +template <typename OffsetMappingBuilder> +void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::AppendEmptyTextItem( + LayoutText* layout_object) { + DCHECK(layout_object); + unsigned offset = text_.length(); + AppendItem(items_, NGInlineItem::kText, offset, offset, layout_object); + NGInlineItem& item = items_->back(); + item.SetEndCollapseType(NGInlineItem::kOpaqueToCollapsing); + item.SetIsEmptyItem(true); +} + // Same as AppendBreakOpportunity, but mark the item as IsGenerated(). template <typename OffsetMappingBuilder> void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>:: @@ -265,6 +279,10 @@ LayoutText* layout_text) { DCHECK(layout_text); const NGInlineItems& items = layout_text->InlineItems(); + const NGInlineItem& old_item0 = items.front(); + if (!old_item0.Length()) + return false; + // Don't reuse existing items if they might be affected by whitespace // collapsing. // TODO(layout-dev): This could likely be optimized further. @@ -272,9 +290,7 @@ const ComputedStyle& new_style = layout_text->StyleRef(); bool collapse_spaces = new_style.CollapseWhiteSpace(); if (NGInlineItem* last_item = LastItemToCollapseWith(items_)) { - const NGInlineItem& old_item0 = items.front(); if (collapse_spaces) { - DCHECK_GT(old_item0.Length(), 0u); switch (last_item->EndCollapseType()) { case NGInlineItem::kCollapsible: // If the original string starts with a collapsible space, it may be @@ -320,8 +336,6 @@ } else if (collapse_spaces) { // If the original string starts with a collapsible space, it may be // collapsed because it is now a leading collapsible space. - const NGInlineItem& old_item0 = items.front(); - DCHECK_GT(old_item0.Length(), 0u); if (original_string[old_item0.StartOffset()] == kSpaceCharacter) return false; } @@ -395,8 +409,11 @@ const String& string, LayoutText* layout_object) { DCHECK(layout_object); - if (string.IsEmpty()) + + if (string.IsEmpty()) { + AppendEmptyTextItem(layout_object); return; + } text_.ReserveCapacity(string.length()); typename OffsetMappingBuilder::SourceNodeScope scope(&mapping_builder_, @@ -592,14 +609,18 @@ } } - if (text_.length() > start_offset) { - AppendItem(items_, NGInlineItem::kText, start_offset, text_.length(), - layout_object); - NGInlineItem& item = items_->back(); - item.SetEndCollapseType(end_collapse, space_run_has_newline); - DCHECK(!item.IsEmptyItem()); - is_empty_inline_ = false; // text item is not empty. + DCHECK_GE(text_.length(), start_offset); + if (UNLIKELY(text_.length() == start_offset)) { + AppendEmptyTextItem(layout_object); + return; } + + AppendItem(items_, NGInlineItem::kText, start_offset, text_.length(), + layout_object); + NGInlineItem& item = items_->back(); + item.SetEndCollapseType(end_collapse, space_run_has_newline); + DCHECK(!item.IsEmptyItem()); + is_empty_inline_ = false; // text item is not empty. } // Even when without whitespace collapsing, control characters (newlines and @@ -836,29 +857,15 @@ text_.erase(space_offset); mapping_builder_.CollapseTrailingSpace(space_offset); - // Remove the item if the item has only one space that we're removing. - if (item->Length() == 1) { - DCHECK_EQ(item->StartOffset(), space_offset); - wtf_size_t index = - static_cast<wtf_size_t>(std::distance(items_->begin(), item)); - items_->EraseAt(index); - for (BoxInfo& box : boxes_) { - if (box.item_index >= index) - --box.item_index; - } - if (index == items_->size()) - return; - // Re-compute |item| because |EraseAt| may have reallocated the buffer. - item = &(*items_)[index]; - } else { - item->SetEndOffset(item->EndOffset() - 1); - item->SetEndCollapseType(NGInlineItem::kCollapsed); - item++; - } + // Keep the item even if the length became zero. This is not needed for + // the layout purposes, but needed to maintain LayoutObject states. See + // |AddEmptyTextItem()|. + item->SetEndOffset(item->EndOffset() - 1); + item->SetEndCollapseType(NGInlineItem::kCollapsed); // Trailing spaces can be removed across non-character items. // Adjust their offsets if after the removed index. - for (; item != items_->end(); item++) { + for (item++; item != items_->end(); item++) { item->SetOffset(item->StartOffset() - 1, item->EndOffset() - 1); } } @@ -1071,7 +1078,11 @@ template <typename OffsetMappingBuilder> void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::ClearNeedsLayout( LayoutObject* object) { - NGInlineNode::ClearNeedsLayout(object); + // |CollectInlines()| for the pre-layout does not |ClearNeedsLayout|. It is + // done during the actual layout because re-layout may not require + // |CollectInlines()|. + object->ClearNeedsCollectInlines(); + ClearInlineFragment(object); // Reset previous items if they cannot be reused to prevent stale items // for subsequent layouts. Items that can be reused have already been
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h index fa2632b..9d04bba 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.h
@@ -195,6 +195,7 @@ void AppendTextItem(NGInlineItem::NGInlineItemType type, const StringView, LayoutText* layout_object); + void AppendEmptyTextItem(LayoutText* layout_object); void AppendGeneratedBreakOpportunity(LayoutObject*);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc index c73426da..868bbe90 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder_test.cc
@@ -105,7 +105,7 @@ for (unsigned i = 0; i < items_.size(); i++) { const NGInlineItem& item = items_[i]; EXPECT_EQ(current_offset, item.StartOffset()); - EXPECT_LT(item.StartOffset(), item.EndOffset()); + EXPECT_LE(item.StartOffset(), item.EndOffset()); current_offset = item.EndOffset(); } EXPECT_EQ(current_offset, text_.length()); @@ -340,7 +340,8 @@ TEST_F(NGInlineItemsBuilderTest, AppendEmptyString) { EXPECT_EQ("", TestAppend("")); - EXPECT_EQ(0u, items_.size()); + EXPECT_EQ(1u, items_.size()); + EXPECT_ITEM_OFFSET(items_[0], NGInlineItem::kText, 0u, 0u); } TEST_F(NGInlineItemsBuilderTest, NewLines) {
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc index 6b84be4..f02a3f9 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.cc
@@ -168,7 +168,9 @@ } void ClearNeedsLayout(LayoutObject* object) { - NGInlineNode::ClearNeedsLayout(object); + object->ClearNeedsLayout(); + object->ClearNeedsCollectInlines(); + ClearInlineFragment(object); } void UpdateShouldCreateBoxFragment(LayoutInline* object) { @@ -569,7 +571,7 @@ unsigned segment_index = 0; for (const NGInlineItem& item : items) { - if (item.Type() == NGInlineItem::kText && + if (item.Type() == NGInlineItem::kText && item.Length() && item.Style()->GetFont().GetFontDescription().Orientation() == FontOrientation::kVerticalMixed) { segment_index = data->segments->AppendMixedFontOrientation( @@ -639,7 +641,7 @@ for (unsigned index = 0; index < items->size();) { NGInlineItem& start_item = (*items)[index]; - if (start_item.Type() != NGInlineItem::kText) { + if (start_item.Type() != NGInlineItem::kText || !start_item.Length()) { index++; continue; } @@ -675,6 +677,8 @@ break; } if (item.Type() == NGInlineItem::kText) { + if (!item.Length()) + continue; // Shape adjacent items together if the font and direction matches to // allow ligatures and kerning to apply. // Also run segment properties must match because NGInlineItem gives @@ -769,7 +773,7 @@ unsigned range_index = 0; for (; index < end_index; index++) { NGInlineItem& item = (*items)[index]; - if (item.Type() != NGInlineItem::kText) + if (item.Type() != NGInlineItem::kText || !item.Length()) continue; // We don't use SafeToBreak API here because this is not a line break. @@ -790,7 +794,7 @@ #if DCHECK_IS_ON() for (const NGInlineItem& item : *items) { - if (item.Type() == NGInlineItem::kText) { + if (item.Type() == NGInlineItem::kText && item.Length()) { DCHECK(item.TextShapeResult()); DCHECK_EQ(item.TextShapeResult()->StartIndex(), item.StartOffset()); DCHECK_EQ(item.TextShapeResult()->EndIndex(), item.EndOffset()); @@ -1019,9 +1023,6 @@ NGPositionedFloatVector empty_leading_floats; NGLineLayoutOpportunity line_opportunity(available_inline_size); LayoutUnit result; - LayoutUnit previous_floats_inline_size = - input.float_left_inline_size + input.float_right_inline_size; - DCHECK_GE(previous_floats_inline_size, 0); NGLineBreaker line_breaker(node, mode, space, line_opportunity, empty_leading_floats, /* handled_leading_floats_index */ 0u, @@ -1029,22 +1030,92 @@ line_breaker.SetMaxSizeCache(max_size_cache); const NGInlineItemsData& items_data = line_breaker.ItemsData(); + // Computes max-size for floats in inline formatting context. + class FloatsMaxSize { + STACK_ALLOCATED(); + + public: + explicit FloatsMaxSize(const MinMaxSizeInput& input) + : floats_inline_size_(input.float_left_inline_size + + input.float_right_inline_size) { + DCHECK_GE(floats_inline_size_, 0); + } + + void AddFloat(const ComputedStyle& float_style, + const ComputedStyle& style, + LayoutUnit float_inline_max_size_with_margin) { + floating_objects_.push_back(FloatingObject{ + float_style, style, float_inline_max_size_with_margin}); + } + + LayoutUnit ComputeMaxSizeForLine(LayoutUnit line_inline_size, + LayoutUnit max_inline_size) { + if (floating_objects_.IsEmpty()) + return std::max(max_inline_size, line_inline_size); + + EFloat previous_float_type = EFloat::kNone; + for (const auto& floating_object : floating_objects_) { + const EClear float_clear = + ResolvedClear(floating_object.float_style, floating_object.style); + + // If this float clears the previous float we start a new "line". + // This is subtly different to block layout which will only reset either + // the left or the right float size trackers. + if ((previous_float_type == EFloat::kLeft && + (float_clear == EClear::kBoth || float_clear == EClear::kLeft)) || + (previous_float_type == EFloat::kRight && + (float_clear == EClear::kBoth || float_clear == EClear::kRight))) { + max_inline_size = + std::max(max_inline_size, line_inline_size + floats_inline_size_); + floats_inline_size_ = LayoutUnit(); + } + + // When negative margins move the float outside the content area, + // such float should not affect the content size. + floats_inline_size_ += floating_object.float_inline_max_size_with_margin + .ClampNegativeToZero(); + previous_float_type = ResolvedFloating(floating_object.float_style, + floating_object.style); + } + max_inline_size = + std::max(max_inline_size, line_inline_size + floats_inline_size_); + floats_inline_size_ = LayoutUnit(); + floating_objects_.Shrink(0); + return max_inline_size; + } + + private: + LayoutUnit floats_inline_size_; + struct FloatingObject { + const ComputedStyle& float_style; + const ComputedStyle& style; + LayoutUnit float_inline_max_size_with_margin; + }; + Vector<FloatingObject, 4> floating_objects_; + }; + // This struct computes the max size from the line break results for the min // size. struct MaxSizeFromMinSize { + STACK_ALLOCATED(); + + public: LayoutUnit position; LayoutUnit max_size; const NGInlineItemsData& items_data; const NGInlineItem* next_item; const NGLineBreaker::MaxSizeCache& max_size_cache; + FloatsMaxSize* floats; bool is_after_break = true; explicit MaxSizeFromMinSize( const NGInlineItemsData& items_data, - const NGLineBreaker::MaxSizeCache& max_size_cache) + const NGLineBreaker::MaxSizeCache& max_size_cache, + FloatsMaxSize* floats) : items_data(items_data), next_item(items_data.items.begin()), - max_size_cache(max_size_cache) {} + max_size_cache(max_size_cache), + floats(floats) {} // Add all text items up to |end|. The line break results for min size // may break text into multiple lines, and may remove trailing spaces. For @@ -1052,7 +1123,7 @@ void AddTextUntil(const NGInlineItem* end) { DCHECK(end); for (; next_item != end; ++next_item) { - if (next_item->Type() == NGInlineItem::kText) { + if (next_item->Type() == NGInlineItem::kText && next_item->Length()) { DCHECK(next_item->TextShapeResult()); const ShapeResult& shape_result = *next_item->TextShapeResult(); position += shape_result.SnappedWidth().ClampNegativeToZero(); @@ -1065,8 +1136,8 @@ // removed during the line breaking. AddTextUntil(&item); next_item = std::next(&item); - // Reset |position| to zero. - max_size = std::max(max_size, position); + max_size = floats->ComputeMaxSizeForLine(position.ClampNegativeToZero(), + max_size); position = LayoutUnit(); is_after_break = true; } @@ -1088,7 +1159,8 @@ LayoutUnit Finish(const NGInlineItem* end) { AddTextUntil(end); - return std::max(position, max_size); + return floats->ComputeMaxSizeForLine(position.ClampNegativeToZero(), + max_size); } void ComputeFromMinSize(const NGLineInfo& line_info) { @@ -1129,12 +1201,9 @@ } } }; - // Instantiate |MaxSizeFromMinSize| if we can compute the max size in 1 pass. - base::Optional<MaxSizeFromMinSize> max_size_from_min_size; - if (mode == NGLineBreakerMode::kMinContent && !previous_floats_inline_size) { - DCHECK(max_size_cache); - max_size_from_min_size.emplace(items_data, *max_size_cache); - } + FloatsMaxSize floats_max_size(input); + MaxSizeFromMinSize max_size_from_min_size(items_data, *max_size_cache, + &floats_max_size); Vector<LayoutObject*> floats_for_min_max; do { @@ -1149,25 +1218,6 @@ LayoutUnit inline_size = line_info.Width(); DCHECK_EQ(inline_size, line_info.ComputeWidth().ClampNegativeToZero()); - // These variables are only used for the max-content calculation. - LayoutUnit floats_inline_size = mode == NGLineBreakerMode::kMaxContent - ? previous_floats_inline_size - : LayoutUnit(); - EFloat previous_float_type = EFloat::kNone; - - // Earlier floats can only be assumed to affect the first line, so clear - // them now. - previous_floats_inline_size = LayoutUnit(); - - // Compute the max size from the line break result for the min size. - if (max_size_from_min_size.has_value()) { - // If there were floats, fall back to 2 pass for now. - if (!floats_for_min_max.IsEmpty()) - max_size_from_min_size.reset(); - else - max_size_from_min_size->ComputeFromMinSize(line_info); - } - for (auto* floating_object : floats_for_min_max) { DCHECK(floating_object->IsFloating()); @@ -1183,35 +1233,21 @@ if (mode == NGLineBreakerMode::kMinContent) { result = std::max(result, child_sizes.min_size + child_inline_margins); - } else { - const EClear float_clear = ResolvedClear(float_style, style); - - // If this float clears the previous float we start a new "line". - // This is subtly different to block layout which will only reset either - // the left or the right float size trackers. - if ((previous_float_type == EFloat::kLeft && - (float_clear == EClear::kBoth || float_clear == EClear::kLeft)) || - (previous_float_type == EFloat::kRight && - (float_clear == EClear::kBoth || float_clear == EClear::kRight))) { - result = std::max(result, inline_size + floats_inline_size); - floats_inline_size = LayoutUnit(); - } - - // When negative margins move the float outside the content area, - // such float should not affect the content size. - floats_inline_size += - (child_sizes.max_size + child_inline_margins).ClampNegativeToZero(); - previous_float_type = ResolvedFloating(float_style, style); } + floats_max_size.AddFloat(float_style, style, + child_sizes.max_size + child_inline_margins); } - // NOTE: floats_inline_size will be zero for the min-content calculation, - // and will just take the inline size of the un-breakable line. - result = std::max(result, inline_size + floats_inline_size); + if (mode == NGLineBreakerMode::kMinContent) { + result = std::max(result, inline_size); + max_size_from_min_size.ComputeFromMinSize(line_info); + } else { + result = floats_max_size.ComputeMaxSizeForLine(inline_size, result); + } } while (!line_breaker.IsFinished()); - if (max_size_from_min_size.has_value()) { - *max_size_out = max_size_from_min_size->Finish(items_data.items.end()); + if (mode == NGLineBreakerMode::kMinContent) { + *max_size_out = max_size_from_min_size.Finish(items_data.items.end()); // Check the max size matches to the value computed from 2 pass. DCHECK_EQ(**max_size_out, ComputeContentSize(node, container_writing_mode, input, @@ -1238,16 +1274,8 @@ sizes.min_size = ComputeContentSize(*this, container_writing_mode, input, NGLineBreakerMode::kMinContent, &max_size_cache, &max_size); - - // If the max size is also computed, use it. - if (max_size.has_value()) { - sizes.max_size = *max_size; - } else { - // Compute the sum of inline sizes of all inline boxes with no line breaks. - sizes.max_size = ComputeContentSize(*this, container_writing_mode, input, - NGLineBreakerMode::kMaxContent, - &max_size_cache, nullptr); - } + DCHECK(max_size.has_value()); + sizes.max_size = *max_size; // Negative text-indent can make min > max. Ensure min is the minimum size. sizes.min_size = std::min(sizes.min_size, sizes.max_size);
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h index 586df137..166917a 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node.h
@@ -105,13 +105,6 @@ object->SetFirstInlineFragment(nullptr); } - // A helper function for NGInlineItemsBuilder. - static void ClearNeedsLayout(LayoutObject* object) { - object->ClearNeedsLayout(); - object->ClearNeedsCollectInlines(); - ClearInlineFragment(object); - } - protected: bool IsPrepareLayoutFinished() const;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc index 9993472..5b9bc42 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_node_test.cc
@@ -1172,7 +1172,8 @@ ComputeMinMaxSize(NGInlineNode(layout_block_flow_)); auto lines = MarkLineBoxesDirty(); - EXPECT_FALSE(lines[0]->IsDirty()); + // TODO(kojii): Ideally, 0 should be false, or even 1 as well. + EXPECT_TRUE(lines[0]->IsDirty()); EXPECT_TRUE(lines[1]->IsDirty()); }
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc index c42d798..d36e73f 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
@@ -149,6 +149,12 @@ return true; } +inline void ClearNeedsLayout(const NGInlineItem& item) { + LayoutObject* layout_object = item.GetLayoutObject(); + if (layout_object->NeedsLayout()) + layout_object->ClearNeedsLayout(); +} + } // namespace NGLineBreaker::NGLineBreaker(NGInlineNode node, @@ -377,7 +383,10 @@ // They (or part of them) may also overhang the available width. const NGInlineItem& item = items[item_index_]; if (item.Type() == NGInlineItem::kText) { - HandleText(item, line_info); + if (item.Length()) + HandleText(item, line_info); + else + HandleEmptyText(item, line_info); #if DCHECK_IS_ON() if (!item_results->IsEmpty()) item_results->back().CheckConsistency(true); @@ -490,6 +499,7 @@ // NGInlineItemBuilder. ++offset_; if (offset_ == item.EndOffset()) { + ClearNeedsLayout(item); MoveToNextOf(item); return; } @@ -758,6 +768,14 @@ return true; } +void NGLineBreaker::HandleEmptyText(const NGInlineItem& item, + NGLineInfo* line_info) { + // Fully collapsed text is not needed for line breaking/layout, but it may + // have |SelfNeedsLayout()| set. Mark it was laid out. + ClearNeedsLayout(item); + MoveToNextOf(item); +} + // Re-shape the specified range of |NGInlineItem|. scoped_refptr<ShapeResult> NGLineBreaker::ShapeText(const NGInlineItem& item, unsigned start, @@ -892,6 +910,7 @@ state_ = LineBreakState::kDone; return; } + ClearNeedsLayout(item); item_index_++; state_ = LineBreakState::kTrailing; } @@ -915,6 +934,7 @@ item_result->inline_size = item_result->shape_result->SnappedWidth(); position_ += item_result->inline_size; } else { + ClearNeedsLayout(*item_result->item); line_info->MutableResults()->erase(item_result); } trailing_collapsible_space_.reset();
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h index f55724b2..1e9baf8 100644 --- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h +++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h
@@ -135,6 +135,7 @@ const NGInlineItem&, const ShapeResult&, NGLineInfo*); + void HandleEmptyText(const NGInlineItem& item, NGLineInfo*); scoped_refptr<ShapeResultView> TruncateLineEndResult( const NGLineInfo&,
diff --git a/third_party/blink/renderer/core/loader/appcache/application_cache_host.cc b/third_party/blink/renderer/core/loader/appcache/application_cache_host.cc index 9722296..ae2ea058 100644 --- a/third_party/blink/renderer/core/loader/appcache/application_cache_host.cc +++ b/third_party/blink/renderer/core/loader/appcache/application_cache_host.cc
@@ -40,7 +40,6 @@ #include "third_party/blink/public/platform/web_url_response.h" #include "third_party/blink/public/platform/web_vector.h" #include "third_party/blink/renderer/core/events/application_cache_error_event.h" -#include "third_party/blink/renderer/core/events/current_input_event.h" #include "third_party/blink/renderer/core/events/progress_event.h" #include "third_party/blink/renderer/core/frame/deprecation.h" #include "third_party/blink/renderer/core/frame/hosts_using_features.h" @@ -162,8 +161,6 @@ // navigation. see ApplicationCacheGroup::selectCache() FrameLoadRequest request(document, ResourceRequest(document->Url())); request.SetClientRedirect(ClientRedirectPolicy::kClientRedirect); - if (const WebInputEvent* input_event = CurrentInputEvent::Get()) - request.SetInputStartTime(input_event->TimeStamp()); frame->Navigate(request, WebFrameLoadType::kReplaceCurrentItem); } }
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc index 798e858..70ec829 100644 --- a/third_party/blink/renderer/core/loader/document_loader.cc +++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -1306,12 +1306,12 @@ if (response_.CacheControlContainsNoCache()) { GetFrame()->GetFrameScheduler()->RegisterStickyFeature( SchedulingPolicy::Feature::kMainResourceHasCacheControlNoCache, - {SchedulingPolicy::DisableBackForwardCache()}); + {SchedulingPolicy::RecordMetricsForBackForwardCache()}); } if (response_.CacheControlContainsNoStore()) { GetFrame()->GetFrameScheduler()->RegisterStickyFeature( SchedulingPolicy::Feature::kMainResourceHasCacheControlNoStore, - {SchedulingPolicy::DisableBackForwardCache()}); + {SchedulingPolicy::RecordMetricsForBackForwardCache()}); } // When a new navigation commits in the frame, subresource loading should be
diff --git a/third_party/blink/renderer/core/loader/frame_load_request.cc b/third_party/blink/renderer/core/loader/frame_load_request.cc index 2dbc56f1..78c15ae60 100644 --- a/third_party/blink/renderer/core/loader/frame_load_request.cc +++ b/third_party/blink/renderer/core/loader/frame_load_request.cc
@@ -6,6 +6,7 @@ #include "third_party/blink/public/common/blob/blob_utils.h" #include "third_party/blink/public/platform/web_url_request.h" +#include "third_party/blink/renderer/core/events/current_input_event.h" #include "third_party/blink/renderer/core/fileapi/public_url_manager.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" @@ -48,6 +49,9 @@ resource_request_.SetFetchRedirectMode( network::mojom::FetchRedirectMode::kManual); + if (const WebInputEvent* input_event = CurrentInputEvent::Get()) + SetInputStartTime(input_event->TimeStamp()); + if (origin_document) { DCHECK(!resource_request_.RequestorOrigin()); resource_request_.SetRequestorOrigin(origin_document->GetSecurityOrigin());
diff --git a/third_party/blink/renderer/core/loader/navigation_policy_test.cc b/third_party/blink/renderer/core/loader/navigation_policy_test.cc index 1882709f..d28c630f 100644 --- a/third_party/blink/renderer/core/loader/navigation_policy_test.cc +++ b/third_party/blink/renderer/core/loader/navigation_policy_test.cc
@@ -239,6 +239,52 @@ } } +TEST_F(NavigationPolicyTest, NoOpenerAndNoReferrer) { + static const struct { + const char* feature_string; + NavigationPolicy policy; + } kCases[] = { + {"", kNavigationPolicyNewForegroundTab}, + {"noopener, noreferrer", kNavigationPolicyNewForegroundTab}, + {"noopener, notreferrer", kNavigationPolicyNewPopup}, + {"notopener, noreferrer", kNavigationPolicyNewPopup}, + {"something, noopener, noreferrer", kNavigationPolicyNewPopup}, + {"noopener, noreferrer, something", kNavigationPolicyNewPopup}, + {"noopener, something, noreferrer", kNavigationPolicyNewPopup}, + {"NoOpEnEr, NoReFeRrEr", kNavigationPolicyNewForegroundTab}, + }; + + for (const auto& test : kCases) { + EXPECT_EQ(test.policy, + NavigationPolicyForCreateWindow( + GetWindowFeaturesFromString(test.feature_string))) + << "Testing '" << test.feature_string << "'"; + } +} + +TEST_F(NavigationPolicyTest, NoReferrer) { + static const struct { + const char* feature_string; + NavigationPolicy policy; + } kCases[] = { + {"", kNavigationPolicyNewForegroundTab}, + {"something", kNavigationPolicyNewPopup}, + {"something, something", kNavigationPolicyNewPopup}, + {"notreferrer", kNavigationPolicyNewPopup}, + {"noreferrer", kNavigationPolicyNewForegroundTab}, + {"something, noreferrer", kNavigationPolicyNewPopup}, + {"noreferrer, something", kNavigationPolicyNewPopup}, + {"NoReFeRrEr", kNavigationPolicyNewForegroundTab}, + }; + + for (const auto& test : kCases) { + EXPECT_EQ(test.policy, + NavigationPolicyForCreateWindow( + GetWindowFeaturesFromString(test.feature_string))) + << "Testing '" << test.feature_string << "'"; + } +} + TEST_F(NavigationPolicyTest, NotResizableForcesPopup) { features.resizable = false; EXPECT_EQ(kNavigationPolicyNewPopup,
diff --git a/third_party/blink/renderer/core/page/create_window.cc b/third_party/blink/renderer/core/page/create_window.cc index 6727b84d..64bd5a1 100644 --- a/third_party/blink/renderer/core/page/create_window.cc +++ b/third_party/blink/renderer/core/page/create_window.cc
@@ -141,7 +141,8 @@ if (key_string.IsEmpty()) continue; - if (!ui_features_were_disabled && key_string != "noopener") { + if (!ui_features_were_disabled && key_string != "noopener" && + key_string != "noreferrer") { ui_features_were_disabled = true; window_features.menu_bar_visible = false; window_features.status_bar_visible = false; @@ -173,6 +174,8 @@ window_features.resizable = value; } else if (key_string == "noopener") { window_features.noopener = value; + } else if (key_string == "noreferrer") { + window_features.noreferrer = value; } else if (key_string == "background") { window_features.background = true; } else if (key_string == "persistent") { @@ -180,6 +183,9 @@ } } + if (window_features.noreferrer) + window_features.noopener = true; + return window_features; }
diff --git a/third_party/blink/renderer/core/page/touch_adjustment.cc b/third_party/blink/renderer/core/page/touch_adjustment.cc index a5b8eb3e..46cf35b2 100644 --- a/third_party/blink/renderer/core/page/touch_adjustment.cc +++ b/third_party/blink/renderer/core/page/touch_adjustment.cc
@@ -47,8 +47,10 @@ namespace touch_adjustment { const float kZeroTolerance = 1e-6f; -// The maximum adjustment range (diameters) in dip. +// The touch adjustment range (diameters) in dip, using same as the value in +// gesture_configuration_android.cc constexpr float kMaxAdjustmentSizeDip = 32.f; +constexpr float kMinAdjustmentSizeDip = 20.f; // Class for remembering absolute quads of a target node and what node they // represent. @@ -530,10 +532,13 @@ const LayoutSize max_size_in_dip(touch_adjustment::kMaxAdjustmentSizeDip, touch_adjustment::kMaxAdjustmentSizeDip); + const LayoutSize min_size_in_dip(touch_adjustment::kMinAdjustmentSizeDip, + touch_adjustment::kMinAdjustmentSizeDip); // (when use-zoom-for-dsf enabled) touch_area is in physical pixel scaled, // max_size_in_dip should be converted to physical pixel and scale too. - return touch_area.ShrunkTo(max_size_in_dip * - (device_scale_factor / page_scale_factor)); + return touch_area + .ShrunkTo(max_size_in_dip * (device_scale_factor / page_scale_factor)) + .ExpandedTo(min_size_in_dip * (device_scale_factor / page_scale_factor)); } } // namespace blink
diff --git a/third_party/blink/renderer/core/page/touch_adjustment_test.cc b/third_party/blink/renderer/core/page/touch_adjustment_test.cc index 57eafa2..ee3823a9 100644 --- a/third_party/blink/renderer/core/page/touch_adjustment_test.cc +++ b/third_party/blink/renderer/core/page/touch_adjustment_test.cc
@@ -50,6 +50,7 @@ } const LayoutSize max_touch_area_dip_unscaled = LayoutSize(32, 32); + const LayoutSize min_touch_area_dip_unscaled = LayoutSize(20, 20); private: Persistent<MockChromeClient> chrome_client_; @@ -102,4 +103,25 @@ EXPECT_EQ(result, max_touch_area_dip_unscaled); } +TEST_F(TouchAdjustmentTest, AdjustmentRangeLowerboundScale) { + // touch_area is set to 0 to always lower than minimal range. + LayoutSize touch_area(0, 0); + LayoutSize result; + + // Browser zoom without dsf change is not changing the size. + SetZoomAndScale(1 /* dsf */, 2 /* browser_zoom */, 1 /* page_scale */); + result = GetHitTestRectForAdjustment(GetFrame(), touch_area); + EXPECT_EQ(result, min_touch_area_dip_unscaled); + + // touch_area is in physical pixel, should change with dsf change. + SetZoomAndScale(2 /* dsf */, 1 /* browser_zoom */, 1 /* page_scale */); + result = GetHitTestRectForAdjustment(GetFrame(), touch_area); + EXPECT_EQ(result, min_touch_area_dip_unscaled * 2.f); + + // Adjustment range is changed with page scale. + SetZoomAndScale(1 /* dsf */, 1 /* browser_zoom */, 2 /* page_scale */); + result = GetHitTestRectForAdjustment(GetFrame(), touch_area); + EXPECT_EQ(result, min_touch_area_dip_unscaled * (1.f / 2)); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/page/window_features_test.cc b/third_party/blink/renderer/core/page/window_features_test.cc index 7e2ad0b..e6b11fe8 100644 --- a/third_party/blink/renderer/core/page/window_features_test.cc +++ b/third_party/blink/renderer/core/page/window_features_test.cc
@@ -34,4 +34,34 @@ } } +TEST_F(WindowFeaturesTest, NoReferrer) { + static const struct { + const char* feature_string; + bool noopener; + bool noreferrer; + } kCases[] = { + {"", false, false}, + {"something", false, false}, + {"something, something", false, false}, + {"notreferrer", false, false}, + {"noreferrer", true, true}, + {"something, noreferrer", true, true}, + {"noreferrer, something", true, true}, + {"NoReFeRrEr", true, true}, + {"noreferrer, noopener=0", true, true}, + {"noreferrer=0, noreferrer=1", true, true}, + {"noreferrer=1, noreferrer=0", false, false}, + {"noreferrer=1, noreferrer=0, noopener=1", true, false}, + {"something, noreferrer=1, noreferrer=0", false, false}, + {"noopener=1, noreferrer=1, noreferrer=0", true, false}, + {"noopener=0, noreferrer=1, noreferrer=0", false, false}, + }; + + for (const auto& test : kCases) { + EXPECT_EQ(test.noreferrer, + GetWindowFeaturesFromString(test.feature_string).noreferrer) + << "Testing '" << test.feature_string << "'"; + } +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/scheduler/scheduler_affecting_features_test.cc b/third_party/blink/renderer/core/scheduler/scheduler_affecting_features_test.cc index f526785..4c9de60 100644 --- a/third_party/blink/renderer/core/scheduler/scheduler_affecting_features_test.cc +++ b/third_party/blink/renderer/core/scheduler/scheduler_affecting_features_test.cc
@@ -23,8 +23,10 @@ class SchedulingAffectingFeaturesTest : public SimTest { public: PageScheduler* PageScheduler() { - return MainFrame().Scheduler()->GetPageScheduler(); + return MainFrameScheduler()->GetPageScheduler(); } + + FrameScheduler* MainFrameScheduler() { return MainFrame().Scheduler(); } }; TEST_F(SchedulingAffectingFeaturesTest, WebSocketStopsThrottling) { @@ -33,7 +35,8 @@ LoadURL("https://example.com/"); EXPECT_FALSE(PageScheduler()->OptedOutFromAggressiveThrottlingForTest()); - EXPECT_THAT(PageScheduler()->GetActiveFeaturesOptingOutFromBackForwardCache(), + EXPECT_THAT(MainFrameScheduler() + ->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), testing::UnorderedElementsAre()); main_resource.Complete( @@ -43,13 +46,15 @@ EXPECT_TRUE(PageScheduler()->OptedOutFromAggressiveThrottlingForTest()); EXPECT_THAT( - PageScheduler()->GetActiveFeaturesOptingOutFromBackForwardCache(), + MainFrameScheduler() + ->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebSocket)); MainFrame().ExecuteScript(WebString("socket.close();")); EXPECT_FALSE(PageScheduler()->OptedOutFromAggressiveThrottlingForTest()); - EXPECT_THAT(PageScheduler()->GetActiveFeaturesOptingOutFromBackForwardCache(), + EXPECT_THAT(MainFrameScheduler() + ->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), testing::UnorderedElementsAre()); } @@ -61,7 +66,8 @@ LoadURL("https://example.com/"); EXPECT_FALSE(PageScheduler()->OptedOutFromAggressiveThrottlingForTest()); - EXPECT_THAT(PageScheduler()->GetActiveFeaturesOptingOutFromBackForwardCache(), + EXPECT_THAT(MainFrameScheduler() + ->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), testing::UnorderedElementsAre()); main_resource.Complete( @@ -71,13 +77,15 @@ EXPECT_TRUE(PageScheduler()->OptedOutFromAggressiveThrottlingForTest()); EXPECT_THAT( - PageScheduler()->GetActiveFeaturesOptingOutFromBackForwardCache(), + MainFrameScheduler() + ->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebRTC)); MainFrame().ExecuteScript(WebString("data_channel.close();")); EXPECT_FALSE(PageScheduler()->OptedOutFromAggressiveThrottlingForTest()); - EXPECT_THAT(PageScheduler()->GetActiveFeaturesOptingOutFromBackForwardCache(), + EXPECT_THAT(MainFrameScheduler() + ->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), testing::UnorderedElementsAre()); } @@ -93,14 +101,16 @@ main_resource.Complete("<img src=image.png>"); EXPECT_THAT( - PageScheduler()->GetActiveFeaturesOptingOutFromBackForwardCache(), + MainFrameScheduler() + ->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), testing::UnorderedElementsAre( SchedulingPolicy::Feature::kMainResourceHasCacheControlNoStore)); image_resource.Complete(); EXPECT_THAT( - PageScheduler()->GetActiveFeaturesOptingOutFromBackForwardCache(), + MainFrameScheduler() + ->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), testing::UnorderedElementsAre( SchedulingPolicy::Feature::kMainResourceHasCacheControlNoStore, SchedulingPolicy::Feature::kSubresourceHasCacheControlNoStore)); @@ -117,14 +127,16 @@ main_resource.Complete("<img src=image.png>"); EXPECT_THAT( - PageScheduler()->GetActiveFeaturesOptingOutFromBackForwardCache(), + MainFrameScheduler() + ->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), testing::UnorderedElementsAre( SchedulingPolicy::Feature::kMainResourceHasCacheControlNoCache)); image_resource.Complete(); EXPECT_THAT( - PageScheduler()->GetActiveFeaturesOptingOutFromBackForwardCache(), + MainFrameScheduler() + ->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), testing::UnorderedElementsAre( SchedulingPolicy::Feature::kMainResourceHasCacheControlNoCache, SchedulingPolicy::Feature::kSubresourceHasCacheControlNoCache)); @@ -138,7 +150,8 @@ main_resource1.Complete(); EXPECT_THAT( - PageScheduler()->GetActiveFeaturesOptingOutFromBackForwardCache(), + MainFrameScheduler() + ->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), testing::UnorderedElementsAre( SchedulingPolicy::Feature::kMainResourceHasCacheControlNoCache, SchedulingPolicy::Feature::kMainResourceHasCacheControlNoStore)); @@ -147,7 +160,8 @@ LoadURL("https://bar.com/"); main_resource2.Complete(); - EXPECT_THAT(PageScheduler()->GetActiveFeaturesOptingOutFromBackForwardCache(), + EXPECT_THAT(MainFrameScheduler() + ->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), testing::UnorderedElementsAre()); } @@ -159,7 +173,8 @@ " window.addEventListener(\"pageshow\", () => {}); " "</script>)"); - EXPECT_THAT(PageScheduler()->GetActiveFeaturesOptingOutFromBackForwardCache(), + EXPECT_THAT(MainFrameScheduler() + ->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), testing::UnorderedElementsAre( SchedulingPolicy::Feature::kPageShowEventListener)); } @@ -172,7 +187,8 @@ " window.addEventListener(\"pagehide\", () => {}); " "</script>)"); - EXPECT_THAT(PageScheduler()->GetActiveFeaturesOptingOutFromBackForwardCache(), + EXPECT_THAT(MainFrameScheduler() + ->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), testing::UnorderedElementsAre( SchedulingPolicy::Feature::kPageHideEventListener)); } @@ -185,7 +201,8 @@ " window.addEventListener(\"beforeunload\", () => {}); " "</script>)"); - EXPECT_THAT(PageScheduler()->GetActiveFeaturesOptingOutFromBackForwardCache(), + EXPECT_THAT(MainFrameScheduler() + ->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), testing::UnorderedElementsAre( SchedulingPolicy::Feature::kBeforeUnloadEventListener)); } @@ -198,7 +215,8 @@ " window.addEventListener(\"unload\", () => {}); " "</script>)"); - EXPECT_THAT(PageScheduler()->GetActiveFeaturesOptingOutFromBackForwardCache(), + EXPECT_THAT(MainFrameScheduler() + ->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), testing::UnorderedElementsAre( SchedulingPolicy::Feature::kUnloadEventListener)); } @@ -211,7 +229,8 @@ " window.addEventListener(\"freeze\", () => {}); " "</script>)"); - EXPECT_THAT(PageScheduler()->GetActiveFeaturesOptingOutFromBackForwardCache(), + EXPECT_THAT(MainFrameScheduler() + ->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), testing::UnorderedElementsAre( SchedulingPolicy::Feature::kFreezeEventListener)); } @@ -224,7 +243,8 @@ " window.addEventListener(\"resume\", () => {}); " "</script>)"); - EXPECT_THAT(PageScheduler()->GetActiveFeaturesOptingOutFromBackForwardCache(), + EXPECT_THAT(MainFrameScheduler() + ->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), testing::UnorderedElementsAre( SchedulingPolicy::Feature::kResumeEventListener)); } @@ -247,7 +267,8 @@ base::RunLoop().RunUntilIdle(); - EXPECT_THAT(PageScheduler()->GetActiveFeaturesOptingOutFromBackForwardCache(), + EXPECT_THAT(MainFrameScheduler() + ->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), testing::UnorderedElementsAre( SchedulingPolicy::Feature::kContainsPlugins)); }
diff --git a/third_party/blink/renderer/core/testing/dummy_page_holder.cc b/third_party/blink/renderer/core/testing/dummy_page_holder.cc index 85e5db0..59b521d 100644 --- a/third_party/blink/renderer/core/testing/dummy_page_holder.cc +++ b/third_party/blink/renderer/core/testing/dummy_page_holder.cc
@@ -33,6 +33,7 @@ #include <memory> #include "base/memory/ptr_util.h" +#include "third_party/blink/renderer/core/core_initializer.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_view.h" @@ -80,6 +81,8 @@ frame_->SetView(LocalFrameView::Create(*frame_, initial_view_size)); frame_->View()->GetPage()->GetVisualViewport().SetSize(initial_view_size); frame_->Init(); + + CoreInitializer::GetInstance().ProvideModulesToPage(GetPage(), nullptr); } DummyPageHolder::~DummyPageHolder() {
diff --git a/third_party/blink/renderer/modules/media_controls/BUILD.gn b/third_party/blink/renderer/modules/media_controls/BUILD.gn index 8532518..80ac541 100644 --- a/third_party/blink/renderer/modules/media_controls/BUILD.gn +++ b/third_party/blink/renderer/modules/media_controls/BUILD.gn
@@ -104,6 +104,8 @@ if (is_android && notouch_build) { sources += [ + "touchless/elements/media_controls_touchless_bottom_container_element.cc", + "touchless/elements/media_controls_touchless_bottom_container_element.h", "touchless/elements/media_controls_touchless_element.cc", "touchless/elements/media_controls_touchless_element.h", "touchless/elements/media_controls_touchless_overlay_element.cc",
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.cc b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.cc new file mode 100644 index 0000000..3efbc4c --- /dev/null +++ b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.cc
@@ -0,0 +1,35 @@ +// Copyright 2019 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 "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h" + +#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h" +#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h" + +namespace blink { + +MediaControlsTouchlessBottomContainerElement:: + MediaControlsTouchlessBottomContainerElement( + MediaControlsTouchlessImpl& media_controls) + : MediaControlsTouchlessElement(media_controls) { + SetShadowPseudoId( + AtomicString("-internal-media-controls-touchless-bottom-container")); + + MediaControlsTouchlessTimeDisplayElement* time_display_element = + MakeGarbageCollected<MediaControlsTouchlessTimeDisplayElement>( + media_controls); + MediaControlsTouchlessTimelineElement* timeline_element = + MakeGarbageCollected<MediaControlsTouchlessTimelineElement>( + media_controls); + + ParserAppendChild(time_display_element); + ParserAppendChild(timeline_element); +} + +void MediaControlsTouchlessBottomContainerElement::Trace( + blink::Visitor* visitor) { + MediaControlsTouchlessElement::Trace(visitor); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h new file mode 100644 index 0000000..bfe01bc --- /dev/null +++ b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h
@@ -0,0 +1,23 @@ +// Copyright 2019 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 THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_BOTTOM_CONTAINER_ELEMENT_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_BOTTOM_CONTAINER_ELEMENT_H_ + +#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h" + +namespace blink { + +class MediaControlsTouchlessImpl; + +class MediaControlsTouchlessBottomContainerElement + : public MediaControlsTouchlessElement { + public: + MediaControlsTouchlessBottomContainerElement(MediaControlsTouchlessImpl&); + void Trace(blink::Visitor*) override; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_BOTTOM_CONTAINER_ELEMENT_H_
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.cc b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.cc index e6142888..cbbac960 100644 --- a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.cc +++ b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.cc
@@ -4,14 +4,26 @@ #include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h" +#include "third_party/blink/renderer/core/dom/dom_token_list.h" +#include "third_party/blink/renderer/core/html/media/html_media_element.h" #include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h" #include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener.h" namespace blink { +namespace { + +// Amount of time that media controls are visible. +constexpr WTF::TimeDelta kTimeToHideControl = TimeDelta::FromMilliseconds(3000); + +const char kTransparentCSSClass[] = "transparent"; + +} // namespace + MediaControlsTouchlessElement::MediaControlsTouchlessElement( MediaControlsTouchlessImpl& media_controls) - : media_controls_(media_controls) { + : HTMLDivElement(media_controls.GetDocument()), + media_controls_(media_controls) { media_controls_->MediaEventListener().AddObserver(this); } @@ -19,7 +31,46 @@ return media_controls_->MediaElement(); } +void MediaControlsTouchlessElement::MakeOpaque(bool should_hide) { + EnsureHideControlTimer(); + + classList().Remove(kTransparentCSSClass); + + if (hide_control_timer_->IsActive()) + StopHideControlTimer(); + + if (should_hide) + StartHideControlTimer(); +} + +void MediaControlsTouchlessElement::MakeTransparent() { + classList().Add(kTransparentCSSClass); +} + +void MediaControlsTouchlessElement::EnsureHideControlTimer() { + if (!hide_control_timer_) { + hide_control_timer_ = + std::make_unique<TaskRunnerTimer<MediaControlsTouchlessElement>>( + MediaElement().GetDocument().GetTaskRunner( + TaskType::kInternalMedia), + this, &MediaControlsTouchlessElement::HideControlTimerFired); + } +} + +void MediaControlsTouchlessElement::HideControlTimerFired(TimerBase*) { + MakeTransparent(); +} + +void MediaControlsTouchlessElement::StartHideControlTimer() { + hide_control_timer_->StartOneShot(kTimeToHideControl, FROM_HERE); +} + +void MediaControlsTouchlessElement::StopHideControlTimer() { + hide_control_timer_->Stop(); +} + void MediaControlsTouchlessElement::Trace(blink::Visitor* visitor) { + HTMLDivElement::Trace(visitor); visitor->Trace(media_controls_); }
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h index 0785f485..bec599edd 100644 --- a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h +++ b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_element.h
@@ -6,8 +6,10 @@ #define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIA_CONTROLS_TOUCHLESS_ELEMENTS_MEDIA_CONTROLS_TOUCHLESS_ELEMENT_H_ #include "base/macros.h" +#include "third_party/blink/renderer/core/html/html_div_element.h" #include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener_observer.h" #include "third_party/blink/renderer/platform/heap/member.h" +#include "third_party/blink/renderer/platform/timer.h" namespace blink { @@ -15,12 +17,18 @@ class MediaControlsTouchlessImpl; class MediaControlsTouchlessElement - : public MediaControlsTouchlessMediaEventListenerObserver { + : public HTMLDivElement, + public MediaControlsTouchlessMediaEventListenerObserver { + USING_GARBAGE_COLLECTED_MIXIN(MediaControlsTouchlessElement); + public: HTMLMediaElement& MediaElement() const; void Trace(blink::Visitor* visitor) override; + void MakeOpaque(bool /** True if control should hide after timer fired */); + void MakeTransparent(); + // Non-touch media event listener observer implementation. void OnFocusIn() override {} void OnTimeUpdate() override {} @@ -38,8 +46,16 @@ MediaControlsTouchlessElement(MediaControlsTouchlessImpl& media_controls); private: + void EnsureHideControlTimer(); + void HideControlTimerFired(TimerBase*); + void StartHideControlTimer(); + void StopHideControlTimer(); + Member<MediaControlsTouchlessImpl> media_controls_; + std::unique_ptr<TaskRunnerTimer<MediaControlsTouchlessElement>> + hide_control_timer_; + DISALLOW_COPY_AND_ASSIGN(MediaControlsTouchlessElement); };
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.cc b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.cc index 2df28ce..5e008b0 100644 --- a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.cc +++ b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.cc
@@ -13,8 +13,7 @@ MediaControlsTouchlessOverlayElement::MediaControlsTouchlessOverlayElement( MediaControlsTouchlessImpl& media_controls) - : HTMLDivElement(media_controls.GetDocument()), - MediaControlsTouchlessElement(media_controls) { + : MediaControlsTouchlessElement(media_controls) { SetShadowPseudoId(AtomicString("-internal-media-controls-touchless-overlay")); MediaControlsTouchlessPlayButtonElement* play_button = @@ -43,7 +42,6 @@ } void MediaControlsTouchlessOverlayElement::Trace(blink::Visitor* visitor) { - HTMLDivElement::Trace(visitor); MediaControlsTouchlessElement::Trace(visitor); }
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.h b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.h index fe91774..6c38453 100644 --- a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.h +++ b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.h
@@ -13,10 +13,7 @@ class MediaControlsTouchlessImpl; class MediaControlsTouchlessOverlayElement - : public HTMLDivElement, - public MediaControlsTouchlessElement { - USING_GARBAGE_COLLECTED_MIXIN(MediaControlsTouchlessOverlayElement); - + : public MediaControlsTouchlessElement { public: MediaControlsTouchlessOverlayElement(MediaControlsTouchlessImpl&); void Trace(blink::Visitor*) override;
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_play_button_element.cc b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_play_button_element.cc index 5b81cf52..ed97243 100644 --- a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_play_button_element.cc +++ b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_play_button_element.cc
@@ -20,8 +20,7 @@ MediaControlsTouchlessPlayButtonElement:: MediaControlsTouchlessPlayButtonElement( MediaControlsTouchlessImpl& controls) - : HTMLDivElement(controls.GetDocument()), - MediaControlsTouchlessElement(controls) { + : MediaControlsTouchlessElement(controls) { SetShadowPseudoId( AtomicString("-internal-media-controls-touchless-play-button")); @@ -37,7 +36,6 @@ } void MediaControlsTouchlessPlayButtonElement::Trace(blink::Visitor* visitor) { - HTMLDivElement::Trace(visitor); MediaControlsTouchlessElement::Trace(visitor); }
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_play_button_element.h b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_play_button_element.h index 0c5635f87..46eb44f 100644 --- a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_play_button_element.h +++ b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_play_button_element.h
@@ -11,10 +11,7 @@ namespace blink { class MediaControlsTouchlessPlayButtonElement - : public HTMLDivElement, - public MediaControlsTouchlessElement { - USING_GARBAGE_COLLECTED_MIXIN(MediaControlsTouchlessPlayButtonElement); - + : public MediaControlsTouchlessElement { public: MediaControlsTouchlessPlayButtonElement(MediaControlsTouchlessImpl&);
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_seek_button_element.cc b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_seek_button_element.cc index 11791779..4d778eb 100644 --- a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_seek_button_element.cc +++ b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_seek_button_element.cc
@@ -12,15 +12,13 @@ MediaControlsTouchlessSeekButtonElement( MediaControlsTouchlessImpl& controls, bool forward) - : HTMLDivElement(controls.GetDocument()), - MediaControlsTouchlessElement(controls) { + : MediaControlsTouchlessElement(controls) { SetShadowPseudoId(AtomicString( forward ? "-internal-media-controls-touchless-seek-forward-button" : "-internal-media-controls-touchless-seek-backward-button")); } void MediaControlsTouchlessSeekButtonElement::Trace(blink::Visitor* visitor) { - HTMLDivElement::Trace(visitor); MediaControlsTouchlessElement::Trace(visitor); }
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_seek_button_element.h b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_seek_button_element.h index e2065e8..fa0acbf3 100644 --- a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_seek_button_element.h +++ b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_seek_button_element.h
@@ -11,10 +11,7 @@ namespace blink { class MediaControlsTouchlessSeekButtonElement - : public HTMLDivElement, - public MediaControlsTouchlessElement { - USING_GARBAGE_COLLECTED_MIXIN(MediaControlsTouchlessSeekButtonElement); - + : public MediaControlsTouchlessElement { public: MediaControlsTouchlessSeekButtonElement( MediaControlsTouchlessImpl&,
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.cc b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.cc index 154d6ad..261f52b 100644 --- a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.cc +++ b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.cc
@@ -14,8 +14,7 @@ MediaControlsTouchlessTimeDisplayElement:: MediaControlsTouchlessTimeDisplayElement( MediaControlsTouchlessImpl& media_controls) - : HTMLDivElement(media_controls.GetDocument()), - MediaControlsTouchlessElement(media_controls), + : MediaControlsTouchlessElement(media_controls), current_time_(0.0), duration_(0.0) { SetShadowPseudoId( @@ -34,7 +33,6 @@ } void MediaControlsTouchlessTimeDisplayElement::Trace(blink::Visitor* visitor) { - HTMLDivElement::Trace(visitor); MediaControlsTouchlessElement::Trace(visitor); }
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h index d0eb117..6a8455a 100644 --- a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h +++ b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h
@@ -11,10 +11,7 @@ namespace blink { class MediaControlsTouchlessTimeDisplayElement - : public HTMLDivElement, - public MediaControlsTouchlessElement { - USING_GARBAGE_COLLECTED_MIXIN(MediaControlsTouchlessTimeDisplayElement); - + : public MediaControlsTouchlessElement { public: explicit MediaControlsTouchlessTimeDisplayElement( MediaControlsTouchlessImpl&);
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.cc b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.cc index e06998a..57bd4a63 100644 --- a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.cc +++ b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.cc
@@ -15,8 +15,7 @@ MediaControlsTouchlessTimelineElement::MediaControlsTouchlessTimelineElement( MediaControlsTouchlessImpl& media_controls) - : HTMLDivElement(media_controls.GetDocument()), - MediaControlsTouchlessElement(media_controls) { + : MediaControlsTouchlessElement(media_controls) { SetShadowPseudoId( AtomicString("-internal-media-controls-touchless-timeline")); @@ -88,7 +87,6 @@ void MediaControlsTouchlessTimelineElement::Trace(blink::Visitor* visitor) { visitor->Trace(loaded_bar_); visitor->Trace(progress_bar_); - HTMLDivElement::Trace(visitor); MediaControlsTouchlessElement::Trace(visitor); }
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h index 0050fcf..b1416ce9 100644 --- a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h +++ b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h
@@ -11,10 +11,7 @@ namespace blink { class MediaControlsTouchlessTimelineElement - : public HTMLDivElement, - public MediaControlsTouchlessElement { - USING_GARBAGE_COLLECTED_MIXIN(MediaControlsTouchlessTimelineElement); - + : public MediaControlsTouchlessElement { public: explicit MediaControlsTouchlessTimelineElement(MediaControlsTouchlessImpl&);
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_button_element.cc b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_button_element.cc index a0aa379..b8c660b 100644 --- a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_button_element.cc +++ b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_button_element.cc
@@ -12,15 +12,13 @@ MediaControlsTouchlessVolumeButtonElement( MediaControlsTouchlessImpl& controls, bool up) - : HTMLDivElement(controls.GetDocument()), - MediaControlsTouchlessElement(controls) { + : MediaControlsTouchlessElement(controls) { SetShadowPseudoId(AtomicString( up ? "-internal-media-controls-touchless-volume-up-button" : "-internal-media-controls-touchless-volume-down-button")); } void MediaControlsTouchlessVolumeButtonElement::Trace(blink::Visitor* visitor) { - HTMLDivElement::Trace(visitor); MediaControlsTouchlessElement::Trace(visitor); }
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_button_element.h b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_button_element.h index b272cead..ad7ae783 100644 --- a/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_button_element.h +++ b/third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_volume_button_element.h
@@ -11,10 +11,7 @@ namespace blink { class MediaControlsTouchlessVolumeButtonElement - : public HTMLDivElement, - public MediaControlsTouchlessElement { - USING_GARBAGE_COLLECTED_MIXIN(MediaControlsTouchlessVolumeButtonElement); - + : public MediaControlsTouchlessElement { public: MediaControlsTouchlessVolumeButtonElement( MediaControlsTouchlessImpl&,
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.cc b/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.cc index a010853d6..2877c78e 100644 --- a/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.cc +++ b/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.cc
@@ -22,9 +22,8 @@ #include "third_party/blink/renderer/modules/media_controls/elements/media_control_elements_helper.h" #include "third_party/blink/renderer/modules/media_controls/media_controls_orientation_lock_delegate.h" #include "third_party/blink/renderer/modules/media_controls/media_controls_text_track_manager.h" +#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_bottom_container_element.h" #include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_overlay_element.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_time_display_element.h" -#include "third_party/blink/renderer/modules/media_controls/touchless/elements/media_controls_touchless_timeline_element.h" #include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener.h" #include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_resource_loader.h" #include "third_party/blink/renderer/platform/keyboard_codes.h" @@ -43,12 +42,6 @@ // Amount of volume to change when press up/down arrow. constexpr double kVolumeToChangeForTouchless = 0.05; -// Amount of time that media controls are visible. -constexpr WTF::TimeDelta kTimeToHideMediaControls = - TimeDelta::FromMilliseconds(3000); - -const char kTransparentCSSClass[] = "transparent"; - } // namespace enum class MediaControlsTouchlessImpl::ArrowDirection { @@ -62,16 +55,14 @@ HTMLMediaElement& media_element) : HTMLDivElement(media_element.GetDocument()), MediaControls(media_element), + overlay_(nullptr), + bottom_container_(nullptr), media_event_listener_( MakeGarbageCollected<MediaControlsTouchlessMediaEventListener>( media_element)), text_track_manager_( MakeGarbageCollected<MediaControlsTextTrackManager>(media_element)), - orientation_lock_delegate_(nullptr), - hide_media_controls_timer_( - media_element.GetDocument().GetTaskRunner(TaskType::kInternalMedia), - this, - &MediaControlsTouchlessImpl::HideMediaControlsTimerFired) { + orientation_lock_delegate_(nullptr) { SetShadowPseudoId(AtomicString("-internal-media-controls-touchless")); media_event_listener_->AddObserver(this); } @@ -81,23 +72,19 @@ ShadowRoot& shadow_root) { MediaControlsTouchlessImpl* controls = MakeGarbageCollected<MediaControlsTouchlessImpl>(media_element); - MediaControlsTouchlessOverlayElement* overlay_element = + controls->overlay_ = MakeGarbageCollected<MediaControlsTouchlessOverlayElement>(*controls); + controls->bottom_container_ = + MakeGarbageCollected<MediaControlsTouchlessBottomContainerElement>( + *controls); - MediaControlsTouchlessTimeDisplayElement* time_display_element = - MakeGarbageCollected<MediaControlsTouchlessTimeDisplayElement>(*controls); - MediaControlsTouchlessTimelineElement* timeline_element = - MakeGarbageCollected<MediaControlsTouchlessTimelineElement>(*controls); - - controls->ParserAppendChild(overlay_element); - - Element* bottom_container = MediaControlElementsHelper::CreateDiv( - "-internal-media-controls-touchless-bottom-container", controls); - bottom_container->ParserAppendChild(time_display_element); - bottom_container->ParserAppendChild(timeline_element); + controls->ParserAppendChild(controls->overlay_); + controls->ParserAppendChild(controls->bottom_container_); // Controls start hidden. - controls->MakeTransparent(); + controls->overlay_->MakeTransparent(); + if (!media_element.paused()) + controls->bottom_container_->MakeTransparent(); if (RuntimeEnabledFeatures::VideoFullscreenOrientationLockEnabled() && media_element.IsHTMLVideoElement()) { @@ -135,20 +122,6 @@ orientation_lock_delegate_->Detach(); } -void MediaControlsTouchlessImpl::MakeOpaque() { - // show controls - classList().Remove(kTransparentCSSClass); - - if (hide_media_controls_timer_.IsActive()) - StopHideMediaControlsTimer(); - StartHideMediaControlsTimer(); -} - -void MediaControlsTouchlessImpl::MakeTransparent() { - // hide controls - classList().Add(kTransparentCSSClass); -} - void MediaControlsTouchlessImpl::MaybeShow() { RemoveInlineStyleProperty(CSSPropertyID::kDisplay); } @@ -162,28 +135,26 @@ return *media_event_listener_; } -void MediaControlsTouchlessImpl::HideMediaControlsTimerFired(TimerBase*) { - MakeTransparent(); -} - -void MediaControlsTouchlessImpl::StartHideMediaControlsTimer() { - hide_media_controls_timer_.StartOneShot(kTimeToHideMediaControls, FROM_HERE); -} - -void MediaControlsTouchlessImpl::StopHideMediaControlsTimer() { - hide_media_controls_timer_.Stop(); -} - void MediaControlsTouchlessImpl::OnFocusIn() { - if (MediaElement().ShouldShowControls()) - MakeOpaque(); + if (MediaElement().ShouldShowControls()) { + overlay_->MakeOpaque(true); + bottom_container_->MakeOpaque(!MediaElement().paused()); + } +} + +void MediaControlsTouchlessImpl::OnPlay() { + bottom_container_->MakeOpaque(true); +} + +void MediaControlsTouchlessImpl::OnPause() { + bottom_container_->MakeOpaque(false); } void MediaControlsTouchlessImpl::OnKeyDown(KeyboardEvent* event) { bool handled = true; switch (event->keyCode()) { case VKEY_RETURN: - MakeOpaque(); + overlay_->MakeOpaque(true); MediaElement().TogglePlayState(); break; case VKEY_LEFT: @@ -364,10 +335,14 @@ } void MediaControlsTouchlessImpl::HandleLeftButtonPress() { + if (!MediaElement().paused()) + bottom_container_->MakeOpaque(true); MaybeJump(kNumberOfSecondsToJumpForTouchless * -1); } void MediaControlsTouchlessImpl::HandleRightButtonPress() { + if (!MediaElement().paused()) + bottom_container_->MakeOpaque(true); MaybeJump(kNumberOfSecondsToJumpForTouchless); } @@ -384,6 +359,8 @@ } void MediaControlsTouchlessImpl::Trace(blink::Visitor* visitor) { + visitor->Trace(bottom_container_); + visitor->Trace(overlay_); visitor->Trace(media_event_listener_); visitor->Trace(text_track_manager_); visitor->Trace(orientation_lock_delegate_);
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h b/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h index bcb6d391..b765727 100644 --- a/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h +++ b/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl.h
@@ -11,11 +11,12 @@ #include "third_party/blink/renderer/core/html/media/media_controls.h" #include "third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_media_event_listener_observer.h" #include "third_party/blink/renderer/modules/modules_export.h" -#include "third_party/blink/renderer/platform/timer.h" namespace blink { class MediaControlsOrientationLockDelegate; +class MediaControlsTouchlessBottomContainerElement; +class MediaControlsTouchlessOverlayElement; class MediaControlsTouchlessMediaEventListener; class MediaControlsTextTrackManager; @@ -54,8 +55,8 @@ void OnTimeUpdate() override {} void OnDurationChange() override {} void OnLoadingProgress() override {} - void OnPlay() override {} - void OnPause() override {} + void OnPlay() override; + void OnPause() override; void OnError() override {} void OnLoadedMetadata() override {} void OnKeyPress(KeyboardEvent* event) override {} @@ -86,12 +87,6 @@ // Node bool IsMediaControls() const override { return true; } - void MakeOpaque(); - void MakeTransparent(); - void HideMediaControlsTimerFired(TimerBase*); - void StartHideMediaControlsTimer(); - void StopHideMediaControlsTimer(); - void EnsureMediaControlsMenuHost(); mojom::blink::VideoStatePtr GetVideoState(); WTF::Vector<mojom::blink::TextTrackMetadataPtr> GetTextTracks(); @@ -99,12 +94,13 @@ void OnMediaMenuResult(mojom::blink::MenuResponsePtr); void OnMediaControlsMenuHostConnectionError(); + Member<MediaControlsTouchlessOverlayElement> overlay_; + Member<MediaControlsTouchlessBottomContainerElement> bottom_container_; + Member<MediaControlsTouchlessMediaEventListener> media_event_listener_; Member<MediaControlsTextTrackManager> text_track_manager_; Member<MediaControlsOrientationLockDelegate> orientation_lock_delegate_; - TaskRunnerTimer<MediaControlsTouchlessImpl> hide_media_controls_timer_; - mojom::blink::MediaControlsMenuHostPtr media_controls_host_; DISALLOW_COPY_AND_ASSIGN(MediaControlsTouchlessImpl);
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl_test.cc b/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl_test.cc index e6a9727..813135c 100644 --- a/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl_test.cc +++ b/third_party/blink/renderer/modules/media_controls/touchless/media_controls_touchless_impl_test.cc
@@ -108,8 +108,8 @@ WebMediaPlayer()->buffered_.Assign(&time_range, 1); } - bool IsControlsVisible() { - return !MediaControls().classList().contains("transparent"); + bool IsControlsVisible(Element* element) { + return !element->classList().contains("transparent"); } Element* GetControlByShadowPseudoId(const char* shadow_pseudo_id) { @@ -293,37 +293,85 @@ EXPECT_EQ(time_display->InnerHTMLAsString(), expect_display); } -TEST_F(MediaControlsTouchlessImplTestWithMockScheduler, ControlsShowAndHide) { - // Controls should starts hidden. - ASSERT_FALSE(IsControlsVisible()); +TEST_F(MediaControlsTouchlessImplTestWithMockScheduler, + MidOverlayHideTimerTest) { + Element* overlay = + GetControlByShadowPseudoId("-internal-media-controls-touchless-overlay"); + ASSERT_NE(nullptr, overlay); - // Controls should show when focus in. + // Overlay should starts hidden. + EXPECT_FALSE(IsControlsVisible(overlay)); + + // Overlay should show when focus in. MediaElement().SetFocused(true, WebFocusType::kWebFocusTypeNone); MediaElement().DispatchEvent(*Event::Create(event_type_names::kFocusin)); - ASSERT_TRUE(IsControlsVisible()); + EXPECT_TRUE(IsControlsVisible(overlay)); - // Controls should hide after 3 seconds. + // Overlay should hide after 3 seconds. platform()->RunForPeriodSeconds(2.99); - ASSERT_TRUE(IsControlsVisible()); + EXPECT_TRUE(IsControlsVisible(overlay)); platform()->RunForPeriodSeconds(0.01); - ASSERT_FALSE(IsControlsVisible()); + EXPECT_FALSE(IsControlsVisible(overlay)); - // Controls should show upon pressing return key. + // Overlay should show upon pressing return key. SimulateKeydownEvent(MediaElement(), VKEY_RETURN); - ASSERT_TRUE(IsControlsVisible()); + EXPECT_TRUE(IsControlsVisible(overlay)); - // Controls should not disappear after 2 seconds. + // Overlay should not disappear after 2 seconds. platform()->RunForPeriodSeconds(2); - ASSERT_TRUE(IsControlsVisible()); + EXPECT_TRUE(IsControlsVisible(overlay)); - // Pressing return key again should reset hiding timer. - SimulateKeydownEvent(MediaElement(), VKEY_RETURN); - platform()->RunForPeriodSeconds(2); - ASSERT_TRUE(IsControlsVisible()); - - // Controls should hide 3 seconds after last key press. + // Overlay should hide 3 seconds after last key press. platform()->RunForPeriodSeconds(1); - ASSERT_FALSE(IsControlsVisible()); + EXPECT_FALSE(IsControlsVisible(overlay)); +} + +TEST_F(MediaControlsTouchlessImplTestWithMockScheduler, + BottomContainerHideTimerTest) { + Element* bottom_container = GetControlByShadowPseudoId( + "-internal-media-controls-touchless-bottom-container"); + ASSERT_NE(nullptr, bottom_container); + + // Bottom container starts opaque since video is paused. + EXPECT_TRUE(IsControlsVisible(bottom_container)); + + MediaElement().Play(); + platform()->RunForPeriodSeconds(3); + EXPECT_FALSE(IsControlsVisible(bottom_container)); + + MediaElement().pause(); + + // Pause after play should stop hide timer. + MediaElement().Play(); + MediaElement().pause(); + platform()->RunForPeriodSeconds(5); + EXPECT_TRUE(IsControlsVisible(bottom_container)); + + MediaElement().Play(); + platform()->RunForPeriodSeconds(5); + EXPECT_FALSE(IsControlsVisible(bottom_container)); + + // Bottom container should show after focus in. + MediaElement().SetFocused(true, WebFocusType::kWebFocusTypeNone); + MediaElement().DispatchEvent(*Event::Create(event_type_names::kFocusin)); + EXPECT_TRUE(IsControlsVisible(bottom_container)); + + // Hide after 3 seconds + platform()->RunForPeriodSeconds(3); + EXPECT_FALSE(IsControlsVisible(bottom_container)); + + // Bottom container should show after pressing right/left arrow. + SimulateKeydownEvent(MediaElement(), VK_RIGHT); + EXPECT_TRUE(IsControlsVisible(bottom_container)); + + platform()->RunForPeriodSeconds(3); + EXPECT_FALSE(IsControlsVisible(bottom_container)); + + SimulateKeydownEvent(MediaElement(), VK_LEFT); + EXPECT_TRUE(IsControlsVisible(bottom_container)); + + platform()->RunForPeriodSeconds(3); + EXPECT_FALSE(IsControlsVisible(bottom_container)); } } // namespace
diff --git a/third_party/blink/renderer/modules/media_controls/touchless/resources/mediaControlsTouchless.css b/third_party/blink/renderer/modules/media_controls/touchless/resources/mediaControlsTouchless.css index 3a4ddb0..439a6fe 100644 --- a/third_party/blink/renderer/modules/media_controls/touchless/resources/mediaControlsTouchless.css +++ b/third_party/blink/renderer/modules/media_controls/touchless/resources/mediaControlsTouchless.css
@@ -18,11 +18,6 @@ margin-bottom: env(safe-area-inset-bottom); } -video::-internal-media-controls-touchless.transparent { - opacity: 0; - transition: opacity .5s; -} - video::-internal-media-controls-touchless-overlay { width: 104px; height: 104px; @@ -31,6 +26,7 @@ background-position: center; background-repeat: no-repeat; position: absolute; + opacity: 1; z-index: 1; margin: auto; top: 0; @@ -39,6 +35,11 @@ right: 0; } +video::-internal-media-controls-touchless-overlay.transparent { + opacity: 0; + transition: opacity .5s; +} + video::-internal-media-controls-touchless-volume-up-button { width: 30px; height: 30px; @@ -110,11 +111,16 @@ height: 100%; width: 100%; z-index: 0; - background-size: auto 48px; background: -webkit-image-set(url('gradient_bg.png') 1x) repeat-x bottom left; + background-size: auto 48px; +} + +video::-internal-media-controls-touchless-bottom-container.transparent { + opacity: 0; + transition: opacity .5s; } video::-internal-media-controls-touchless-time-display {
diff --git a/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc b/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc index f79b511..0e1b4cf 100644 --- a/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc +++ b/third_party/blink/renderer/modules/mediastream/media_constraints_impl.cc
@@ -665,11 +665,6 @@ CopyBooleanConstraint(constraints_in->echoCancellation(), naked_treatment, constraint_buffer.echo_cancellation); } - if (constraints_in->hasEchoCancellationType()) { - CopyStringConstraint(constraints_in->echoCancellationType(), - naked_treatment, - constraint_buffer.echo_cancellation_type); - } if (constraints_in->hasAutoGainControl()) { CopyBooleanConstraint(constraints_in->autoGainControl(), naked_treatment, constraint_buffer.goog_auto_gain_control);
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_track.cc b/third_party/blink/renderer/modules/mediastream/media_stream_track.cc index 2452dd60..10ad386 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_track.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_track.cc
@@ -347,7 +347,6 @@ Vector<String> echo_cancellation_type; for (String value : platform_capabilities.echo_cancellation_type) echo_cancellation_type.push_back(value); - capabilities->setEchoCancellationType(echo_cancellation_type); // Sample size. if (platform_capabilities.sample_size.size() == 2) { LongRange* sample_size = LongRange::Create(); @@ -509,11 +508,6 @@ settings->setAutoGainControl(*platform_settings.auto_gain_control); if (platform_settings.noise_supression) settings->setNoiseSuppression(*platform_settings.noise_supression); - if (RuntimeEnabledFeatures::ExperimentalHardwareEchoCancellationEnabled( - GetExecutionContext()) && - !platform_settings.echo_cancellation_type.IsNull()) { - settings->setEchoCancellationType(platform_settings.echo_cancellation_type); - } if (platform_settings.HasSampleRate()) settings->setSampleRate(platform_settings.sample_rate);
diff --git a/third_party/blink/renderer/modules/mediastream/media_track_capabilities.idl b/third_party/blink/renderer/modules/mediastream/media_track_capabilities.idl index 55d1fa4..b4a3fc26 100644 --- a/third_party/blink/renderer/modules/mediastream/media_track_capabilities.idl +++ b/third_party/blink/renderer/modules/mediastream/media_track_capabilities.idl
@@ -10,8 +10,6 @@ sequence<DOMString> facingMode; sequence<DOMString> resizeMode; sequence<boolean> echoCancellation; - // See http://crbug.com/846270. - [RuntimeEnabled=ExperimentalHardwareEchoCancellation] sequence<DOMString> echoCancellationType; sequence<boolean> autoGainControl; sequence<boolean> noiseSuppression; LongRange sampleSize;
diff --git a/third_party/blink/renderer/modules/mediastream/media_track_constraint_set.idl b/third_party/blink/renderer/modules/mediastream/media_track_constraint_set.idl index e09bbe3d..899eee12 100644 --- a/third_party/blink/renderer/modules/mediastream/media_track_constraint_set.idl +++ b/third_party/blink/renderer/modules/mediastream/media_track_constraint_set.idl
@@ -21,8 +21,6 @@ ConstrainLong sampleRate; ConstrainLong sampleSize; ConstrainBoolean echoCancellation; - // See http://crbug.com/846270. - [RuntimeEnabled=ExperimentalHardwareEchoCancellation] ConstrainDOMString echoCancellationType; ConstrainBoolean autoGainControl; ConstrainBoolean noiseSuppression; ConstrainDouble latency;
diff --git a/third_party/blink/renderer/modules/mediastream/media_track_settings.idl b/third_party/blink/renderer/modules/mediastream/media_track_settings.idl index 774e38f..3a08dbc 100644 --- a/third_party/blink/renderer/modules/mediastream/media_track_settings.idl +++ b/third_party/blink/renderer/modules/mediastream/media_track_settings.idl
@@ -21,7 +21,6 @@ long channelCount; DOMString deviceId; DOMString groupId; - [RuntimeEnabled=ExperimentalHardwareEchoCancellation] DOMString echoCancellationType; // Media Capture Depth Stream Extensions // https://w3c.github.io/mediacapture-depth/#mediatracksettings-dictionary // TODO(riju): videoKind attribute should be declared as partial
diff --git a/third_party/blink/renderer/modules/mediastream/media_track_supported_constraints.idl b/third_party/blink/renderer/modules/mediastream/media_track_supported_constraints.idl index 5651fd5..cb7da5a9 100644 --- a/third_party/blink/renderer/modules/mediastream/media_track_supported_constraints.idl +++ b/third_party/blink/renderer/modules/mediastream/media_track_supported_constraints.idl
@@ -18,8 +18,6 @@ boolean sampleRate = true; boolean sampleSize = true; boolean echoCancellation = true; - // See http://crbug.com/846270. - [RuntimeEnabled=ExperimentalHardwareEchoCancellation] boolean echoCancellationType = true; boolean autoGainControl = true; boolean noiseSuppression = true; boolean latency = true;
diff --git a/third_party/blink/renderer/modules/mediastream/user_media_request.cc b/third_party/blink/renderer/modules/mediastream/user_media_request.cc index 6ee8b14b..dd9d090 100644 --- a/third_party/blink/renderer/modules/mediastream/user_media_request.cc +++ b/third_party/blink/renderer/modules/mediastream/user_media_request.cc
@@ -444,12 +444,6 @@ UseCounter::Count(context, WebFeature::kUserMediaDisableHardwareNoiseSuppression); } - if (RuntimeEnabledFeatures::ExperimentalHardwareEchoCancellationEnabled( - context)) { - UseCounter::Count( - context, - WebFeature::kUserMediaEnableExperimentalHardwareEchoCancellation); - } } UserMediaRequest::~UserMediaRequest() = default;
diff --git a/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc b/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc index 80ea675..e317e4d 100644 --- a/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc +++ b/third_party/blink/renderer/modules/peerconnection/adapters/ice_transport_proxy.cc
@@ -25,7 +25,7 @@ feature_handle_for_scheduler_(frame.GetFrameScheduler()->RegisterFeature( SchedulingPolicy::Feature::kWebRTC, {SchedulingPolicy::DisableAggressiveThrottling(), - SchedulingPolicy::DisableBackForwardCache()})), + SchedulingPolicy::RecordMetricsForBackForwardCache()})), weak_ptr_factory_(this) { DCHECK(host_thread_); DCHECK(delegate_);
diff --git a/third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_host.cc b/third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_host.cc index 70debe1..6bafeb04 100644 --- a/third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_host.cc +++ b/third_party/blink/renderer/modules/peerconnection/adapters/quic_stream_host.cc
@@ -58,7 +58,7 @@ void QuicStreamHost::WriteData(Vector<uint8_t> data, bool fin) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); DCHECK(p2p_stream_); - p2p_stream_->WriteData(data, fin); + p2p_stream_->WriteData(std::move(data), fin); if (fin) { DCHECK(writable_); writable_ = false;
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc index 590c14d4..0b499ed4 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -762,7 +762,7 @@ document->GetFrame()->GetFrameScheduler()->RegisterFeature( SchedulingPolicy::Feature::kWebRTC, {SchedulingPolicy::DisableAggressiveThrottling(), - SchedulingPolicy::DisableBackForwardCache()}); + SchedulingPolicy::RecordMetricsForBackForwardCache()}); } RTCPeerConnection::~RTCPeerConnection() {
diff --git a/third_party/blink/renderer/modules/webaudio/audio_context_test.cc b/third_party/blink/renderer/modules/webaudio/audio_context_test.cc index b867671a..d2ce4bd9 100644 --- a/third_party/blink/renderer/modules/webaudio/audio_context_test.cc +++ b/third_party/blink/renderer/modules/webaudio/audio_context_test.cc
@@ -9,6 +9,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/platform/web_audio_device.h" #include "third_party/blink/public/platform/web_audio_latency_hint.h" +#include "third_party/blink/renderer/core/core_initializer.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/testing/page_test_base.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h" @@ -88,7 +89,10 @@ ~AudioContextTest() override { platform_.reset(); } - void SetUp() override { PageTestBase::SetUp(IntSize()); } + void SetUp() override { + PageTestBase::SetUp(IntSize()); + CoreInitializer::GetInstance().ProvideModulesToPage(GetPage(), nullptr); + } mojom::blink::AudioContextManagerPtr& GetAudioContextManagerPtrFor( AudioContext* audio_context) {
diff --git a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc index 8dbf1c0a..af89931 100644 --- a/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc +++ b/third_party/blink/renderer/modules/websockets/websocket_channel_impl.cc
@@ -223,7 +223,7 @@ feature_handle_for_scheduler_ = scheduler->RegisterFeature( SchedulingPolicy::Feature::kWebSocket, {SchedulingPolicy::DisableAggressiveThrottling(), - SchedulingPolicy::DisableBackForwardCache()}); + SchedulingPolicy::RecordMetricsForBackForwardCache()}); } if (MixedContentChecker::IsMixedContent(
diff --git a/third_party/blink/renderer/platform/exported/web_url_request.cc b/third_party/blink/renderer/platform/exported/web_url_request.cc index dc464e6..7ab5481ff 100644 --- a/third_party/blink/renderer/platform/exported/web_url_request.cc +++ b/third_party/blink/renderer/platform/exported/web_url_request.cc
@@ -421,6 +421,10 @@ resource_request_->SetRequestedWithHeader(value); } +const WebString WebURLRequest::GetPurposeHeader() const { + return resource_request_->GetPurposeHeader(); +} + const base::UnguessableToken& WebURLRequest::GetFetchWindowId() const { return resource_request_->GetFetchWindowId(); }
diff --git a/third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.cc b/third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.cc index 46294765..8876a88 100644 --- a/third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.cc +++ b/third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.cc
@@ -65,10 +65,4 @@ service_->SetMainThreadTaskLoadIsLow(main_thread_task_load_is_low); } -void RendererResourceCoordinator::OnRendererIsBloated() { - if (!service_) - return; - service_->OnRendererIsBloated(); -} - } // namespace blink
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc index 810e9c1..0afe90ea 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -809,7 +809,7 @@ DetermineRequestContext(resource_type, kImageNotImageSet)); } if (resource_type == ResourceType::kLinkPrefetch) - resource_request.SetHttpHeaderField(http_names::kPurpose, "prefetch"); + resource_request.SetPurposeHeader("prefetch"); // Indicate whether the network stack can return a stale resource. If a // stale resource is returned a StaleRevalidation request will be scheduled.
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc index d0061eea..aa60491 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_loader.cc
@@ -1028,12 +1028,12 @@ if (response.CacheControlContainsNoCache()) { frame_scheduler->RegisterStickyFeature( SchedulingPolicy::Feature::kSubresourceHasCacheControlNoCache, - {SchedulingPolicy::DisableBackForwardCache()}); + {SchedulingPolicy::RecordMetricsForBackForwardCache()}); } if (response.CacheControlContainsNoStore()) { frame_scheduler->RegisterStickyFeature( SchedulingPolicy::Feature::kSubresourceHasCacheControlNoStore, - {SchedulingPolicy::DisableBackForwardCache()}); + {SchedulingPolicy::RecordMetricsForBackForwardCache()}); } }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc index 594821fb..4926c03 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_request.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.cc
@@ -127,6 +127,7 @@ request->SetIsAutomaticUpgrade(IsAutomaticUpgrade()); request->SetRequestedWithHeader(GetRequestedWithHeader()); request->SetClientDataHeader(GetClientDataHeader()); + request->SetPurposeHeader(GetPurposeHeader()); request->SetUkmSourceId(GetUkmSourceId()); request->SetInspectorId(InspectorId());
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_request.h b/third_party/blink/renderer/platform/loader/fetch/resource_request.h index e7599bf..55f7bd2 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource_request.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource_request.h
@@ -402,6 +402,9 @@ void SetClientDataHeader(const String& value) { client_data_header_ = value; } const String& GetClientDataHeader() const { return client_data_header_; } + void SetPurposeHeader(const String& value) { purpose_header_ = value; } + const String& GetPurposeHeader() const { return purpose_header_; } + void SetUkmSourceId(ukm::SourceId ukm_source_id) { ukm_source_id_ = ukm_source_id; } @@ -492,6 +495,7 @@ base::Optional<String> devtools_id_; String requested_with_header_; String client_data_header_; + String purpose_header_; ukm::SourceId ukm_source_id_ = ukm::kInvalidSourceId;
diff --git a/third_party/blink/renderer/platform/network/http_names.json5 b/third_party/blink/renderer/platform/network/http_names.json5 index 27db4b1d3..248c5e8 100644 --- a/third_party/blink/renderer/platform/network/http_names.json5 +++ b/third_party/blink/renderer/platform/network/http_names.json5
@@ -50,7 +50,6 @@ "Ping-From", "Ping-To", "Pragma", - "Purpose", "Range", // TODO(domfarolino): Remove "Referer" as part of https://crbug.com/850813. "Referer",
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index c4ddfad3..598c66f5 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -494,11 +494,6 @@ name: "ExperimentalContentSecurityPolicyFeatures", status: "experimental", }, - { - name: "ExperimentalHardwareEchoCancellation", - origin_trial_feature_name: "ExperimentalHardwareEchoCancellation2", - status: "experimental", - }, // Enables navigator.scheduling.isInputPending, allowing long-running JS to // be able to yield itself when user input is queued (crbug.com/910421). {
diff --git a/third_party/blink/renderer/platform/scheduler/common/frame_or_worker_scheduler.cc b/third_party/blink/renderer/platform/scheduler/common/frame_or_worker_scheduler.cc index a23ec4f3..f2c6488 100644 --- a/third_party/blink/renderer/platform/scheduler/common/frame_or_worker_scheduler.cc +++ b/third_party/blink/renderer/platform/scheduler/common/frame_or_worker_scheduler.cc
@@ -22,7 +22,8 @@ SchedulingPolicy policy, base::WeakPtr<FrameOrWorkerScheduler> scheduler) : feature_(feature), policy_(policy), scheduler_(std::move(scheduler)) { - DCHECK(scheduler_); + if (!scheduler_) + return; scheduler_->OnStartedUsingFeature(feature_, policy_); } @@ -52,7 +53,11 @@ FrameOrWorkerScheduler::RegisterFeature(SchedulingPolicy::Feature feature, SchedulingPolicy policy) { DCHECK(!SchedulingPolicy::IsFeatureSticky(feature)); - return SchedulingAffectingFeatureHandle(feature, policy, GetWeakPtr()); + // We reset feature sets upon frame navigation, so having a document-bound + // weak pointer ensures that the feature handle associated with previous + // document can't influence the new one. + return SchedulingAffectingFeatureHandle(feature, policy, + GetDocumentBoundWeakPtr()); } void FrameOrWorkerScheduler::RegisterStickyFeature( @@ -85,6 +90,11 @@ } } +base::WeakPtr<FrameOrWorkerScheduler> +FrameOrWorkerScheduler::GetDocumentBoundWeakPtr() { + return nullptr; +} + base::WeakPtr<FrameOrWorkerScheduler> FrameOrWorkerScheduler::GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc index 1bc4a7d..96b3fb1 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -219,6 +219,7 @@ this, &tracing_controller_, KeepActiveStateToString), + document_bound_weak_factory_(this), weak_factory_(this) { frame_task_queue_controller_.reset( new FrameTaskQueueController(main_thread_scheduler_, this, this)); @@ -622,55 +623,65 @@ } void FrameSchedulerImpl::ResetForNavigation() { - // Reset "sticky" features when the frame navigates. - for (auto it = back_forward_cache_opt_out_counts_.begin(); - it != back_forward_cache_opt_out_counts_.end();) { - if (SchedulingPolicy::IsFeatureSticky(it->first)) { - it = back_forward_cache_opt_out_counts_.erase(it); - } else { - ++it; - } - } - opted_out_from_back_forward_cache_ = - !back_forward_cache_opt_out_counts_.empty(); + document_bound_weak_factory_.InvalidateWeakPtrs(); + + back_forward_cache_opt_out_counts_.clear(); + back_forward_cache_opt_outs_.reset(); + last_uploaded_active_features_ = 0; } void FrameSchedulerImpl::OnStartedUsingFeature( SchedulingPolicy::Feature feature, const SchedulingPolicy& policy) { - uint64_t old_mask = GetActiveFeaturesOptingOutFromBackForwardCacheMask(); + uint64_t old_mask = GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(); if (policy.disable_aggressive_throttling) OnAddedAggressiveThrottlingOptOut(); if (policy.disable_back_forward_cache) OnAddedBackForwardCacheOptOut(feature); - uint64_t new_mask = GetActiveFeaturesOptingOutFromBackForwardCacheMask(); + uint64_t new_mask = GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(); - if (old_mask != new_mask && delegate_ && - GetFrameType() == FrameType::kMainFrame) { - // TODO(altimin): Support subframes as well. - delegate_->UpdateActiveSchedulerTrackedFeatures(new_mask); - } + if (old_mask != new_mask) + NotifyDelegateAboutFeaturesAfterCurrentTask(); } void FrameSchedulerImpl::OnStoppedUsingFeature( SchedulingPolicy::Feature feature, const SchedulingPolicy& policy) { - uint64_t old_mask = GetActiveFeaturesOptingOutFromBackForwardCacheMask(); + uint64_t old_mask = GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(); if (policy.disable_aggressive_throttling) OnRemovedAggressiveThrottlingOptOut(); if (policy.disable_back_forward_cache) OnRemovedBackForwardCacheOptOut(feature); - uint64_t new_mask = GetActiveFeaturesOptingOutFromBackForwardCacheMask(); + uint64_t new_mask = GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(); - if (old_mask != new_mask && delegate_ && - GetFrameType() == FrameType::kMainFrame) { - // TODO(altimin): Support subframes as well. - delegate_->UpdateActiveSchedulerTrackedFeatures(new_mask); - } + if (old_mask != new_mask) + NotifyDelegateAboutFeaturesAfterCurrentTask(); +} + +void FrameSchedulerImpl::NotifyDelegateAboutFeaturesAfterCurrentTask() { + if (!delegate_) + return; + if (feature_report_scheduled_) + return; + feature_report_scheduled_ = true; + + main_thread_scheduler_->ExecuteAfterCurrentTask( + base::BindOnce(&FrameSchedulerImpl::ReportFeaturesToDelegate, + document_bound_weak_factory_.GetWeakPtr())); +} + +void FrameSchedulerImpl::ReportFeaturesToDelegate() { + DCHECK(delegate_); + feature_report_scheduled_ = false; + uint64_t mask = GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(); + if (mask == last_uploaded_active_features_) + return; + last_uploaded_active_features_ = mask; + delegate_->UpdateActiveSchedulerTrackedFeatures(mask); } base::WeakPtr<FrameScheduler> FrameSchedulerImpl::GetWeakPtr() { @@ -697,6 +708,7 @@ void FrameSchedulerImpl::OnAddedBackForwardCacheOptOut( SchedulingPolicy::Feature feature) { ++back_forward_cache_opt_out_counts_[feature]; + back_forward_cache_opt_outs_.set(static_cast<size_t>(feature)); opted_out_from_back_forward_cache_ = true; } @@ -706,6 +718,7 @@ auto it = back_forward_cache_opt_out_counts_.find(feature); if (it->second == 1) { back_forward_cache_opt_out_counts_.erase(it); + back_forward_cache_opt_outs_.reset(static_cast<size_t>(feature)); } else { --it->second; } @@ -1059,7 +1072,7 @@ } WTF::HashSet<SchedulingPolicy::Feature> -FrameSchedulerImpl::GetActiveFeaturesOptingOutFromBackForwardCache() { +FrameSchedulerImpl::GetActiveFeaturesTrackedForBackForwardCacheMetrics() { WTF::HashSet<SchedulingPolicy::Feature> result; for (const auto& it : back_forward_cache_opt_out_counts_) result.insert(it.first); @@ -1067,11 +1080,19 @@ } uint64_t -FrameSchedulerImpl::GetActiveFeaturesOptingOutFromBackForwardCacheMask() const { - uint64_t mask = 0; - for (const auto& it : back_forward_cache_opt_out_counts_) - mask |= (1 << static_cast<int>(it.first)); - return mask; +FrameSchedulerImpl::GetActiveFeaturesTrackedForBackForwardCacheMetricsMask() + const { + auto result = back_forward_cache_opt_outs_.to_ullong(); + static_assert(static_cast<size_t>(SchedulingPolicy::Feature::kCount) <= + sizeof(result) * 8, + "Number of the features should allow a bitmask to fit into " + "64-bit integer"); + return result; +} + +base::WeakPtr<FrameOrWorkerScheduler> +FrameSchedulerImpl::GetDocumentBoundWeakPtr() { + return document_bound_weak_factory_.GetWeakPtr(); } // static
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h index da1bd57..794dde1 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_MAIN_THREAD_FRAME_SCHEDULER_IMPL_H_ #include <array> +#include <bitset> #include <memory> #include <utility> @@ -162,8 +163,19 @@ static void InitializeTaskTypeQueueTraitsMap( FrameTaskTypeToQueueTraitsArray&); + // Returns the list of active features which currently tracked by the + // scheduler for back-forward cache metrics. WTF::HashSet<SchedulingPolicy::Feature> - GetActiveFeaturesOptingOutFromBackForwardCache(); + GetActiveFeaturesTrackedForBackForwardCacheMetrics() override; + + // Notifies the delegate about the change in the set of active features. + // The scheduler calls this function when needed after each task finishes, + // grouping multiple OnStartedUsingFeature/OnStoppedUsingFeature into + // one call to the delegate (which is generally expected to upload them to + // the browser process). + // No calls will be issued to the delegate if the set of features didn't + // change since the previous call. + void ReportFeaturesToDelegate(); protected: FrameSchedulerImpl(MainThreadSchedulerImpl* main_thread_scheduler, @@ -249,9 +261,13 @@ // Reset the state which should not persist across navigations. void ResetForNavigation(); - // Same as GetActiveFeaturesOptingOutFromBackForwardCache, but returns + // Same as GetActiveFeaturesTrackedForBackForwardCacheMetrics, but returns // a mask instead of a set. - uint64_t GetActiveFeaturesOptingOutFromBackForwardCacheMask() const; + uint64_t GetActiveFeaturesTrackedForBackForwardCacheMetricsMask() const; + + base::WeakPtr<FrameOrWorkerScheduler> GetDocumentBoundWeakPtr() override; + + void NotifyDelegateAboutFeaturesAfterCurrentTask(); // Create QueueTraits for the default (non-finch) task queues. static MainThreadTaskQueue::QueueTraits ThrottleableTaskQueueTraits(); @@ -301,8 +317,14 @@ size_t subresource_loading_pause_count_; base::flat_map<SchedulingPolicy::Feature, int> back_forward_cache_opt_out_counts_; + std::bitset<static_cast<size_t>(SchedulingPolicy::Feature::kCount)> + back_forward_cache_opt_outs_; TraceableState<bool, TracingCategoryName::kInfo> opted_out_from_back_forward_cache_; + // The last set of features passed to + // Delegate::UpdateActiveSchedulerTrackedFeatures. + uint64_t last_uploaded_active_features_ = 0; + bool feature_report_scheduled_ = false; // These are the states of the Page. // They should be accessed via GetPageScheduler()->SetPageState(). @@ -313,6 +335,10 @@ TraceableState<bool, TracingCategoryName::kInfo> page_keep_active_for_tracing_; + // TODO(altimin): Remove after we have have 1:1 relationship between frames + // and documents. + base::WeakPtrFactory<FrameSchedulerImpl> document_bound_weak_factory_; + base::WeakPtrFactory<FrameSchedulerImpl> weak_factory_; DISALLOW_COPY_AND_ASSIGN(FrameSchedulerImpl);
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc index 10aaa93..74fc4076 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl_unittest.cc
@@ -35,6 +35,8 @@ // To avoid symbol collisions in jumbo builds. namespace frame_scheduler_impl_unittest { +using FeatureHandle = FrameOrWorkerScheduler::SchedulingAffectingFeatureHandle; + class FrameSchedulerDelegateForTesting : public FrameScheduler::Delegate { public: FrameSchedulerDelegateForTesting() {} @@ -49,7 +51,7 @@ update_task_time_calls_++; } - void UpdateActiveSchedulerTrackedFeatures(uint64_t features_mask) override {} + MOCK_METHOD1(UpdateActiveSchedulerTrackedFeatures, void(uint64_t)); int update_task_time_calls_ = 0; }; @@ -79,16 +81,16 @@ task_environment_.GetMockTickClock()), base::nullopt)); page_scheduler_.reset(new PageSchedulerImpl(nullptr, scheduler_.get())); - frame_scheduler_delegate_ = - std::make_unique<FrameSchedulerDelegateForTesting>(); + frame_scheduler_delegate_ = std::make_unique< + testing::StrictMock<FrameSchedulerDelegateForTesting>>(); frame_scheduler_ = FrameSchedulerImpl::Create( page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr, FrameScheduler::FrameType::kSubframe); } void ResetFrameScheduler(FrameScheduler::FrameType frame_type) { - frame_scheduler_delegate_ = - std::make_unique<FrameSchedulerDelegateForTesting>(); + frame_scheduler_delegate_ = std::make_unique< + testing::StrictMock<FrameSchedulerDelegateForTesting>>(); frame_scheduler_ = FrameSchedulerImpl::Create( page_scheduler_.get(), frame_scheduler_delegate_.get(), nullptr, frame_type); @@ -100,6 +102,11 @@ page_scheduler_.reset(); scheduler_->Shutdown(); scheduler_.reset(); + frame_scheduler_delegate_.reset(); + } + + static void ResetForNavigation(FrameSchedulerImpl* frame_scheduler) { + frame_scheduler->ResetForNavigation(); } base::TimeDelta GetTaskTime() { return frame_scheduler_->task_time_; } @@ -112,6 +119,12 @@ frame_scheduler_delegate_->update_task_time_calls_ = 0; } + static uint64_t GetActiveFeaturesTrackedForBackForwardCacheMetricsMask( + FrameSchedulerImpl* frame_scheduler) { + return frame_scheduler + ->GetActiveFeaturesTrackedForBackForwardCacheMetricsMask(); + } + protected: scoped_refptr<TaskQueue> throttleable_task_queue() { return throttleable_task_queue_; @@ -201,7 +214,8 @@ std::unique_ptr<MainThreadSchedulerImpl> scheduler_; std::unique_ptr<PageSchedulerImpl> page_scheduler_; std::unique_ptr<FrameSchedulerImpl> frame_scheduler_; - std::unique_ptr<FrameSchedulerDelegateForTesting> frame_scheduler_delegate_; + std::unique_ptr<testing::StrictMock<FrameSchedulerDelegateForTesting>> + frame_scheduler_delegate_; scoped_refptr<TaskQueue> throttleable_task_queue_; }; @@ -1926,6 +1940,224 @@ frame_scheduler_->ComputePriority(task_queue.get()); } +namespace { + +// Mask is a preferred way of plumbing the list of features, but a list +// is more convenient to read in the tests. +// Here we ensure that these two methods are equivalent. +uint64_t ComputeMaskFromFeatures(FrameSchedulerImpl* frame_scheduler) { + uint64_t result = 0; + for (SchedulingPolicy::Feature feature : + frame_scheduler->GetActiveFeaturesTrackedForBackForwardCacheMetrics()) { + result |= (1 << static_cast<size_t>(feature)); + } + return result; +} + +} // namespace + +TEST_F(FrameSchedulerImplTest, BackForwardCacheOptOut) { + EXPECT_THAT( + frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), + testing::UnorderedElementsAre()); + EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()), + GetActiveFeaturesTrackedForBackForwardCacheMetricsMask( + frame_scheduler_.get())); + + auto feature_handle1 = frame_scheduler_->RegisterFeature( + SchedulingPolicy::Feature::kWebSocket, + {SchedulingPolicy::RecordMetricsForBackForwardCache()}); + + EXPECT_THAT( + frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), + testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebSocket)); + EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()), + GetActiveFeaturesTrackedForBackForwardCacheMetricsMask( + frame_scheduler_.get())); + + auto feature_handle2 = frame_scheduler_->RegisterFeature( + SchedulingPolicy::Feature::kWebRTC, + {SchedulingPolicy::RecordMetricsForBackForwardCache()}); + + EXPECT_THAT( + frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), + testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebSocket, + SchedulingPolicy::Feature::kWebRTC)); + EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()), + GetActiveFeaturesTrackedForBackForwardCacheMetricsMask( + frame_scheduler_.get())); + + feature_handle1.reset(); + + EXPECT_THAT( + frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), + testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebRTC)); + EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()), + GetActiveFeaturesTrackedForBackForwardCacheMetricsMask( + frame_scheduler_.get())); + + feature_handle2.reset(); + + EXPECT_THAT( + frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), + testing::UnorderedElementsAre()); + EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()), + GetActiveFeaturesTrackedForBackForwardCacheMetricsMask( + frame_scheduler_.get())); +} + +TEST_F(FrameSchedulerImplTest, BackForwardCacheOptOut_FrameNavigated) { + EXPECT_THAT( + frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), + testing::UnorderedElementsAre()); + EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()), + GetActiveFeaturesTrackedForBackForwardCacheMetricsMask( + frame_scheduler_.get())); + + auto feature_handle = frame_scheduler_->RegisterFeature( + SchedulingPolicy::Feature::kWebSocket, + {SchedulingPolicy::RecordMetricsForBackForwardCache()}); + + EXPECT_THAT( + frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), + testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebSocket)); + EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()), + GetActiveFeaturesTrackedForBackForwardCacheMetricsMask( + frame_scheduler_.get())); + + frame_scheduler_->RegisterStickyFeature( + SchedulingPolicy::Feature::kMainResourceHasCacheControlNoStore, + {SchedulingPolicy::RecordMetricsForBackForwardCache()}); + + EXPECT_THAT( + frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), + testing::UnorderedElementsAre( + SchedulingPolicy::Feature::kWebSocket, + SchedulingPolicy::Feature::kMainResourceHasCacheControlNoStore)); + EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()), + GetActiveFeaturesTrackedForBackForwardCacheMetricsMask( + frame_scheduler_.get())); + + // Same document navigations don't affect anything. + frame_scheduler_->DidCommitProvisionalLoad( + false, FrameScheduler::NavigationType::kSameDocument); + EXPECT_THAT( + frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), + testing::UnorderedElementsAre( + SchedulingPolicy::Feature::kWebSocket, + SchedulingPolicy::Feature::kMainResourceHasCacheControlNoStore)); + EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()), + GetActiveFeaturesTrackedForBackForwardCacheMetricsMask( + frame_scheduler_.get())); + + // Regular navigations reset all features. + frame_scheduler_->DidCommitProvisionalLoad( + false, FrameScheduler::NavigationType::kOther); + EXPECT_THAT( + frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), + testing::UnorderedElementsAre()); + EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()), + GetActiveFeaturesTrackedForBackForwardCacheMetricsMask( + frame_scheduler_.get())); + + // Resetting a feature handle after navigation shouldn't do anything. + feature_handle.reset(); + + EXPECT_THAT( + frame_scheduler_->GetActiveFeaturesTrackedForBackForwardCacheMetrics(), + testing::UnorderedElementsAre()); + EXPECT_EQ(ComputeMaskFromFeatures(frame_scheduler_.get()), + GetActiveFeaturesTrackedForBackForwardCacheMetricsMask( + frame_scheduler_.get())); +} + +TEST_F(FrameSchedulerImplTest, FeatureUpload) { + ResetFrameScheduler(FrameScheduler::FrameType::kMainFrame); + + frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimer) + ->PostTask( + FROM_HERE, + base::BindOnce( + [](FrameSchedulerImpl* frame_scheduler, + testing::StrictMock<FrameSchedulerDelegateForTesting>* + delegate) { + frame_scheduler->RegisterStickyFeature( + SchedulingPolicy::Feature:: + kMainResourceHasCacheControlNoStore, + {SchedulingPolicy::RecordMetricsForBackForwardCache()}); + frame_scheduler->RegisterStickyFeature( + SchedulingPolicy::Feature:: + kMainResourceHasCacheControlNoCache, + {SchedulingPolicy::RecordMetricsForBackForwardCache()}); + // Ensure that the feature upload is delayed. + testing::Mock::VerifyAndClearExpectations(delegate); + EXPECT_CALL( + *delegate, + UpdateActiveSchedulerTrackedFeatures( + (1 << static_cast<size_t>( + SchedulingPolicy::Feature:: + kMainResourceHasCacheControlNoStore)) | + (1 << static_cast<size_t>( + SchedulingPolicy::Feature:: + kMainResourceHasCacheControlNoCache)))); + }, + frame_scheduler_.get(), frame_scheduler_delegate_.get())); + + base::RunLoop().RunUntilIdle(); + + testing::Mock::VerifyAndClearExpectations(frame_scheduler_delegate_.get()); +} + +TEST_F(FrameSchedulerImplTest, FeatureUpload_FrameDestruction) { + ResetFrameScheduler(FrameScheduler::FrameType::kMainFrame); + + FeatureHandle feature_handle; + + frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimer) + ->PostTask( + FROM_HERE, + base::BindOnce( + [](FrameSchedulerImpl* frame_scheduler, + testing::StrictMock<FrameSchedulerDelegateForTesting>* + delegate, + FeatureHandle* feature_handle) { + *feature_handle = frame_scheduler->RegisterFeature( + SchedulingPolicy::Feature::kWebSocket, + {SchedulingPolicy::RecordMetricsForBackForwardCache()}); + // Ensure that the feature upload is delayed. + testing::Mock::VerifyAndClearExpectations(delegate); + EXPECT_CALL(*delegate, + UpdateActiveSchedulerTrackedFeatures( + (1 << static_cast<size_t>( + SchedulingPolicy::Feature::kWebSocket)))); + }, + frame_scheduler_.get(), frame_scheduler_delegate_.get(), + &feature_handle)); + frame_scheduler_->GetTaskRunner(TaskType::kJavascriptTimer) + ->PostTask(FROM_HERE, + base::BindOnce( + [](FrameSchedulerImpl* frame_scheduler, + testing::StrictMock<FrameSchedulerDelegateForTesting>* + delegate, + FeatureHandle* feature_handle) { + feature_handle->reset(); + ResetForNavigation(frame_scheduler); + // Ensure that we don't upload the features for frame + // destruction. + testing::Mock::VerifyAndClearExpectations(delegate); + EXPECT_CALL( + *delegate, + UpdateActiveSchedulerTrackedFeatures(testing::_)) + .Times(0); + }, + frame_scheduler_.get(), frame_scheduler_delegate_.get(), + &feature_handle)); + + base::RunLoop().RunUntilIdle(); + + testing::Mock::VerifyAndClearExpectations(frame_scheduler_delegate_.get()); +} + } // namespace frame_scheduler_impl_unittest } // namespace scheduler } // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc index f3a7a77..9684f03f 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
@@ -2387,6 +2387,8 @@ if (main_thread_only().nested_runloop) return; + DispatchOnTaskCompletionCallbacks(); + if (queue) { task_queue_throttler()->OnTaskRunTimeReported( queue, task_timing.start_time(), task_timing.end_time()); @@ -2673,6 +2675,19 @@ main_thread_only().has_safepoint = true; } +void MainThreadSchedulerImpl::ExecuteAfterCurrentTask( + base::OnceClosure on_completion_task) { + main_thread_only().on_task_completion_callbacks.push_back( + std::move(on_completion_task)); +} + +void MainThreadSchedulerImpl::DispatchOnTaskCompletionCallbacks() { + for (auto& closure : main_thread_only().on_task_completion_callbacks) { + std::move(closure).Run(); + } + main_thread_only().on_task_completion_callbacks.clear(); +} + // static const char* MainThreadSchedulerImpl::UseCaseToString(UseCase use_case) { switch (use_case) {
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h index 5facd4f8..7e7c38c 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h
@@ -47,6 +47,7 @@ #include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h" #include "third_party/blink/renderer/platform/scheduler/public/rail_mode_observer.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" namespace base { namespace trace_event { @@ -384,6 +385,11 @@ void SetShouldPrioritizeCompositing(bool should_prioritize_compositing); + // Allow places in the scheduler to do some work after the current task. + // The primary use case here is batching – to allow updates to be processed + // only once per task. + void ExecuteAfterCurrentTask(base::OnceClosure on_completion_task); + base::WeakPtr<MainThreadSchedulerImpl> GetWeakPtr(); protected: @@ -708,6 +714,10 @@ void ShutdownAllQueues(); + // Dispatch the callbacks which requested to be executed after the current + // task. + void DispatchOnTaskCompletionCallbacks(); + // Indicates that scheduler has been shutdown. // It should be accessed only on the main thread, but couldn't be a member // of MainThreadOnly struct because last might be destructed before we @@ -870,6 +880,9 @@ // True if a task has a safepoint. bool has_safepoint; + + // List of callbacks to execute after the current task. + WTF::Vector<base::OnceClosure> on_task_completion_callbacks; }; struct AnyThread {
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc index 78cac46..174520e 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.cc
@@ -425,18 +425,6 @@ } } -WTF::HashSet<SchedulingPolicy::Feature> -PageSchedulerImpl::GetActiveFeaturesOptingOutFromBackForwardCache() const { - WTF::HashSet<SchedulingPolicy::Feature> result; - for (FrameSchedulerImpl* frame_scheduler : frame_schedulers_) { - for (SchedulingPolicy::Feature feature : - frame_scheduler->GetActiveFeaturesOptingOutFromBackForwardCache()) { - result.insert(feature); - } - } - return result; -} - bool PageSchedulerImpl::IsExemptFromBudgetBasedThrottling() const { return opted_out_from_aggressive_throttling_; }
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h index d27eaa0..22966515 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h +++ b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl.h
@@ -75,8 +75,6 @@ int max_task_starvation_count) override; void AudioStateChanged(bool is_audio_playing) override; bool IsAudioPlaying() const override; - WTF::HashSet<SchedulingPolicy::Feature> - GetActiveFeaturesOptingOutFromBackForwardCache() const override; bool IsExemptFromBudgetBasedThrottling() const override; bool OptedOutFromAggressiveThrottlingForTest() const override; bool RequestBeginMainFrameNotExpected(bool new_state) override;
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc index a49cdd3c..c54a570c 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc
@@ -1718,101 +1718,6 @@ UnorderedElementsAreArray(GetExpectedBuckets())); } -TEST_F(PageSchedulerImplTest, BackForwardCacheOptOut) { - EXPECT_THAT(page_scheduler_->GetActiveFeaturesOptingOutFromBackForwardCache(), - testing::UnorderedElementsAre()); - - auto feature_handle1 = frame_scheduler_->RegisterFeature( - SchedulingPolicy::Feature::kWebSocket, - {SchedulingPolicy::DisableBackForwardCache()}); - - EXPECT_THAT( - page_scheduler_->GetActiveFeaturesOptingOutFromBackForwardCache(), - testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebSocket)); - - auto feature_handle2 = frame_scheduler_->RegisterFeature( - SchedulingPolicy::Feature::kWebRTC, - {SchedulingPolicy::DisableBackForwardCache()}); - - EXPECT_THAT( - page_scheduler_->GetActiveFeaturesOptingOutFromBackForwardCache(), - testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebSocket, - SchedulingPolicy::Feature::kWebRTC)); - - feature_handle1.reset(); - - EXPECT_THAT( - page_scheduler_->GetActiveFeaturesOptingOutFromBackForwardCache(), - testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebRTC)); - - feature_handle2.reset(); - - EXPECT_THAT(page_scheduler_->GetActiveFeaturesOptingOutFromBackForwardCache(), - testing::UnorderedElementsAre()); -} - -TEST_F(PageSchedulerImplTest, BackForwardCacheOptOut_FrameDeleted) { - EXPECT_THAT(page_scheduler_->GetActiveFeaturesOptingOutFromBackForwardCache(), - testing::UnorderedElementsAre()); - - auto feature_handle = frame_scheduler_->RegisterFeature( - SchedulingPolicy::Feature::kWebSocket, - {SchedulingPolicy::DisableBackForwardCache()}); - - EXPECT_THAT( - page_scheduler_->GetActiveFeaturesOptingOutFromBackForwardCache(), - testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebSocket)); - - frame_scheduler_.reset(); - - EXPECT_THAT(page_scheduler_->GetActiveFeaturesOptingOutFromBackForwardCache(), - testing::UnorderedElementsAre()); -} - -TEST_F(PageSchedulerImplTest, BackForwardCacheOptOut_FrameNavigated) { - EXPECT_THAT(page_scheduler_->GetActiveFeaturesOptingOutFromBackForwardCache(), - testing::UnorderedElementsAre()); - - auto feature_handle = frame_scheduler_->RegisterFeature( - SchedulingPolicy::Feature::kWebSocket, - {SchedulingPolicy::DisableBackForwardCache()}); - - EXPECT_THAT( - page_scheduler_->GetActiveFeaturesOptingOutFromBackForwardCache(), - testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebSocket)); - - frame_scheduler_->RegisterStickyFeature( - SchedulingPolicy::Feature::kMainResourceHasCacheControlNoStore, - {SchedulingPolicy::DisableBackForwardCache()}); - - EXPECT_THAT( - page_scheduler_->GetActiveFeaturesOptingOutFromBackForwardCache(), - testing::UnorderedElementsAre( - SchedulingPolicy::Feature::kWebSocket, - SchedulingPolicy::Feature::kMainResourceHasCacheControlNoStore)); - - // Same document navigations don't affect anything. - frame_scheduler_->DidCommitProvisionalLoad( - false, FrameScheduler::NavigationType::kSameDocument); - EXPECT_THAT( - page_scheduler_->GetActiveFeaturesOptingOutFromBackForwardCache(), - testing::UnorderedElementsAre( - SchedulingPolicy::Feature::kWebSocket, - SchedulingPolicy::Feature::kMainResourceHasCacheControlNoStore)); - - // Regular navigations reset sticky features. - frame_scheduler_->DidCommitProvisionalLoad( - false, FrameScheduler::NavigationType::kOther); - EXPECT_THAT( - page_scheduler_->GetActiveFeaturesOptingOutFromBackForwardCache(), - testing::UnorderedElementsAre(SchedulingPolicy::Feature::kWebSocket)); - - feature_handle.reset(); - - EXPECT_THAT(page_scheduler_->GetActiveFeaturesOptingOutFromBackForwardCache(), - testing::UnorderedElementsAre()); -} - } // namespace page_scheduler_impl_unittest } // namespace scheduler } // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h b/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h index 94523d85..6c3132b 100644 --- a/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h
@@ -129,6 +129,8 @@ virtual void OnStoppedUsingFeature(SchedulingPolicy::Feature feature, const SchedulingPolicy& policy) = 0; + virtual base::WeakPtr<FrameOrWorkerScheduler> GetDocumentBoundWeakPtr(); + base::WeakPtr<FrameOrWorkerScheduler> GetWeakPtr(); private:
diff --git a/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h b/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h index b8f929a..1eb0093c 100644 --- a/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h
@@ -16,6 +16,7 @@ #include "third_party/blink/public/platform/web_scoped_virtual_time_pauser.h" #include "third_party/blink/renderer/platform/platform_export.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h" +#include "third_party/blink/renderer/platform/wtf/hash_set.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace ukm { @@ -41,6 +42,9 @@ // Notify that the list of active features for this frame has changed. // See SchedulingPolicy::Feature for the list of features and the meaning // of individual features. + // Note that this method is not called when the frame navigates — it is + // the responsibility of the observer to detect this and act reset features + // accordingly. virtual void UpdateActiveSchedulerTrackedFeatures( uint64_t features_mask) = 0; }; @@ -144,6 +148,11 @@ virtual std::unique_ptr<blink::mojom::blink::PauseSubresourceLoadingHandle> GetPauseSubresourceLoadingHandle() = 0; + // Returns the list of active features which currently tracked by the + // scheduler for back-forward cache metrics. + virtual WTF::HashSet<SchedulingPolicy::Feature> + GetActiveFeaturesTrackedForBackForwardCacheMetrics() = 0; + // TODO(altimin): Move FrameScheduler object to oilpan. virtual base::WeakPtr<FrameScheduler> GetWeakPtr() = 0; };
diff --git a/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h b/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h index 4783bcc..03a096e 100644 --- a/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/public/page_scheduler.h
@@ -135,12 +135,6 @@ // (e.g. due to a page maintaining an active connection). virtual bool IsExemptFromBudgetBasedThrottling() const = 0; - // Returns a set of features which at the moment prevent page from going into - // back-forward cache. If this list is empty, the page is eligible for - // back-forward cache. - virtual WTF::HashSet<SchedulingPolicy::Feature> - GetActiveFeaturesOptingOutFromBackForwardCache() const = 0; - virtual bool OptedOutFromAggressiveThrottlingForTest() const = 0; // Returns true if the request has been succcessfully relayed to the
diff --git a/third_party/blink/renderer/platform/scheduler/public/scheduling_policy.h b/third_party/blink/renderer/platform/scheduler/public/scheduling_policy.h index 8c4f50d..8f87f950 100644 --- a/third_party/blink/renderer/platform/scheduler/public/scheduling_policy.h +++ b/third_party/blink/renderer/platform/scheduler/public/scheduling_policy.h
@@ -6,6 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_PUBLIC_SCHEDULING_POLICY_H_ #include "base/traits_bag.h" +#include "third_party/blink/public/common/scheduler/web_scheduler_tracked_feature.h" #include "third_party/blink/renderer/platform/platform_export.h" namespace blink { @@ -14,27 +15,7 @@ // if the page is using this feature. // See FrameOrWorkerScheduler::RegisterFeature. struct PLATFORM_EXPORT SchedulingPolicy { - // List of features which can trigger the policy changes. - enum class Feature { - kWebSocket = 0, - kWebRTC = 1, - - kMainResourceHasCacheControlNoCache = 2, - kMainResourceHasCacheControlNoStore = 3, - kSubresourceHasCacheControlNoCache = 4, - kSubresourceHasCacheControlNoStore = 5, - - kPageShowEventListener = 6, - kPageHideEventListener = 7, - kBeforeUnloadEventListener = 8, - kUnloadEventListener = 9, - kFreezeEventListener = 10, - kResumeEventListener = 11, - - kContainsPlugins = 12, - - kCount = 13 - }; + using Feature = scheduler::WebSchedulerTrackedFeature; // Sticky features can't be unregistered and remain active for the rest // of the lifetime of the page. @@ -42,11 +23,11 @@ // List of opt-outs which form a policy. struct DisableAggressiveThrottling {}; - struct DisableBackForwardCache {}; + struct RecordMetricsForBackForwardCache {}; struct ValidPolicies { ValidPolicies(DisableAggressiveThrottling); - ValidPolicies(DisableBackForwardCache); + ValidPolicies(RecordMetricsForBackForwardCache); }; template <class... ArgTypes, @@ -58,7 +39,8 @@ base::trait_helpers::HasTrait<DisableAggressiveThrottling>( args...)), disable_back_forward_cache( - base::trait_helpers::HasTrait<DisableBackForwardCache>(args...)) {} + base::trait_helpers::HasTrait<RecordMetricsForBackForwardCache>( + args...)) {} SchedulingPolicy() {}
diff --git a/third_party/blink/renderer/platform/scheduler/test/fake_page_scheduler.h b/third_party/blink/renderer/platform/scheduler/test/fake_page_scheduler.h index 27675de..a089527 100644 --- a/third_party/blink/renderer/platform/scheduler/test/fake_page_scheduler.h +++ b/third_party/blink/renderer/platform/scheduler/test/fake_page_scheduler.h
@@ -78,10 +78,6 @@ bool RequestBeginMainFrameNotExpected(bool new_state) override { return false; } - WTF::HashSet<SchedulingPolicy::Feature> - GetActiveFeaturesOptingOutFromBackForwardCache() const override { - return WTF::HashSet<SchedulingPolicy::Feature>(); - } private: bool is_audio_playing_;
diff --git a/third_party/blink/renderer/platform/scheduler/test/renderer_scheduler_test_support.cc b/third_party/blink/renderer/platform/scheduler/test/renderer_scheduler_test_support.cc index a3744ed..9eb78c6 100644 --- a/third_party/blink/renderer/platform/scheduler/test/renderer_scheduler_test_support.cc +++ b/third_party/blink/renderer/platform/scheduler/test/renderer_scheduler_test_support.cc
@@ -90,6 +90,10 @@ const SchedulingPolicy& policy) override {} void OnStoppedUsingFeature(SchedulingPolicy::Feature feature, const SchedulingPolicy& policy) override {} + WTF::HashSet<SchedulingPolicy::Feature> + GetActiveFeaturesTrackedForBackForwardCacheMetrics() override { + return WTF::HashSet<SchedulingPolicy::Feature>(); + } base::WeakPtr<FrameScheduler> GetWeakPtr() override { return nullptr; } private: @@ -131,10 +135,6 @@ return false; } bool RequestBeginMainFrameNotExpected(bool) override { return false; } - WTF::HashSet<SchedulingPolicy::Feature> - GetActiveFeaturesOptingOutFromBackForwardCache() const override { - return WTF::HashSet<SchedulingPolicy::Feature>(); - } private: DISALLOW_COPY_AND_ASSIGN(SimplePageScheduler);
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 03715c1..a0decd7 100644 --- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
@@ -235,7 +235,10 @@ crbug.com/591099 external/wpt/css/css-writing-modes/vertical-alignment-009.xht [ Pass ] crbug.com/591099 external/wpt/css/cssom-view/elementsFromPoint-inline-vrl-ltr.html [ Pass ] crbug.com/591099 external/wpt/css/cssom-view/elementsFromPoint-inline-vrl-rtl.html [ Pass ] -crbug.com/953479 external/wpt/css/cssom-view/offsetTopLeftEmptyInline.html [ Failure ] +crbug.com/953479 external/wpt/css/cssom-view/offsetTopLeft-empty-inline.html [ Failure ] +crbug.com/953479 external/wpt/css/cssom-view/offsetTopLeft-empty-inline-offset.html [ Failure ] +crbug.com/953479 external/wpt/css/cssom-view/offsetTopLeft-leading-space-inline.html [ Failure ] +crbug.com/953479 external/wpt/css/cssom-view/offsetTopLeft-trailing-space-inline.html [ Failure ] crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-self-horiz-002.xhtml [ Pass ] crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-writing-mode-011.html [ Pass ] crbug.com/591099 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/ib-split/emptyspan-1.html [ Pass ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index f034adc..e6d869b 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -1115,13 +1115,13 @@ crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/float-edge.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/float-margin-at-row-boundary.html [ Failure ] crbug.com/829028 virtual/layout_ng_experimental/fast/multicol/float-margin-at-row-boundary-fixed-multicol-height.html [ Failure ] -crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/float-moved-by-child-line-and-unbreakable.html [ Failure ] +crbug.com/954171 virtual/layout_ng_experimental/fast/multicol/float-moved-by-child-line-and-unbreakable.html [ Failure Crash ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/float-paginate-empty-lines.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/float-paginate.html [ Failure ] -crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/float-with-margin-moved-by-child-block-and-unbreakable.html [ Failure ] -crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/float-with-margin-moved-by-child-block.html [ Failure ] -crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/float-with-margin-moved-by-child-line-and-unbreakable.html [ Failure ] -crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/float-with-margin-moved-by-child-line.html [ Failure ] +crbug.com/954171 virtual/layout_ng_experimental/fast/multicol/float-with-margin-moved-by-child-block-and-unbreakable.html [ Failure Crash ] +crbug.com/954171 virtual/layout_ng_experimental/fast/multicol/float-with-margin-moved-by-child-block.html [ Failure Crash ] +crbug.com/954171 virtual/layout_ng_experimental/fast/multicol/float-with-margin-moved-by-child-line-and-unbreakable.html [ Failure Crash ] +crbug.com/954171 virtual/layout_ng_experimental/fast/multicol/float-with-margin-moved-by-child-line.html [ Failure Crash ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/float-with-margin-moved-unbreakable.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/forced-break-after-block-with-spanner.html [ Failure ] crbug.com/591099 virtual/layout_ng_experimental/fast/multicol/forced-break-after-empty-block-after-spanner.html [ Failure ] @@ -6327,6 +6327,9 @@ # Sheriff 2019-04-17 crbug.com/953534 [ Mac ] virtual/layout_ng_experimental/external/wpt/css/css-flexbox/ttwf-reftest-flex-wrap.html [ Failure ] +crbug.com/953479 external/wpt/css/cssom-view/offsetTopLeft-empty-inline.html [ Failure ] +crbug.com/953479 external/wpt/css/cssom-view/offsetTopLeft-leading-space-inline.html [ Failure ] + crbug.com/953591 [ Win ] css3/masking/mask-repeat-space-padding.html [ Pass Failure ] crbug.com/953591 [ Win ] fast/forms/datalist/input-appearance-range-with-transform.html [ Pass Failure ] crbug.com/953591 [ Win ] transforms/matrix-02.html [ Pass Failure ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json index bae4e58..41263931 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -133,51 +133,51 @@ {} ] ], - "clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html": [ - [ - "clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html", - {} - ] - ], - "clipboard-apis/async-write-blobtext-read-text-manual.https.html": [ - [ - "clipboard-apis/async-write-blobtext-read-text-manual.https.html", - {} - ] - ], "clipboard-apis/async-write-image-read-image-manual.https.html": [ [ "clipboard-apis/async-write-image-read-image-manual.https.html", {} ] ], - "clipboard-apis/async-write-text-read-blobtext-manual.https.html": [ + "clipboard-apis/events/copy-event-manual.html": [ [ - "clipboard-apis/async-write-text-read-blobtext-manual.https.html", + "clipboard-apis/events/copy-event-manual.html", {} ] ], - "clipboard-apis/async-write-text-read-text-manual.https.html": [ + "clipboard-apis/events/cut-event-manual.html": [ [ - "clipboard-apis/async-write-text-read-text-manual.https.html", + "clipboard-apis/events/cut-event-manual.html", {} ] ], - "clipboard-apis/copy-event-manual.html": [ + "clipboard-apis/events/paste-event-manual.html": [ [ - "clipboard-apis/copy-event-manual.html", + "clipboard-apis/events/paste-event-manual.html", {} ] ], - "clipboard-apis/cut-event-manual.html": [ + "clipboard-apis/text-write-read/async-write-read-manual.https.html": [ [ - "clipboard-apis/cut-event-manual.html", + "clipboard-apis/text-write-read/async-write-read-manual.https.html", {} ] ], - "clipboard-apis/paste-event-manual.html": [ + "clipboard-apis/text-write-read/async-write-readText-manual.https.html": [ [ - "clipboard-apis/paste-event-manual.html", + "clipboard-apis/text-write-read/async-write-readText-manual.https.html", + {} + ] + ], + "clipboard-apis/text-write-read/async-writeText-read-manual.https.html": [ + [ + "clipboard-apis/text-write-read/async-writeText-read-manual.https.html", + {} + ] + ], + "clipboard-apis/text-write-read/async-writeText-readText-manual.https.html": [ + [ + "clipboard-apis/text-write-read/async-writeText-readText-manual.https.html", {} ] ], @@ -93781,18 +93781,6 @@ {} ] ], - "css/cssom-view/offsetTopLeftInlineMultiLine.html": [ - [ - "css/cssom-view/offsetTopLeftInlineMultiLine.html", - [ - [ - "/css/reference/nothing.html", - "==" - ] - ], - {} - ] - ], "css/cssom-view/scrollTop-display-change.html": [ [ "css/cssom-view/scrollTop-display-change.html", @@ -167342,11 +167330,6 @@ {} ] ], - "html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-noreferrer-expected.txt": [ - [ - {} - ] - ], "html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-screenx-screeny-expected.txt": [ [ {} @@ -167452,6 +167435,11 @@ {} ] ], + "html/browsers/the-window-object/support/BarProp-target.html": [ + [ + {} + ] + ], "html/browsers/the-window-object/support/closed.html": [ [ {} @@ -167487,11 +167475,6 @@ {} ] ], - "html/browsers/the-window-object/window-open-noreferrer-expected.txt": [ - [ - {} - ] - ], "html/browsers/the-window-object/window-properties.https-expected.txt": [ [ {} @@ -181417,6 +181400,16 @@ {} ] ], + "native-file-system/README.md": [ + [ + {} + ] + ], + "native-file-system/resources/test-helpers.js": [ + [ + {} + ] + ], "navigation-timing/META.yml": [ [ {} @@ -219918,12 +219911,6 @@ {} ] ], - "animation-worklet/animator-animate.https.html": [ - [ - "animation-worklet/animator-animate.https.html", - {} - ] - ], "animation-worklet/animator-with-options.https.html": [ [ "animation-worklet/animator-with-options.https.html", @@ -220022,6 +220009,12 @@ {} ] ], + "animation-worklet/worklet-animation-play.https.html": [ + [ + "animation-worklet/worklet-animation-play.https.html", + {} + ] + ], "animation-worklet/worklet-animation-with-fill-mode.https.html": [ [ "animation-worklet/worklet-animation-with-fill-mode.https.html", @@ -259802,6 +259795,12 @@ {} ] ], + "html/browsers/the-window-object/noopener-noreferrer-BarProp.window.js": [ + [ + "html/browsers/the-window-object/noopener-noreferrer-BarProp.window.html", + {} + ] + ], "html/browsers/the-window-object/security-window/window-security.https.html": [ [ "html/browsers/the-window-object/security-window/window-security.https.html", @@ -277038,6 +277037,84 @@ } ] ], + "native-file-system/FileSystemBaseHandle-copyTo.tentative.window.js": [ + [ + "native-file-system/FileSystemBaseHandle-copyTo.tentative.window.html", + { + "script_metadata": [ + [ + "script", + "resources/test-helpers.js" + ] + ] + } + ] + ], + "native-file-system/FileSystemBaseHandle-moveTo.tentative.window.js": [ + [ + "native-file-system/FileSystemBaseHandle-moveTo.tentative.window.html", + { + "script_metadata": [ + [ + "script", + "resources/test-helpers.js" + ] + ] + } + ] + ], + "native-file-system/FileSystemBaseHandle-remove.tentative.window.js": [ + [ + "native-file-system/FileSystemBaseHandle-remove.tentative.window.html", + { + "script_metadata": [ + [ + "script", + "resources/test-helpers.js" + ] + ] + } + ] + ], + "native-file-system/FileSystemDirectoryHandle-getDirectory.tentative.window.js": [ + [ + "native-file-system/FileSystemDirectoryHandle-getDirectory.tentative.window.html", + { + "script_metadata": [ + [ + "script", + "resources/test-helpers.js" + ] + ] + } + ] + ], + "native-file-system/FileSystemDirectoryHandle-getFile.tentative.window.js": [ + [ + "native-file-system/FileSystemDirectoryHandle-getFile.tentative.window.html", + { + "script_metadata": [ + [ + "script", + "resources/test-helpers.js" + ] + ] + } + ] + ], + "native-file-system/FileSystemWriter.tentative.window.js": [ + [ + "native-file-system/FileSystemWriter.tentative.window.html", + { + "script_metadata": [ + [ + "script", + "resources/test-helpers.js" + ] + ] + } + ] + ], "navigation-timing/dom_interactive_image_document.html": [ [ "navigation-timing/dom_interactive_image_document.html", @@ -321859,6 +321936,12 @@ {} ] ], + "webxr/xrDevice_requestSession_no_mode.https.html": [ + [ + "webxr/xrDevice_requestSession_no_mode.https.html", + {} + ] + ], "webxr/xrDevice_requestSession_non_immersive_no_gesture.https.html": [ [ "webxr/xrDevice_requestSession_non_immersive_no_gesture.https.html", @@ -341138,10 +341221,6 @@ "415f39440156e0c3906799869662f65e19ceef38", "testharness" ], - "animation-worklet/animator-animate.https.html": [ - "2ac25498bceb06180e5e1d0eefc243e9e85aab31", - "testharness" - ], "animation-worklet/animator-with-options.https.html": [ "975c57f03847025e7a53c74bcc4bc10ecf99c996", "testharness" @@ -341242,6 +341321,10 @@ "417db9e37a61193a99908648e4cbc3be4c2e9618", "testharness" ], + "animation-worklet/worklet-animation-play.https.html": [ + "038cd74aab06d11352ad4235263b23978a8b863e", + "testharness" + ], "animation-worklet/worklet-animation-set-keyframes-ref.html": [ "26bf33fdb403877f2e3adf9b8bb3fca6bf8301bb", "support" @@ -342655,35 +342738,19 @@ "support" ], "clipboard-apis/async-interfaces.https.html": [ - "e0d0977959b5dbe943005587c1442de451d9a18d", + "e19c958f975d7967b8028a13d6901bdbd2ab4553", "testharness" ], "clipboard-apis/async-navigator-clipboard-basics.https.html": [ - "9bff6ab08582ce6389eb1a3a9d866c9c3d8de3bc", + "706093af61314dc0de57ff8fa5415011c13089ee", "testharness" ], "clipboard-apis/async-write-blobs-read-blobs-manual.https.html": [ - "a7d1fde24fb54b4bc84436aad7755493106de4b9", - "manual" - ], - "clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html": [ - "aaf0b589c81ca6bf3f7e965cfc65fe6a9df7e5c0", - "manual" - ], - "clipboard-apis/async-write-blobtext-read-text-manual.https.html": [ - "72fe597fb74defc294f87eba85aab66f3472d20e", + "b5f0f3d9dc13d2b67264b3a61b9f0f8be0cd6ecd", "manual" ], "clipboard-apis/async-write-image-read-image-manual.https.html": [ - "2cc6eb70542b92238441a6581552abe525751e15", - "manual" - ], - "clipboard-apis/async-write-text-read-blobtext-manual.https.html": [ - "d62c119a8f5246e3169bc785dbe24c9a0137f393", - "manual" - ], - "clipboard-apis/async-write-text-read-text-manual.https.html": [ - "25c7edb43f061552717459caf6d4df969383e84c", + "351e74bd74568b4c221cd60c145c2681e1dc6ed5", "manual" ], "clipboard-apis/clipboard-events-synthetic.html": [ @@ -342691,18 +342758,18 @@ "testharness" ], "clipboard-apis/clipboard-item.https.html": [ - "aa55f9985c05cf8b8c8003d979ca00da1b306474", + "9218ee299e2b66a3bd7e70b6ac58c6cb26fdfaac", "testharness" ], - "clipboard-apis/copy-event-manual.html": [ + "clipboard-apis/events/copy-event-manual.html": [ "6f687af196fa198cda7d83f468945f9f69330568", "manual" ], - "clipboard-apis/cut-event-manual.html": [ + "clipboard-apis/events/cut-event-manual.html": [ "c5593171754cfa2bd684e1ff3a8a724283456cbd", "manual" ], - "clipboard-apis/paste-event-manual.html": [ + "clipboard-apis/events/paste-event-manual.html": [ "19e6b95c5f32a0eb7dbccb0f5bd538e9dbb1360e", "manual" ], @@ -342710,6 +342777,22 @@ "6e555e3b197ce2f448f59d61e1488a0175490145", "support" ], + "clipboard-apis/text-write-read/async-write-read-manual.https.html": [ + "b374333ca944a5a675f71678f1f30f1216a100d1", + "manual" + ], + "clipboard-apis/text-write-read/async-write-readText-manual.https.html": [ + "2d78b2f186e3c761549b578555f3ac6c15145221", + "manual" + ], + "clipboard-apis/text-write-read/async-writeText-read-manual.https.html": [ + "4f9fe25bca588d47d4d4d045a8fa3afe0cd44314", + "manual" + ], + "clipboard-apis/text-write-read/async-writeText-readText-manual.https.html": [ + "48e5adb51d249b0846398a5a742c430809972e87", + "manual" + ], "common/META.yml": [ "958883a1b07e7db13249153fc85c69d2a40363a3", "support" @@ -392307,7 +392390,7 @@ "testharness" ], "css/css-syntax/input-preprocessing-expected.txt": [ - "046fc641d4288ee11e2a9ef0fc4f32096763cc65", + "7a92af0cf36e3b19e34d68271838d5220b824155", "support" ], "css/css-syntax/input-preprocessing.html": [ @@ -417098,10 +417181,6 @@ "772cc34f05bffc5b8445cd23ba13d9357269b84b", "reftest" ], - "css/cssom-view/offsetTopLeftInlineMultiLine.html": [ - "b93095c886165c69743f6d5e5c06f1079c06db5b", - "reftest" - ], "css/cssom-view/resources/elementsFromPoint.js": [ "ba986ef3f568d4971eb4e84c4faaeae6e276b975", "support" @@ -438510,10 +438589,6 @@ "c955e677899ed7fdb9028c4c3e0f39d54fbe2f80", "testharness" ], - "html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-noreferrer-expected.txt": [ - "9a42415d04b1d18f06ab58ddfd340786548d12d3", - "support" - ], "html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-noreferrer.html": [ "4807f634fdac8e3b82337efc2f6562074fb40a61", "testharness" @@ -438674,6 +438749,10 @@ "760bd418db8a8f59694b79d38e36287b9f2bb625", "testharness" ], + "html/browsers/the-window-object/noopener-noreferrer-BarProp.window.js": [ + "a75a0346501a80ceef91d25ed250a2957f42cfb9", + "testharness" + ], "html/browsers/the-window-object/security-window/window-security.https.html": [ "1fb0ed7c1e62da55b890c6434bee6e46637e0209", "testharness" @@ -438682,6 +438761,10 @@ "1b0fa1211a701253b61d1eced344faa8763ad6ef", "testharness" ], + "html/browsers/the-window-object/support/BarProp-target.html": [ + "9921e7a5773db8eef8d90f5956dbade3284609e6", + "support" + ], "html/browsers/the-window-object/support/closed.html": [ "3b70598e34d0e9b46a8ba2150a1589fecfb90ea8", "support" @@ -438726,10 +438809,6 @@ "a7eef5f1fcfce4ae448b7450b1a8ccbfa2eb0c12", "support" ], - "html/browsers/the-window-object/window-open-noreferrer-expected.txt": [ - "698c187031f6d821496a383f69e0376351f33e3b", - "support" - ], "html/browsers/the-window-object/window-open-noreferrer.html": [ "92b72cdb5f1ec07ad058ce5e25714130e6ceecfe", "testharness" @@ -449007,7 +449086,7 @@ "testharness" ], "html/semantics/embedded-content/the-img-element/relevant-mutations.html": [ - "0ce7a01078f793a2c6483319102ada6a33935534", + "76fdb641dffa96ce4340de2391450103e1d2bfbc", "testharness" ], "html/semantics/embedded-content/the-img-element/resources/cat.jpg": [ @@ -462346,6 +462425,38 @@ "0d9137dc6fb91b1499d922e01d6ad96049f5757b", "testharness" ], + "native-file-system/FileSystemBaseHandle-copyTo.tentative.window.js": [ + "2019024363ab5f4c17b3d8a8cef3eddf9008c948", + "testharness" + ], + "native-file-system/FileSystemBaseHandle-moveTo.tentative.window.js": [ + "3badce1ca9487fc3584674e101246e3b1c72787c", + "testharness" + ], + "native-file-system/FileSystemBaseHandle-remove.tentative.window.js": [ + "33ac96038829b249312f7463fc5c072b9f805825", + "testharness" + ], + "native-file-system/FileSystemDirectoryHandle-getDirectory.tentative.window.js": [ + "105879dbd1e0cc34cd10d6872d6299ba3fe00431", + "testharness" + ], + "native-file-system/FileSystemDirectoryHandle-getFile.tentative.window.js": [ + "0d9bacd87ee266b9b1637f66808244786c22ebde", + "testharness" + ], + "native-file-system/FileSystemWriter.tentative.window.js": [ + "cc8444237b6576f5425f74c0c3c5b12d0f644cd0", + "testharness" + ], + "native-file-system/README.md": [ + "6905a68e7901ce26bc1a363062304e1536604400", + "support" + ], + "native-file-system/resources/test-helpers.js": [ + "dc5f376233bd2de148d77a17cf2bcdbc4cc0c687", + "support" + ], "navigation-timing/META.yml": [ "c09a6e03fd19f5a405b391c2c4671df6ff04edf1", "support" @@ -481335,7 +481446,7 @@ "support" ], "resources/chromium/image_capture.mojom.js": [ - "bf8dd16ca75d4be1095808138d09a9c400159b86", + "50428ffcb80c736c1f63f8a91e0c65ff472ef463", "support" ], "resources/chromium/mock-barcodedetection.js": [ @@ -481479,7 +481590,7 @@ "support" ], "resources/testharness.js": [ - "d40817c7d4197ccc2469f646207b82d8a0af4c84", + "cb341db2050ee201a7646e1db22634682b05bc97", "support" ], "resources/testharness.js.headers": [ @@ -493899,7 +494010,7 @@ "support" ], "tools/wpt/utils.py": [ - "f98687feb5178b2f4f82f45951c4a4295407c74c", + "2d427713e4e824845b6d7871b61cd6f11ec251f6", "support" ], "tools/wpt/virtualenv.py": [ @@ -505019,7 +505130,7 @@ "support" ], "webxr/idlharness.https.window-expected.txt": [ - "2455866576303c29b3ec79bff4577e8e0fae58e7", + "969bdab40431a2aa75af6e56b6fce8ec9edcc398", "support" ], "webxr/idlharness.https.window.js": [ @@ -505067,19 +505178,23 @@ "testharness" ], "webxr/xrDevice_requestSession_immersive.https.html": [ - "c5956e7f3d12745638092558abb0b41749fb16d6", + "50a9d344541c8ce3b6bca11d1d5b30a52a835227", "testharness" ], "webxr/xrDevice_requestSession_immersive_no_gesture.https.html": [ - "c1b3286709d3a7d4dc45029253e3bbffb579e237", + "eb5a4fda0bdfc6e69cc9fbafa276d2ac85a2a16e", "testharness" ], "webxr/xrDevice_requestSession_immersive_unsupported.https.html": [ - "60e9e6cc6e1c0fa990af396e42418bb16984a5e8", + "2592f3a4a0d4b96b81ca2d3b0e2c43c06343c9aa", + "testharness" + ], + "webxr/xrDevice_requestSession_no_mode.https.html": [ + "c4ac3f6b6d77e9aab391069eb8895a28cb1c904a", "testharness" ], "webxr/xrDevice_requestSession_non_immersive_no_gesture.https.html": [ - "241b5ded0a50495cf21b2b5c78aee8327f384a62", + "40e6f4928b3f63c9c6e4bd71d40022e86dbf4bec", "testharness" ], "webxr/xrDevice_supportsSession_immersive.https.html": [ @@ -505095,11 +505210,11 @@ "testharness" ], "webxr/xrFrame_getPose.https.html": [ - "2c75275a1120e8715975ba3839de882b3c21ecae", + "a8015e3276acc3f97cced60c964d92c752a25d24", "testharness" ], "webxr/xrFrame_lifetime.https.html": [ - "30cf5f996773b9c278370c3ae7df086574d3b72d", + "b924c89771e89457966f0f2d3a8e8e4408376a10", "testharness" ], "webxr/xrRay_constructor.https.html": [ @@ -505111,11 +505226,11 @@ "testharness" ], "webxr/xrRigidTransform_constructor.https.html": [ - "abaf8bf9ebe2fed3c99cef5bf52d697b9e8ed1c8", + "15666973473abbf722fdd3bc8e90d679a36b8732", "testharness" ], "webxr/xrRigidTransform_inverse.https.html": [ - "e795a99538e27d7a85a75c652b9b972d119e91d6", + "da34fec60f00c15fe814e64b918e4a30d9716f70", "testharness" ], "webxr/xrRigidTransform_matrix.https.html": [ @@ -505123,47 +505238,47 @@ "testharness" ], "webxr/xrSession_cancelAnimationFrame.https.html": [ - "cc7b8802cba01ac03adb53a06308acd5642dd0af", + "d45349ad24464ef424e411cae0d059fbbb33d570", "testharness" ], "webxr/xrSession_cancelAnimationFrame_invalidhandle.https.html": [ - "e6a9c0665435034fdf493e9ab2d4c8a6731eff13", + "b93f4e27909efa888793a85f4529d8da7bf0546c", "testharness" ], "webxr/xrSession_end.https.html": [ - "6365c7de508a426f674ae239d99846d77af94615", + "26b6b47d2bfeea35249bd36ca49fda1d5b2ec1f8", "testharness" ], "webxr/xrSession_identity_referenceSpace.https.html": [ - "fb18edf6ddd4369887599617a5577de65a126b33", + "07abc39728c0453668a4fbdc785a9194a2dfb7a0", "testharness" ], "webxr/xrSession_mode.https.html": [ - "4b54d9480211b3641997f78a61dfdc7058592ecd", + "a1d066084393742559a020cb6e71277740793db7", "testharness" ], "webxr/xrSession_prevent_multiple_exclusive.https.html": [ - "c2e7f3bf444d38506f6a54c2cf9904c2927b2ad5", + "e61bd392718ae3b0f8ac8de0fa81604f2d32dcce", "testharness" ], "webxr/xrSession_requestAnimationFrame_callback_calls.https.html": [ - "92f7d1f79dcb61e400e21e4f5a80a85e3685ec9f", + "2ed468bc3a5a44c1653de6bdb3716d8de4078167", "testharness" ], "webxr/xrSession_requestAnimationFrame_data_valid.https.html": [ - "2278666a1d7cfc43362b5e09ddf0df25fef42681", + "44e903e4fb980d672ad6580f2d630874fa9c4b72", "testharness" ], "webxr/xrSession_requestAnimationFrame_getViewerPose.https.html": [ - "8c8e26aa12db1c35e67be8928c4e5f9836a5b5e0", + "5606fa1ab12b1f359de4e88bdf703b5835be2c16", "testharness" ], "webxr/xrSession_requestReferenceSpace.https.html": [ - "ed31f372ceb2b6c3cbfd34da47cdb801b4f366fc", + "0027d5dce01af7499e1037311c27ad29f66328d1", "testharness" ], "webxr/xrSession_transfer_outputContext.https.html": [ - "658cb322487df1af1f2333423ac8c223fdd8733c", + "759d97ba184067f0f4df431500f5eabddd788921", "testharness" ], "workers/META.yml": [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/scroll-snap-stop-always.html b/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/scroll-snap-stop-always.html index 62446f5..7d2a228 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/scroll-snap-stop-always.html +++ b/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/scroll-snap-stop-always.html
@@ -68,4 +68,29 @@ assert_equals(scroller.scrollTop, 0); }, "A scroll with intended end position should always choose the closest snap " + "position regardless of the scroll-snap-stop value.") + +// Tests for programmatic scrolls beyond the scroller bounds. + +test(() => { + scroller.scrollTo(0, 0); + assert_equals(scroller.scrollLeft, 0); + assert_equals(scroller.scrollTop, 0); + + scroller.scrollBy(100000, 0); + assert_equals(scroller.scrollLeft, 100); + assert_equals(scroller.scrollTop, 0); +}, "A scroll outside bounds in the snapping axis with intended direction and " + + "end position should not pass a snap area with scroll-snap-stop: always.") + +test(() => { + scroller.scrollTo(0, 0); + assert_equals(scroller.scrollLeft, 0); + assert_equals(scroller.scrollTop, 0); + + scroller.scrollBy(300, -10); + assert_equals(scroller.scrollLeft, 100); + assert_equals(scroller.scrollTop, 0); +}, "A scroll outside bounds in the non-snapping axis with intended direction " + + "and end position should not pass a snap area with scroll-snap-stop: always.") + </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/scrollTo-scrollBy-snaps.html b/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/scrollTo-scrollBy-snaps.html index 3e022f0a..fba38cb 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/scrollTo-scrollBy-snaps.html +++ b/third_party/blink/web_tests/external/wpt/css/css-scroll-snap/scrollTo-scrollBy-snaps.html
@@ -74,7 +74,9 @@ [ [{left: 800}, 1000, 0], [{top: 900}, 0, 1000], - [{left: 900, top: 800}, 1000, 1000] + [{left: 900, top: 800}, 1000, 1000], + [{left: 800, top: -100}, 1000, 0], /* outside bounds on y axis */ + [{left: 10000, top: -100}, 1000, 0] /* outside bounds on both axes */ ].forEach(([input, expectedX, expectedY]) => { test(() => { divScroller.scrollTo(0, 0);
diff --git a/third_party/blink/web_tests/external/wpt/css/css-syntax/input-preprocessing-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-syntax/input-preprocessing-expected.txt index 046fc64..7a92af0 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-syntax/input-preprocessing-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-syntax/input-preprocessing-expected.txt
@@ -4,10 +4,10 @@ PASS "\0foo" becomes "�foo" PASS "\0" becomes "�" PASS "\0\0\0" becomes "���" -FAIL "fooí " becomes "foo�" assert_equals: expected "foo\ufffd" but got "fooí " -FAIL "fí oo" becomes "f�oo" assert_equals: expected "f\ufffdoo" but got "fí oo" -FAIL "í foo" becomes "�foo" assert_equals: expected "\ufffdfoo" but got "í foo" -FAIL "í " becomes "�" assert_equals: expected "\ufffd" but got "í " -FAIL "í í í " becomes "���" assert_equals: expected "\ufffd\ufffd\ufffd" but got "í í í " +FAIL "fooU+d800" becomes "foo�" assert_equals: expected "foo\ufffd" but got "fooí " +FAIL "fU+d800oo" becomes "f�oo" assert_equals: expected "f\ufffdoo" but got "fí oo" +FAIL "U+d800foo" becomes "�foo" assert_equals: expected "\ufffdfoo" but got "í foo" +FAIL "U+d800" becomes "�" assert_equals: expected "\ufffd" but got "í " +FAIL "U+d800U+d800U+d800" becomes "���" assert_equals: expected "\ufffd\ufffd\ufffd" but got "í í í " Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom-view/offsetTopLeftEmptyInline.html b/third_party/blink/web_tests/external/wpt/css/cssom-view/offsetTopLeft-empty-inline-offset.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/cssom-view/offsetTopLeftEmptyInline.html rename to third_party/blink/web_tests/external/wpt/css/cssom-view/offsetTopLeft-empty-inline-offset.html
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom-view/offsetTopLeft-empty-inline.html b/third_party/blink/web_tests/external/wpt/css/cssom-view/offsetTopLeft-empty-inline.html new file mode 100644 index 0000000..d553cb1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/cssom-view/offsetTopLeft-empty-inline.html
@@ -0,0 +1,32 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/cssom-view-1/#extensions-to-the-htmlelement-interface"> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<style> + .container { + position: relative; + width: 8em; + height: 7em; + padding: 1em; + } +</style> +<div class="container" style="writing-mode:horizontal-tb;"> + <br><span class="target"></span><span>ref</span> +</div> +<div class="container" style="writing-mode:vertical-lr;"> + <br><span class="target"></span><span>ref</span> +</div> +<div class="container" style="writing-mode:vertical-rl;"> + <br><span class="target"></span><span>ref</span> +</div> +<script> +var i = 0; +document.querySelectorAll('span.target').forEach((target) => { + var ref = target.nextSibling; + test(() => { + assert_equals(target.offsetLeft, ref.offsetLeft, 'offsetLeft'); + assert_equals(target.offsetTop, ref.offsetTop, 'offsetTop'); + }, 'offsetTop/Left of empty inline elements should work as if they were not empty: ' + i); + i++; +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom-view/offsetTopLeftInline.html b/third_party/blink/web_tests/external/wpt/css/cssom-view/offsetTopLeft-inline.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/css/cssom-view/offsetTopLeftInline.html rename to third_party/blink/web_tests/external/wpt/css/cssom-view/offsetTopLeft-inline.html
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom-view/offsetTopLeft-leading-space-inline.html b/third_party/blink/web_tests/external/wpt/css/cssom-view/offsetTopLeft-leading-space-inline.html new file mode 100644 index 0000000..a121cdf8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/cssom-view/offsetTopLeft-leading-space-inline.html
@@ -0,0 +1,32 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/cssom-view-1/#extensions-to-the-htmlelement-interface"> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<style> + .container { + position: relative; + width: 8em; + height: 7em; + padding: 1em; + } +</style> +<div class="container" style="writing-mode:horizontal-tb;"> + <br><span class="target"> </span><span>ref</span> +</div> +<div class="container" style="writing-mode:vertical-lr;"> + <br><span class="target"> </span><span>ref</span> +</div> +<div class="container" style="writing-mode:vertical-rl;"> + <br><span class="target"> </span><span>ref</span> +</div> +<script> +var i = 0; +document.querySelectorAll('span.target').forEach((target) => { + var ref = target.nextSibling; + test(() => { + assert_equals(target.offsetLeft, ref.offsetLeft, 'offsetLeft'); + assert_equals(target.offsetTop, ref.offsetTop, 'offsetTop'); + }, 'offsetTop/Left of empty inline elements should work as if they were not empty: ' + i); + i++; +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom-view/offsetTopLeft-trailing-space-inline.html b/third_party/blink/web_tests/external/wpt/css/cssom-view/offsetTopLeft-trailing-space-inline.html new file mode 100644 index 0000000..3e50b78 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/cssom-view/offsetTopLeft-trailing-space-inline.html
@@ -0,0 +1,36 @@ +<!DOCTYPE html> +<link rel="help" href="https://drafts.csswg.org/cssom-view-1/#extensions-to-the-htmlelement-interface"> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<style> + .container { + position: relative; + width: 8em; + height: 7em; + padding: 1em; + } +</style> +<div class="container" style="writing-mode:horizontal-tb;"> + <br><span>ref</span><span class="target"> </span> +</div> +<div class="container" style="writing-mode:vertical-lr;"> + <br><span>ref</span><span class="target"> </span> +</div> +<div class="container" style="writing-mode:vertical-rl;"> + <br><span>ref</span><span class="target"> </span> +</div> +<script> +var i = 0; +document.querySelectorAll('span.target').forEach((target) => { + var ref = target.previousSibling; + test(() => { + assert_equals(target.offsetLeft, + ref.offsetLeft + (i ? 0 : ref.offsetWidth), + 'offsetLeft'); + assert_equals(target.offsetTop, + ref.offsetTop + (i ? ref.offsetHeight : 0), + 'offsetTop'); + }, 'offsetTop/Left of empty inline elements should work as if they were not empty: ' + i); + i++; +}); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-noreferrer-expected.txt b/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-noreferrer-expected.txt deleted file mode 100644 index 9a42415d..0000000 --- a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-noreferrer-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -This is a testharness.js-based test. -FAIL Tokenization of "noreferrer" should skip window features separators before feature assert_equals: " noreferrer" should activate feature "noreferrer" expected null but got object "[object Window]" -FAIL Feature "noreferrer" should be converted to ASCII lowercase assert_equals: "NOREFERRER" should activate feature "noreferrer" expected null but got object "[object Window]" -FAIL After "noreferrer", tokenization should skip window features separators that are not "=" or "," assert_equals: "noreferrer" should activate feature "noreferrer" expected null but got object "[object Window]" -FAIL Tokenizing "noreferrer" should ignore window feature separators except "," after initial "=" and before value assert_equals: "noreferrer= yes" should activate feature "noreferrer" expected null but got object "[object Window]" -FAIL Tokenizing "noreferrer" should read characters until first window feature separator as `value` assert_equals: "noreferrer=1" should set "noreferrer" expected null but got object "[object Window]" -FAIL Integer values other than 0 should activate the feature assert_equals: "noreferrer=1" should activate feature "noreferrer" expected null but got object "[object Window]" -PASS Integer value of 0 should not activate "noreferrer" -PASS Invalid feature names should not tokenize as "noreferrer" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/noopener-noreferrer-BarProp.window.js b/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/noopener-noreferrer-BarProp.window.js new file mode 100644 index 0000000..a75a0346 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/noopener-noreferrer-BarProp.window.js
@@ -0,0 +1,23 @@ +const barProps = ["locationbar", "menubar", "personalbar", "scrollbars", "statusbar", "toolbar"]; + +test(() => { + for(const prop of barProps) { + assert_true(window[prop].visible); + } +}, "All bars visible"); + +["noopener", "noreferrer"].forEach(openerStyle => { + async_test(t => { + const channelName = "5454" + openerStyle + "34324"; + const channel = new BroadcastChannel(channelName); + window.open("support/BarProp-target.html?" + channelName, "", openerStyle); + channel.onmessage = t.step_func_done(e => { + // Send message first so if asserts throw the popup is still closed + channel.postMessage(null); + + for(const prop of barProps) { + assert_true(e.data[prop]); + } + }); + }, `window.open() with ${openerStyle} should have all bars visible`); +});
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/support/BarProp-target.html b/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/support/BarProp-target.html new file mode 100644 index 0000000..9921e7a5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/support/BarProp-target.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<script> + const barProps = ["locationbar", "menubar", "personalbar", "scrollbars", "statusbar", "toolbar"]; + const barPropsObj = {}; + const channelName = location.search.substr(1); + const channel = new BroadcastChannel(channelName); + for (const prop of barProps) { + barPropsObj[prop] = window[prop].visible; + } + channel.postMessage(barPropsObj); + + // Because messages are not delivered synchronously and because closing a + // browsing context prompts the eventual clearing of all task sources, this + // document should not be closed until the opener document has confirmed + // receipt. + channel.onmessage = () => { window.close() }; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/window-open-noreferrer-expected.txt b/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/window-open-noreferrer-expected.txt deleted file mode 100644 index 698c18703..0000000 --- a/third_party/blink/web_tests/external/wpt/html/browsers/the-window-object/window-open-noreferrer-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL window.open() with "noreferrer" tests assert_equals: expected "" but got "http://web-platform.test:8001/html/browsers/the-window-object/window-open-noreferrer.html" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/relevant-mutations.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/relevant-mutations.html index 0ce7a010..76fdb641 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/relevant-mutations.html +++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/relevant-mutations.html
@@ -21,16 +21,27 @@ <img src="/images/green-2x2.png" data-desc="src set to same value"> -<img data-desc="crossorigin absent to empty"> -<img data-desc="crossorigin absent to anonymous"> -<img data-desc="crossorigin absent to use-credentials"> -<img crossorigin data-desc="crossorigin empty to absent"> -<img crossorigin data-desc="crossorigin empty to use-credentials"> -<img crossorigin=anonymous data-desc="crossorigin anonymous to absent"> -<img crossorigin=anonymous data-desc="crossorigin anonymous to use-credentials"> -<img crossorigin=use-credentials data-desc="crossorigin use-credentials to absent"> -<img crossorigin=use-credentials data-desc="crossorigin use-credentials to empty"> -<img crossorigin=use-credentials data-desc="crossorigin use-credentials to anonymous"> +<img data-desc="crossorigin absent to empty, src absent"> +<img data-desc="crossorigin absent to anonymous, src absent"> +<img data-desc="crossorigin absent to use-credentials, src absent"> +<img crossorigin data-desc="crossorigin empty to absent, src absent"> +<img crossorigin data-desc="crossorigin empty to use-credentials, src absent"> +<img crossorigin=anonymous data-desc="crossorigin anonymous to absent, src absent"> +<img crossorigin=anonymous data-desc="crossorigin anonymous to use-credentials, src absent"> +<img crossorigin=use-credentials data-desc="crossorigin use-credentials to absent, src absent"> +<img crossorigin=use-credentials data-desc="crossorigin use-credentials to empty, src absent"> +<img crossorigin=use-credentials data-desc="crossorigin use-credentials to anonymous, src absent"> + +<img src="/images/green-2x2.png" data-desc="crossorigin absent to empty, src already set"> +<img src="/images/green-2x2.png" data-desc="crossorigin absent to anonymous, src already set"> +<img src="/images/green-2x2.png" data-desc="crossorigin absent to use-credentials, src already set"> +<img src="/images/green-2x2.png" crossorigin data-desc="crossorigin empty to absent, src already set"> +<img src="/images/green-2x2.png" crossorigin data-desc="crossorigin empty to use-credentials, src already set"> +<img src="/images/green-2x2.png" crossorigin=anonymous data-desc="crossorigin anonymous to absent, src already set"> +<img src="/images/green-2x2.png" crossorigin=anonymous data-desc="crossorigin anonymous to use-credentials, src already set"> +<img src="/images/green-2x2.png" crossorigin=use-credentials data-desc="crossorigin use-credentials to absent, src already set"> +<img src="/images/green-2x2.png" crossorigin=use-credentials data-desc="crossorigin use-credentials to empty, src already set"> +<img src="/images/green-2x2.png" crossorigin=use-credentials data-desc="crossorigin use-credentials to anonymous, src already set"> <img src="/images/green-2x2.png" data-desc="inserted into picture"><picture></picture> @@ -165,46 +176,92 @@ img.src = '/images/green-2x2.png'; }, 'load'); - t('crossorigin absent to empty', function(img) { + // When src is absent, changing the crossorigin attribute state MUST NOT + // generate events. + + t('crossorigin absent to empty, src absent', function(img) { img.crossOrigin = ''; }, 'timeout'); - t('crossorigin absent to anonymous', function(img) { + t('crossorigin absent to anonymous, src absent', function(img) { img.crossOrigin = 'anonymous'; }, 'timeout'); - t('crossorigin absent to use-credentials', function(img) { + t('crossorigin absent to use-credentials, src absent', function(img) { img.crossOrigin = 'use-credentials'; }, 'timeout'); - t('crossorigin empty to absent', function(img) { + t('crossorigin empty to absent, src absent', function(img) { img.removeAttribute('crossorigin'); }, 'timeout'); - t('crossorigin empty to use-credentials', function(img) { + t('crossorigin empty to use-credentials, src absent', function(img) { img.crossOrigin = 'use-credentials'; }, 'timeout'); - t('crossorigin anonymous to absent', function(img) { + t('crossorigin anonymous to absent, src absent', function(img) { img.removeAttribute('crossorigin'); }, 'timeout'); - t('crossorigin anonymous to use-credentials', function(img) { + t('crossorigin anonymous to use-credentials, src absent', function(img) { img.crossOrigin = 'use-credentials'; }, 'timeout'); - t('crossorigin use-credentials to absent', function(img) { + t('crossorigin use-credentials to absent, src absent', function(img) { img.removeAttribute('crossorigin'); }, 'timeout'); - t('crossorigin use-credentials to empty', function(img) { + t('crossorigin use-credentials to empty, src absent', function(img) { img.crossOrigin = ''; }, 'timeout'); - t('crossorigin use-credentials to anonymous', function(img) { + t('crossorigin use-credentials to anonymous, src absent', function(img) { img.crossOrigin = 'anonymous'; }, 'timeout'); + // When src is set, changing the crossorigin attribute state MUST generate + // events. + + t('crossorigin absent to empty, src already set', function(img) { + img.crossOrigin = ''; + }, 'load'); + + t('crossorigin absent to anonymous, src already set', function(img) { + img.crossOrigin = 'anonymous'; + }, 'load'); + + t('crossorigin absent to use-credentials, src already set', function(img) { + img.crossOrigin = 'use-credentials'; + }, 'load'); + + t('crossorigin empty to absent, src already set', function(img) { + img.removeAttribute('crossorigin'); + }, 'load'); + + t('crossorigin empty to use-credentials, src already set', function(img) { + img.crossOrigin = 'use-credentials'; + }, 'load'); + + t('crossorigin anonymous to absent, src already set', function(img) { + img.removeAttribute('crossorigin'); + }, 'load'); + + t('crossorigin anonymous to use-credentials, src already set', function(img) { + img.crossOrigin = 'use-credentials'; + }, 'load'); + + t('crossorigin use-credentials to absent, src already set', function(img) { + img.removeAttribute('crossorigin'); + }, 'load'); + + t('crossorigin use-credentials to empty, src already set', function(img) { + img.crossOrigin = ''; + }, 'load'); + + t('crossorigin use-credentials to anonymous, src already set', function(img) { + img.crossOrigin = 'anonymous'; + }, 'load'); + t('inserted into picture', function(img) { img.nextSibling.appendChild(img); }, 'load');
diff --git a/third_party/blink/web_tests/external/wpt/resources/testharness.js b/third_party/blink/web_tests/external/wpt/resources/testharness.js index d40817c..cb341db2 100644 --- a/third_party/blink/web_tests/external/wpt/resources/testharness.js +++ b/third_party/blink/web_tests/external/wpt/resources/testharness.js
@@ -2383,6 +2383,42 @@ return duplicates; }; + function code_unit_str(char) { + return 'U+' + char.charCodeAt(0).toString(16); + } + + function sanitize_unpaired_surrogates(str) { + return str.replace(/([\ud800-\udbff])(?![\udc00-\udfff])/g, + function(_, unpaired) + { + return code_unit_str(unpaired); + }) + // This replacement is intentionally implemented without an + // ES2018 negative lookbehind assertion to support runtimes + // which do not yet implement that language feature. + .replace(/(^|[^\ud800-\udbff])([\udc00-\udfff])/g, + function(_, previous, unpaired) { + if (/[\udc00-\udfff]/.test(previous)) { + previous = code_unit_str(previous); + } + + return previous + code_unit_str(unpaired); + }); + } + + function sanitize_all_unpaired_surrogates(tests) { + forEach (tests, + function (test) + { + var sanitized = sanitize_unpaired_surrogates(test.name); + + if (test.name !== sanitized) { + test.name = sanitized; + delete test._structured_clone; + } + }); + } + Tests.prototype.notify_complete = function() { var this_obj = this; var duplicates; @@ -2390,6 +2426,11 @@ if (this.status.status === null) { duplicates = this.find_duplicates(); + // Some transports adhere to UTF-8's restriction on unpaired + // surrogates. Sanitize the titles so that the results can be + // consistently sent via all transports. + sanitize_all_unpaired_surrogates(this.tests); + // Test names are presumed to be unique within test files--this // allows consumers to use them for identification purposes. // Duplicated names violate this expectation and should therefore
diff --git a/third_party/blink/web_tests/external/wpt/tools/wpt/utils.py b/third_party/blink/web_tests/external/wpt/tools/wpt/utils.py index f98687f..2d427713 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wpt/utils.py +++ b/third_party/blink/web_tests/external/wpt/tools/wpt/utils.py
@@ -6,7 +6,7 @@ from io import BytesIO try: - from typing import Any + from typing import Any, Callable except ImportError: pass @@ -17,10 +17,11 @@ def set_if_none(self, name, # type: str value, # type: Any - err_fn=None, # type: (Kwargs, str) -> Any + err_fn=None, # type: Callable[[Kwargs, str], Any] desc=None, # type: str - extra_cond=None # type: (Kwargs) -> bool + extra_cond=None # type: Callable[[Kwargs], Any] ): + # type: (...) -> Any if desc is None: desc = name
diff --git a/third_party/blink/web_tests/fast/dom/shadow/touch-event.html b/third_party/blink/web_tests/fast/dom/shadow/touch-event.html index d918a8ac..3e935a3 100644 --- a/third_party/blink/web_tests/fast/dom/shadow/touch-event.html +++ b/third_party/blink/web_tests/fast/dom/shadow/touch-event.html
@@ -7,7 +7,7 @@ <div id="container"> <input id="input1" type="text"> - <div id="host1"></div> + <div id="host1" style="margin-top:10px;"></div> </div> <pre id="console"></pre>
diff --git a/third_party/blink/web_tests/fast/events/hit-test-counts-expected.txt b/third_party/blink/web_tests/fast/events/hit-test-counts-expected.txt index f894bd5..c3fcc663 100644 --- a/third_party/blink/web_tests/fast/events/hit-test-counts-expected.txt +++ b/third_party/blink/web_tests/fast/events/hit-test-counts-expected.txt
@@ -27,7 +27,7 @@ GestureTapCancel: 0+1 GestureScrollUpdate: 0+0 GestureScrollEnd: 0+0 -DoubleFingerTouch: 2+0 +DoubleFingerTouch: 3+0 Event entirely over one iframe nested in another --------------------- @@ -46,7 +46,7 @@ GestureTapCancel: 1+0 1+0 0+1 GestureScrollUpdate: 0+0 0+0 0+0 GestureScrollEnd: 0+0 0+0 0+0 -DoubleFingerTouch: 2+0 2+0 2+0 +DoubleFingerTouch: 3+0 3+0 3+0 Event near boundary of two iframes --------------------- @@ -65,7 +65,7 @@ GestureTapCancel: 1+0 0+1 0+0 GestureScrollUpdate: 0+0 0+0 0+0 GestureScrollEnd: 0+0 0+0 0+0 -DoubleFingerTouch: 2+0 2+0 1+0 +DoubleFingerTouch: 3+0 3+0 2+0 Event on a simple div (desktop viewport) --------------------- @@ -84,7 +84,7 @@ GestureTapCancel: 0+1 GestureScrollUpdate: 0+0 GestureScrollEnd: 0+0 -DoubleFingerTouch: 2+0 +DoubleFingerTouch: 3+0 PASS successfullyParsed is true
diff --git a/third_party/blink/web_tests/fast/events/hit-test-counts.html b/third_party/blink/web_tests/fast/events/hit-test-counts.html index f782d70..23725a58a 100644 --- a/third_party/blink/web_tests/fast/events/hit-test-counts.html +++ b/third_party/blink/web_tests/fast/events/hit-test-counts.html
@@ -152,9 +152,9 @@ }); logCounts('DoubleFingerTouch', documents, multiTapNotification, function() { - eventSender.addTouchPoint(targetX+1, targetY+1); + eventSender.addTouchPoint(targetX+1, targetY+1, 15, 15); eventSender.touchStart(); - eventSender.addTouchPoint(targetX+4, targetY+4); + eventSender.addTouchPoint(targetX+4, targetY+4, 15, 15); eventSender.touchStart(); eventSender.releaseTouchPoint(0); eventSender.releaseTouchPoint(1);
diff --git a/third_party/blink/web_tests/fast/mediastream/MediaStreamTrack-getCapabilities.html b/third_party/blink/web_tests/fast/mediastream/MediaStreamTrack-getCapabilities.html index 6536ebde..0f58a3b 100644 --- a/third_party/blink/web_tests/fast/mediastream/MediaStreamTrack-getCapabilities.html +++ b/third_party/blink/web_tests/fast/mediastream/MediaStreamTrack-getCapabilities.html
@@ -6,7 +6,7 @@ return navigator.mediaDevices.getUserMedia({audio: true}) .then(function(stream) { var capabilities = stream.getAudioTracks()[0].getCapabilities(); - assert_equals(Object.keys(capabilities).length, 10); + assert_equals(Object.keys(capabilities).length, 9); assert_true(capabilities.hasOwnProperty('deviceId')); assert_true(capabilities.hasOwnProperty('groupId')); assert_true(capabilities.hasOwnProperty('sampleSize')); @@ -35,7 +35,7 @@ test(function() { var stream = (new AudioContext()).createMediaStreamDestination().stream; var capabilities = stream.getAudioTracks()[0].getCapabilities(); - assert_equals(Object.keys(capabilities).length, 6); + assert_equals(Object.keys(capabilities).length, 5); assert_true(capabilities.hasOwnProperty('deviceId')); assert_true(capabilities.hasOwnProperty('sampleSize')); verifyAudioProcessingProperties(capabilities, false); @@ -63,7 +63,7 @@ var stream = video.captureStream(); var audioCapabilities = stream.getAudioTracks()[0].getCapabilities(); var videoCapabilities = stream.getVideoTracks()[0].getCapabilities(); - assert_equals(Object.keys(audioCapabilities).length, 6); + assert_equals(Object.keys(audioCapabilities).length, 5); assert_true(audioCapabilities.hasOwnProperty('deviceId')); assert_true(audioCapabilities.hasOwnProperty('sampleSize')); verifyAudioProcessingProperties(audioCapabilities, false); @@ -89,7 +89,7 @@ var remoteStream = callee.getRemoteStreams()[0]; var audioCapabilities = remoteStream.getAudioTracks()[0].getCapabilities(); var videoCapabilities = remoteStream.getVideoTracks()[0].getCapabilities(); - assert_equals(Object.keys(audioCapabilities).length, 6); + assert_equals(Object.keys(audioCapabilities).length, 5); assert_true(audioCapabilities.hasOwnProperty('deviceId')); assert_true(audioCapabilities.hasOwnProperty('sampleSize')); verifyAudioProcessingProperties(audioCapabilities, false); @@ -117,19 +117,6 @@ function verifyAudioProcessingProperties(capabilities, is_get_user_media) { assert_true(capabilities.hasOwnProperty('echoCancellation')); assert_equals(Object.keys(capabilities.echoCancellation).length, is_get_user_media ? 2 : 1); - - assert_true(capabilities.hasOwnProperty('echoCancellationType')); - var ec_type_length = Object.keys(capabilities.echoCancellationType).length; - if (is_get_user_media) { - assert_true(ec_type_length == 1 || ec_type_length == 2); - if (ec_type_length == 1) { - assert_true(capabilities.echoCancellationType[0] == 'browser'); - } else { - assert_true(capabilities.echoCancellationType[0] == 'browser' || capabilities.echoCancellationType[1] == 'browser'); - } - } else { - assert_equals(ec_type_length, 0); - } assert_true(capabilities.hasOwnProperty('autoGainControl')); assert_equals(Object.keys(capabilities.autoGainControl).length, is_get_user_media ? 2 : 1); assert_true(capabilities.hasOwnProperty('noiseSuppression'));
diff --git a/third_party/blink/web_tests/fast/mediastream/MediaStreamTrack-getSettings.html b/third_party/blink/web_tests/fast/mediastream/MediaStreamTrack-getSettings.html index da405fe..cb319f58 100644 --- a/third_party/blink/web_tests/fast/mediastream/MediaStreamTrack-getSettings.html +++ b/third_party/blink/web_tests/fast/mediastream/MediaStreamTrack-getSettings.html
@@ -32,10 +32,6 @@ 'Automatic gain control missing: ' + JSON.stringify(settings)); assert_true('noiseSuppression' in settings, 'Noise suppression missing: ' + JSON.stringify(settings)); - assert_true('echoCancellationType' in settings, - 'Echo cancellation type missing: ' + JSON.stringify(settings)); - assert_in_array(settings.echoCancellationType, [ "browser", "system" ], - 'Echo cancellation type invalid: ' + JSON.stringify(settings)); }); }, 'An audio track returns the expected variables');
diff --git a/third_party/blink/web_tests/fast/scroll-snap/animate-fling-to-snap-points.html b/third_party/blink/web_tests/fast/scroll-snap/animate-fling-to-snap-points.html index 711489a..77d48847 100644 --- a/third_party/blink/web_tests/fast/scroll-snap/animate-fling-to-snap-points.html +++ b/third_party/blink/web_tests/fast/scroll-snap/animate-fling-to-snap-points.html
@@ -45,21 +45,39 @@ scroller.scrollTo(0, 0); await smoothScroll(100, 200, 200, GestureSourceType.TOUCH_INPUT, 'downright', SPEED_INSTANT); await waitForAnimationEnd(scrollLeft, 700, 10); - await waitFor( () => { - return approx_equals(scroller.scrollLeft, 80, 1) && - approx_equals(scroller.scrollTop, 80, 1); - }); + assert_approx_equals(scroller.scrollLeft, 80, 1); + assert_approx_equals(scroller.scrollTop, 80, 1); }, "Without fling enabled, the scroll ends at the closest snap point to the scroll destination."); promise_test (async () => { scroller.scrollTo(0, 0); await swipe(100, 200, 200, 'upleft', 900); await waitForAnimationEnd(scrollLeft, 1000, 30); - await waitFor( () => { - return approx_equals(scroller.scrollLeft, 200, 1) && - approx_equals(scroller.scrollTop, 200, 1); - }); -}, "With fling enabled, the scroll ends at the closest snap point to the fling destination.") + assert_approx_equals(scroller.scrollLeft, 200, 1); + assert_approx_equals(scroller.scrollTop, 200, 1); +}, "Fling scroll ends at the closest snap point to the fling destination.") + +promise_test (async () => { + scroller.scrollTo(0, 0); + // Scroll horizontally to (100, 0) with momentum. + await swipe(100, 200, 200, 'left', 900); + await waitForAnimationEnd(scrollLeft, 1000, 30); + assert_approx_equals(scroller.scrollLeft, 200, 1); + assert_approx_equals(scroller.scrollTop, 0, 1); +}, "Fling scroll in one direction ends at closest snap point to the fling destination."); + +promise_test (async () => { + scroller.scrollTo(0, 0); + // Scroll right and up. Going up vertically is not possible since it is outside the bound. The + // expectation in this case is to snap as if user scrolled horizontally to (100, 0) with + // momentun. + await swipe(100, 200, 200, 'downleft', 900); + await waitForAnimationEnd(scrollLeft, 1000, 30); + assert_approx_equals(scroller.scrollLeft, 200, 1); + // TODO(823998): Scroll top may land either at 0px or 80px which are both valid snap targets. + // My expectation was that it would be at 0. Needs more investigation to deflake. + // assert_approx_equals(scroller.scrollTop, 0, 1); +}, "Fling scroll that goes outside the boundary ends at the closest snap point to the fling destination."); function MakeUnscrollable() { scroller.removeChild(space);
diff --git a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-microtasks-expected.txt b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-microtasks-expected.txt index 95bb9c82..0a23e26 100644 --- a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-microtasks-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-microtasks-expected.txt
@@ -1,4 +1,4 @@ -Checks the RunMicrotasks event is emitted. +Checks the RunMicrotasks event is emitted and nested into RunTask. RunMicrotasks Properties: { @@ -9,4 +9,5 @@ startTime : <number> type : "RunMicrotasks" } +Microtask event is nested into Task event: true
diff --git a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-microtasks.js b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-microtasks.js index ecc6381f..e681701 100644 --- a/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-microtasks.js +++ b/third_party/blink/web_tests/http/tests/devtools/tracing/timeline-js/timeline-microtasks.js
@@ -3,7 +3,7 @@ // found in the LICENSE file. (async function() { - TestRunner.addResult(`Checks the RunMicrotasks event is emitted.\n`); + TestRunner.addResult(`Checks the RunMicrotasks event is emitted and nested into RunTask.\n`); await TestRunner.loadModule('performance_test_runner'); await TestRunner.showPanel('timeline'); await TestRunner.evaluateInPagePromise(` @@ -27,8 +27,15 @@ `); await PerformanceTestRunner.invokeAsyncWithTimeline('performActions'); - const event = PerformanceTestRunner.mainTrackEvents().find( + + const microTaskEvent = PerformanceTestRunner.mainTrackEvents().find( e => e.name === TimelineModel.TimelineModel.RecordType.RunMicrotasks); - PerformanceTestRunner.printTraceEventProperties(event); + PerformanceTestRunner.printTraceEventProperties(microTaskEvent); + const nested = PerformanceTestRunner.mainTrackEvents() + .filter(e => e.name === TimelineModel.TimelineModel.RecordType.Task) + .some(e => e.startTime <= microTaskEvent.startTime && microTaskEvent.endTime <= e.endTime); + + TestRunner.addResult(`Microtask event is nested into Task event: ${nested}`); + TestRunner.completeTest(); })();
diff --git a/third_party/blink/web_tests/virtual/outofblink-cors/external/wpt/fetch/sec-metadata/prefetch.tentative.https.sub-expected.txt b/third_party/blink/web_tests/virtual/outofblink-cors/external/wpt/fetch/sec-metadata/prefetch.tentative.https.sub-expected.txt deleted file mode 100644 index 35b7a194..0000000 --- a/third_party/blink/web_tests/virtual/outofblink-cors/external/wpt/fetch/sec-metadata/prefetch.tentative.https.sub-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ -This is a testharness.js-based test. -PASS Browser supports prefetch. -PASS <link rel='prefetch' href='https://web-platform.test:8444/...'> -FAIL <link rel='prefetch' href='https://www.web-platform.test:8444/...'> assert_unreached: Reached unreachable code -FAIL <link rel='prefetch' href='https://www.not-web-platform.test:8444/...'> assert_unreached: Reached unreachable code -Harness: the test ran to completion. -
diff --git a/third_party/crashpad/README.chromium b/third_party/crashpad/README.chromium index 9534547..0b22c6cc 100644 --- a/third_party/crashpad/README.chromium +++ b/third_party/crashpad/README.chromium
@@ -2,7 +2,7 @@ Short Name: crashpad URL: https://crashpad.chromium.org/ Version: unknown -Revision: cc0c2f90df7e1abbd37efb86563a5458fcc305ea +Revision: a7859e9bc63e54e972906745cbcc1b8543a4fe10 License: Apache 2.0 License File: crashpad/LICENSE Security Critical: yes
diff --git a/third_party/crashpad/crashpad/.gitignore b/third_party/crashpad/crashpad/.gitignore index 982a95e..90038f1d 100644 --- a/third_party/crashpad/crashpad/.gitignore +++ b/third_party/crashpad/crashpad/.gitignore
@@ -19,6 +19,7 @@ /third_party/linux/.cipd /third_party/linux/clang /third_party/linux/sysroot +/third_party/lss/lss /third_party/gyp/gyp /third_party/mini_chromium/mini_chromium /third_party/zlib/zlib
diff --git a/third_party/crashpad/crashpad/doc/developing.md b/third_party/crashpad/crashpad/doc/developing.md index 4aaac6c..af557a53 100644 --- a/third_party/crashpad/crashpad/doc/developing.md +++ b/third_party/crashpad/crashpad/doc/developing.md
@@ -106,6 +106,21 @@ [depot_tools](https://www.chromium.org/developers/how-tos/depottools). There’s no need to install them separately. +#### Optional Linux Configs + +To pull and use Crashpad's version of clang and sysroot, make the following +changes. + +Add the following to `~/crashpad/.gclient`. +``` +"custom_vars": { "pull_linux_clang": True }, +``` +Add these args to `out/Default/args.gn`. +``` +clang_path = "//third_party/linux/clang/linux-amd64" +target_sysroot = "//third_party/linux/sysroot" +``` + ### Android Crashpad’s Android port is in its early stages. This build relies on
diff --git a/third_party/crashpad/crashpad/handler/fuchsia/crash_report_exception_handler.cc b/third_party/crashpad/crashpad/handler/fuchsia/crash_report_exception_handler.cc index 0d1ee30..b181cb60 100644 --- a/third_party/crashpad/crashpad/handler/fuchsia/crash_report_exception_handler.cc +++ b/third_party/crashpad/crashpad/handler/fuchsia/crash_report_exception_handler.cc
@@ -15,6 +15,8 @@ #include "handler/fuchsia/crash_report_exception_handler.h" #include <lib/zx/thread.h> +#include <zircon/errors.h> +#include <zircon/status.h> #include <zircon/syscalls/exception.h> #include "base/fuchsia/fuchsia_logging.h" @@ -58,7 +60,7 @@ CrashReportDatabase* database, CrashReportUploadThread* upload_thread, const std::map<std::string, std::string>* process_annotations, - const std::map<std::string, base::FilePath>* process_attachments, + const std::map<std::string, fuchsia::mem::Buffer>* process_attachments, const UserStreamDataSources* user_stream_data_sources) : database_(database), upload_thread_(upload_thread), @@ -165,19 +167,25 @@ if (process_attachments_) { // Note that attachments are read at this point each time rather than once - // so that if the contents of the file has changed it will be re-read for + // so that if the contents of the VMO has changed it will be re-read for // each upload (e.g. in the case of a log file). for (const auto& it : *process_attachments_) { + // TODO(frousseau): make FileWriter VMO-aware. FileWriter* writer = new_report->AddAttachment(it.first); - if (writer) { - std::string contents; - if (!LoggingReadEntireFile(it.second, &contents)) { - // Not being able to read the file isn't considered fatal, and - // should not prevent the report from being processed. - continue; - } - writer->Write(contents.data(), contents.size()); + if (!writer) { + continue; } + auto data = std::make_unique<uint8_t[]>(it.second.size); + const zx_status_t read_status = + it.second.vmo.read(data.get(), 0u, it.second.size); + if (read_status != ZX_OK) { + ZX_LOG(ERROR, read_status) + << "could not read VMO for attachment " << it.first; + // Not being able to read the VMO isn't considered fatal, and + // should not prevent the report from being processed. + continue; + } + writer->Write(data.get(), it.second.size); } }
diff --git a/third_party/crashpad/crashpad/handler/fuchsia/crash_report_exception_handler.h b/third_party/crashpad/crashpad/handler/fuchsia/crash_report_exception_handler.h index 88b4cca2..c636fca 100644 --- a/third_party/crashpad/crashpad/handler/fuchsia/crash_report_exception_handler.h +++ b/third_party/crashpad/crashpad/handler/fuchsia/crash_report_exception_handler.h
@@ -15,6 +15,7 @@ #ifndef CRASHPAD_HANDLER_FUCHSIA_CRASH_REPORT_EXCEPTION_HANDLER_H_ #define CRASHPAD_HANDLER_FUCHSIA_CRASH_REPORT_EXCEPTION_HANDLER_H_ +#include <fuchsia/mem/cpp/fidl.h> #include <lib/zx/port.h> #include <lib/zx/process.h> #include <lib/zx/thread.h> @@ -52,10 +53,10 @@ //! To interoperate with Breakpad servers, the recommended practice is to //! specify values for the `"prod"` and `"ver"` keys as process //! annotations. - //! \param[in] process_attachments A map of file name keys to file paths to be - //! included in the report. Each time a report is written, the file paths - //! will be read in their entirety and included in the report using the - //! file name key as the name in the http upload. + //! \param[in] process_attachments A map of keys to VMOs to be included in the + //! report. Each time a report is written, the VMOs will be read in their + //! entirety and included in the report using the key as the name in the + //! http upload. //! \param[in] user_stream_data_sources Data sources to be used to extend //! crash reports. For each crash report that is written, the data sources //! are called in turn. These data sources may contribute additional @@ -64,7 +65,7 @@ CrashReportDatabase* database, CrashReportUploadThread* upload_thread, const std::map<std::string, std::string>* process_annotations, - const std::map<std::string, base::FilePath>* process_attachments, + const std::map<std::string, fuchsia::mem::Buffer>* process_attachments, const UserStreamDataSources* user_stream_data_sources); ~CrashReportExceptionHandler(); @@ -112,7 +113,8 @@ CrashReportDatabase* database_; // weak CrashReportUploadThread* upload_thread_; // weak const std::map<std::string, std::string>* process_annotations_; // weak - const std::map<std::string, base::FilePath>* process_attachments_; // weak + const std::map<std::string, fuchsia::mem::Buffer>* + process_attachments_; // weak const UserStreamDataSources* user_stream_data_sources_; // weak DISALLOW_COPY_AND_ASSIGN(CrashReportExceptionHandler);
diff --git a/third_party/crashpad/crashpad/handler/linux/crash_report_exception_handler.cc b/third_party/crashpad/crashpad/handler/linux/crash_report_exception_handler.cc index 910b288..5401bafa 100644 --- a/third_party/crashpad/crashpad/handler/linux/crash_report_exception_handler.cc +++ b/third_party/crashpad/crashpad/handler/linux/crash_report_exception_handler.cc
@@ -43,9 +43,12 @@ CrashReportExceptionHandler::~CrashReportExceptionHandler() = default; -bool CrashReportExceptionHandler::HandleException(pid_t client_process_id, - const ClientInformation& info, - UUID* local_report_id) { +bool CrashReportExceptionHandler::HandleException( + pid_t client_process_id, + const ClientInformation& info, + VMAddress requesting_thread_stack_address, + pid_t* requesting_thread_id, + UUID* local_report_id) { Metrics::ExceptionEncountered(); DirectPtraceConnection connection; @@ -55,7 +58,11 @@ return false; } - return HandleExceptionWithConnection(&connection, info, local_report_id); + return HandleExceptionWithConnection(&connection, + info, + requesting_thread_stack_address, + requesting_thread_id, + local_report_id); } bool CrashReportExceptionHandler::HandleExceptionWithBroker( @@ -72,12 +79,15 @@ return false; } - return HandleExceptionWithConnection(&client, info, local_report_id); + return HandleExceptionWithConnection( + &client, info, 0, nullptr, local_report_id); } bool CrashReportExceptionHandler::HandleExceptionWithConnection( PtraceConnection* connection, const ClientInformation& info, + VMAddress requesting_thread_stack_address, + pid_t* requesting_thread_id, UUID* local_report_id) { ProcessSnapshotLinux process_snapshot; if (!process_snapshot.Initialize(connection)) { @@ -85,6 +95,11 @@ return false; } + if (requesting_thread_id && requesting_thread_stack_address) { + *requesting_thread_id = process_snapshot.FindThreadWithStackAddress( + requesting_thread_stack_address); + } + if (!process_snapshot.InitializeException( info.exception_information_address)) { Metrics::ExceptionCaptureResult(
diff --git a/third_party/crashpad/crashpad/handler/linux/crash_report_exception_handler.h b/third_party/crashpad/crashpad/handler/linux/crash_report_exception_handler.h index 9951d840..18051656 100644 --- a/third_party/crashpad/crashpad/handler/linux/crash_report_exception_handler.h +++ b/third_party/crashpad/crashpad/handler/linux/crash_report_exception_handler.h
@@ -66,6 +66,8 @@ bool HandleException(pid_t client_process_id, const ClientInformation& info, + VMAddress requesting_thread_stack_address = 0, + pid_t* requesting_thread_id = nullptr, UUID* local_report_id = nullptr) override; bool HandleExceptionWithBroker(pid_t client_process_id, @@ -76,6 +78,8 @@ private: bool HandleExceptionWithConnection(PtraceConnection* connection, const ClientInformation& info, + VMAddress requesting_thread_stack_address, + pid_t* requesting_thread_id, UUID* local_report_id = nullptr); CrashReportDatabase* database_; // weak
diff --git a/third_party/crashpad/crashpad/handler/linux/exception_handler_server.cc b/third_party/crashpad/crashpad/handler/linux/exception_handler_server.cc index 12e73635..c284212 100644 --- a/third_party/crashpad/crashpad/handler/linux/exception_handler_server.cc +++ b/third_party/crashpad/crashpad/handler/linux/exception_handler_server.cc
@@ -414,8 +414,10 @@ switch (client_msg->type) { case ClientToServerMessage::kCrashDumpRequest: - return HandleCrashDumpRequest( - msg, client_msg->client_info, event->fd.get()); + return HandleCrashDumpRequest(msg, + client_msg->client_info, + client_msg->requesting_thread_stack_address, + event->fd.get()); } DCHECK(false); @@ -426,6 +428,7 @@ bool ExceptionHandlerServer::HandleCrashDumpRequest( const msghdr& msg, const ClientInformation& client_info, + VMAddress requesting_thread_stack_address, int client_sock) { cmsghdr* cmsg = CMSG_FIRSTHDR(&msg); if (cmsg == nullptr) { @@ -460,7 +463,8 @@ ServerToClientMessage::kTypeCrashDumpFailed); case PtraceStrategyDecider::Strategy::kDirectPtrace: - delegate_->HandleException(client_process_id, client_info); + delegate_->HandleException( + client_process_id, client_info, requesting_thread_stack_address); break; case PtraceStrategyDecider::Strategy::kUseBroker:
diff --git a/third_party/crashpad/crashpad/handler/linux/exception_handler_server.h b/third_party/crashpad/crashpad/handler/linux/exception_handler_server.h index 239aeea..6f13fdc 100644 --- a/third_party/crashpad/crashpad/handler/linux/exception_handler_server.h +++ b/third_party/crashpad/crashpad/handler/linux/exception_handler_server.h
@@ -73,11 +73,19 @@ //! //! \param[in] client_process_id The process ID of the crashing client. //! \param[in] info Information on the client. + //! \param[in] requesting_thread_stack_address Any address within the stack + //! range for the the thread that sent the crash dump request. Optional. + //! If unspecified or 0, \a requesting_thread_id will be -1. + //! \param[out] requesting_thread_id The thread ID of the thread which + //! requested the crash dump if not `nullptr`. Set to -1 if the thread + //! ID could not be determined. Optional. //! \param[out] local_report_id The unique identifier for the report created //! in the local report database. Optional. //! \return `true` on success. `false` on failure with a message logged. virtual bool HandleException(pid_t client_process_id, const ClientInformation& info, + VMAddress requesting_thread_stack_address = 0, + pid_t* requesting_thread_id = nullptr, UUID* local_report_id = nullptr) = 0; //! \brief Called on the receipt of a crash dump request from a client for a @@ -141,6 +149,7 @@ bool ReceiveClientMessage(Event* event); bool HandleCrashDumpRequest(const msghdr& msg, const ClientInformation& client_info, + VMAddress requesting_thread_stack_address, int client_sock); std::unordered_map<int, std::unique_ptr<Event>> clients_;
diff --git a/third_party/crashpad/crashpad/handler/linux/exception_handler_server_test.cc b/third_party/crashpad/crashpad/handler/linux/exception_handler_server_test.cc index 083a4ea..7d15cbb 100644 --- a/third_party/crashpad/crashpad/handler/linux/exception_handler_server_test.cc +++ b/third_party/crashpad/crashpad/handler/linux/exception_handler_server_test.cc
@@ -19,6 +19,7 @@ #include "base/logging.h" #include "gtest/gtest.h" +#include "snapshot/linux/process_snapshot_linux.h" #include "test/errors.h" #include "test/multiprocess.h" #include "util/linux/direct_ptrace_connection.h" @@ -103,6 +104,8 @@ bool HandleException(pid_t client_process_id, const ClientInformation& info, + VMAddress requesting_thread_stack_address, + pid_t* requesting_thread_id = nullptr, UUID* local_report_id = nullptr) override { DirectPtraceConnection connection; bool connected = connection.Initialize(client_process_id); @@ -111,7 +114,24 @@ last_exception_address_ = info.exception_information_address; last_client_ = client_process_id; sem_.Signal(); - return connected; + if (!connected) { + return false; + } + + if (requesting_thread_id) { + if (requesting_thread_stack_address) { + ProcessSnapshotLinux process_snapshot; + if (!process_snapshot.Initialize(&connection)) { + ADD_FAILURE(); + return false; + } + *requesting_thread_id = process_snapshot.FindThreadWithStackAddress( + requesting_thread_stack_address); + } else { + *requesting_thread_id = -1; + } + } + return true; } bool HandleExceptionWithBroker(pid_t client_process_id,
diff --git a/third_party/crashpad/crashpad/snapshot/BUILD.gn b/third_party/crashpad/crashpad/snapshot/BUILD.gn index 8925714..17488a0 100644 --- a/third_party/crashpad/crashpad/snapshot/BUILD.gn +++ b/third_party/crashpad/crashpad/snapshot/BUILD.gn
@@ -36,6 +36,8 @@ "memory_snapshot.cc", "memory_snapshot.h", "memory_snapshot_generic.h", + "minidump/exception_snapshot_minidump.cc", + "minidump/exception_snapshot_minidump.h", "minidump/memory_snapshot_minidump.cc", "minidump/memory_snapshot_minidump.h", "minidump/minidump_annotation_reader.cc",
diff --git a/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.cc b/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.cc index 4141b2f..3442e4a 100644 --- a/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.cc +++ b/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.cc
@@ -49,6 +49,20 @@ return true; } +pid_t ProcessSnapshotLinux::FindThreadWithStackAddress( + VMAddress stack_address) { + INITIALIZATION_STATE_DCHECK_VALID(initialized_); + + for (const auto& thread : process_reader_.Threads()) { + if (stack_address >= thread.stack_region_address && + stack_address < + thread.stack_region_address + thread.stack_region_size) { + return thread.tid; + } + } + return -1; +} + bool ProcessSnapshotLinux::InitializeException( LinuxVMAddress exception_info_address) { INITIALIZATION_STATE_DCHECK_VALID(initialized_);
diff --git a/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.h b/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.h index 84bd226..c96384d 100644 --- a/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.h +++ b/third_party/crashpad/crashpad/snapshot/linux/process_snapshot_linux.h
@@ -58,6 +58,13 @@ //! an appropriate message logged. bool Initialize(PtraceConnection* connection); + //! \brief Finds the thread whose stack contains \a stack_address. + //! + //! \param[in] stack_address A stack address to search for. + //! \return The thread ID of the thread whose stack contains \a stack_address + //! or -1 if no matching thread is found. + pid_t FindThreadWithStackAddress(VMAddress stack_address); + //! \brief Initializes the object's exception. //! //! \param[in] exception_info The address of an ExceptionInformation in the
diff --git a/third_party/crashpad/crashpad/snapshot/minidump/exception_snapshot_minidump.cc b/third_party/crashpad/crashpad/snapshot/minidump/exception_snapshot_minidump.cc new file mode 100644 index 0000000..0852ed9 --- /dev/null +++ b/third_party/crashpad/crashpad/snapshot/minidump/exception_snapshot_minidump.cc
@@ -0,0 +1,93 @@ +// Copyright 2019 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "snapshot/minidump/exception_snapshot_minidump.h" + +#include "snapshot/minidump/minidump_string_reader.h" + +namespace crashpad { +namespace internal { + +ExceptionSnapshotMinidump::ExceptionSnapshotMinidump() + : ExceptionSnapshot(), + minidump_exception_stream_(), + exception_information_(), + initialized_() {} + +ExceptionSnapshotMinidump::~ExceptionSnapshotMinidump() {} + +bool ExceptionSnapshotMinidump::Initialize(FileReaderInterface* file_reader, + RVA minidump_exception_stream_rva) { + DCHECK(initialized_.is_uninitialized()); + initialized_.set_invalid(); + + if (!file_reader->SeekSet(minidump_exception_stream_rva)) { + return false; + } + + if (!file_reader->ReadExactly(&minidump_exception_stream_, + sizeof(minidump_exception_stream_))) { + return false; + } + + const size_t num_parameters = + minidump_exception_stream_.ExceptionRecord.NumberParameters; + for (size_t i = 0; i < num_parameters; ++i) { + exception_information_.push_back( + minidump_exception_stream_.ExceptionRecord.ExceptionInformation[i]); + } + + initialized_.set_valid(); + return true; +} + +const CPUContext* ExceptionSnapshotMinidump::Context() const { + DCHECK(initialized_.is_valid()); + NOTREACHED(); // https://crashpad.chromium.org/bug/10 + return nullptr; +} + +uint64_t ExceptionSnapshotMinidump::ThreadID() const { + DCHECK(initialized_.is_valid()); + return minidump_exception_stream_.ThreadId; +} + +uint32_t ExceptionSnapshotMinidump::Exception() const { + DCHECK(initialized_.is_valid()); + return minidump_exception_stream_.ExceptionRecord.ExceptionCode; +} + +uint32_t ExceptionSnapshotMinidump::ExceptionInfo() const { + DCHECK(initialized_.is_valid()); + return minidump_exception_stream_.ExceptionRecord.ExceptionFlags; +} + +uint64_t ExceptionSnapshotMinidump::ExceptionAddress() const { + DCHECK(initialized_.is_valid()); + return minidump_exception_stream_.ExceptionRecord.ExceptionAddress; +} + +const std::vector<uint64_t>& ExceptionSnapshotMinidump::Codes() const { + DCHECK(initialized_.is_valid()); + return exception_information_; +} + +std::vector<const MemorySnapshot*> ExceptionSnapshotMinidump::ExtraMemory() + const { + DCHECK(initialized_.is_valid()); + return std::vector<const MemorySnapshot*>(); +} + +} // namespace internal +} // namespace crashpad
diff --git a/third_party/crashpad/crashpad/snapshot/minidump/exception_snapshot_minidump.h b/third_party/crashpad/crashpad/snapshot/minidump/exception_snapshot_minidump.h new file mode 100644 index 0000000..8ce29f7c --- /dev/null +++ b/third_party/crashpad/crashpad/snapshot/minidump/exception_snapshot_minidump.h
@@ -0,0 +1,72 @@ +// Copyright 2019 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef CRASHPAD_SNAPSHOT_MINIDUMP_EXCEPTION_SNAPSHOT_MINIDUMP_H_ +#define CRASHPAD_SNAPSHOT_MINIDUMP_EXCEPTION_SNAPSHOT_MINIDUMP_H_ + +#include <windows.h> +#include <dbghelp.h> + +#include "build/build_config.h" +#include "snapshot/cpu_context.h" +#include "snapshot/exception_snapshot.h" +#include "util/file/file_reader.h" +#include "util/misc/initialization_state.h" + +namespace crashpad { +namespace internal { + +//! \brief An ExceptionSnapshot based on a minidump file. +class ExceptionSnapshotMinidump final : public ExceptionSnapshot { + public: + ExceptionSnapshotMinidump(); + ~ExceptionSnapshotMinidump() override; + + //! \brief Initializes the object. + //! + //! \param[in] file_reader A file reader corresponding to a minidump file. + //! The file reader must support seeking. + //! \param[in] minidump_exception_stream_rva The file offset in \a file_reader + //! at which the MINIDUMP_EXCEPTION_STREAM structure is located. + //! + //! \return `true` if the snapshot could be created, `false` otherwise with + //! an appropriate message logged. + bool Initialize(FileReaderInterface* file_reader, + RVA minidump_exception_stream_rva); + + // ExceptionSnapshot: + const CPUContext* Context() const override; + uint64_t ThreadID() const override; + uint32_t Exception() const override; + uint32_t ExceptionInfo() const override; + uint64_t ExceptionAddress() const override; + const std::vector<uint64_t>& Codes() const override; + std::vector<const MemorySnapshot*> ExtraMemory() const override; + + // Allow callers to explicitly check whether this exception snapshot has been + // initialized. + bool IsValid() const { return initialized_.is_valid(); } + + private: + MINIDUMP_EXCEPTION_STREAM minidump_exception_stream_; + std::vector<uint64_t> exception_information_; + InitializationState initialized_; + + DISALLOW_COPY_AND_ASSIGN(ExceptionSnapshotMinidump); +}; + +} // namespace internal +} // namespace crashpad + +#endif // CRASHPAD_SNAPSHOT_MINIDUMP_EXCEPTION_SNAPSHOT_MINIDUMP_H_
diff --git a/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.cc b/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.cc index 620f5de9..f191cb9 100644 --- a/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.cc +++ b/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.cc
@@ -53,12 +53,12 @@ custom_streams_(), crashpad_info_(), system_snapshot_(), + exception_snapshot_(), arch_(CPUArchitecture::kCPUArchitectureUnknown), annotations_simple_map_(), file_reader_(nullptr), process_id_(static_cast<pid_t>(-1)), - initialized_() { -} + initialized_() {} ProcessSnapshotMinidump::~ProcessSnapshotMinidump() { } @@ -109,13 +109,10 @@ stream_map_[stream_type] = &directory.Location; } - if (!InitializeCrashpadInfo() || - !InitializeMiscInfo() || - !InitializeModules() || - !InitializeSystemSnapshot() || - !InitializeMemoryInfo() || - !InitializeThreads() || - !InitializeCustomMinidumpStreams()) { + if (!InitializeCrashpadInfo() || !InitializeMiscInfo() || + !InitializeModules() || !InitializeSystemSnapshot() || + !InitializeMemoryInfo() || !InitializeThreads() || + !InitializeCustomMinidumpStreams() || !InitializeExceptionSnapshot()) { return false; } @@ -212,7 +209,10 @@ const ExceptionSnapshot* ProcessSnapshotMinidump::Exception() const { INITIALIZATION_STATE_DCHECK_VALID(initialized_); - NOTREACHED(); // https://crashpad.chromium.org/bug/10 + if (exception_snapshot_.IsValid()) { + return &exception_snapshot_; + } + // Allow caller to know whether the minidump contained an exception stream. return nullptr; } @@ -576,4 +576,22 @@ return true; } +bool ProcessSnapshotMinidump::InitializeExceptionSnapshot() { + const auto& stream_it = stream_map_.find(kMinidumpStreamTypeException); + if (stream_it == stream_map_.end()) { + return true; + } + + if (stream_it->second->DataSize < sizeof(MINIDUMP_EXCEPTION_STREAM)) { + LOG(ERROR) << "system info size mismatch"; + return false; + } + + if (!exception_snapshot_.Initialize(file_reader_, stream_it->second->Rva)) { + return false; + } + + return true; +} + } // namespace crashpad
diff --git a/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.h b/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.h index 8653d33..2df59d2 100644 --- a/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.h +++ b/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.h
@@ -29,6 +29,7 @@ #include "minidump/minidump_extensions.h" #include "snapshot/exception_snapshot.h" #include "snapshot/memory_snapshot.h" +#include "snapshot/minidump/exception_snapshot_minidump.h" #include "snapshot/minidump/minidump_stream.h" #include "snapshot/minidump/module_snapshot_minidump.h" #include "snapshot/minidump/system_snapshot_minidump.h" @@ -129,6 +130,10 @@ // Initializes custom minidump streams. bool InitializeCustomMinidumpStreams(); + // Initializes data carried in a MINIDUMP_EXCEPTION_STREAM stream on behalf of + // Initialize(). + bool InitializeExceptionSnapshot(); + MINIDUMP_HEADER header_; std::vector<MINIDUMP_DIRECTORY> stream_directory_; std::map<MinidumpStreamType, const MINIDUMP_LOCATION_DESCRIPTOR*> stream_map_; @@ -141,6 +146,7 @@ std::vector<std::unique_ptr<MinidumpStream>> custom_streams_; MinidumpCrashpadInfo crashpad_info_; internal::SystemSnapshotMinidump system_snapshot_; + internal::ExceptionSnapshotMinidump exception_snapshot_; CPUArchitecture arch_; std::map<std::string, std::string> annotations_simple_map_; FileReaderInterface* file_reader_; // weak
diff --git a/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump_test.cc b/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump_test.cc index f4b611d..a03edfb1 100644 --- a/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump_test.cc +++ b/third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump_test.cc
@@ -1170,6 +1170,83 @@ EXPECT_STREQ((char*)&stream_data.front(), kStreamUnreservedData); } +TEST(ProcessSnapshotMinidump, Exception) { + StringFile string_file; + + MINIDUMP_HEADER header = {}; + EXPECT_TRUE(string_file.Write(&header, sizeof(header))); + + uint32_t exception_signo = + static_cast<uint32_t>(-1); // crashpad::Signals::kSimulatedSigno + + MINIDUMP_EXCEPTION minidump_exception = {}; + minidump_exception.ExceptionCode = exception_signo; + minidump_exception.ExceptionFlags = 2; + minidump_exception.ExceptionRecord = 4; + minidump_exception.ExceptionAddress = 0xdeedb00f; + minidump_exception.NumberParameters = 2; + minidump_exception.ExceptionInformation[0] = 51; + minidump_exception.ExceptionInformation[1] = 62; + + MINIDUMP_EXCEPTION_STREAM minidump_exception_stream = {}; + minidump_exception_stream.ThreadId = 5; + minidump_exception_stream.ExceptionRecord = minidump_exception; + + MINIDUMP_DIRECTORY minidump_exception_directory = {}; + minidump_exception_directory.StreamType = kMinidumpStreamTypeException; + minidump_exception_directory.Location.DataSize = + sizeof(MINIDUMP_EXCEPTION_STREAM); + minidump_exception_directory.Location.Rva = + static_cast<RVA>(string_file.SeekGet()); + + ASSERT_TRUE(string_file.Write(&minidump_exception_stream, + sizeof(minidump_exception_stream))); + + header.StreamDirectoryRva = static_cast<RVA>(string_file.SeekGet()); + ASSERT_TRUE(string_file.Write(&minidump_exception_directory, + sizeof(minidump_exception_directory))); + + header.Signature = MINIDUMP_SIGNATURE; + header.Version = MINIDUMP_VERSION; + header.NumberOfStreams = 1; + EXPECT_TRUE(string_file.SeekSet(0)); + EXPECT_TRUE(string_file.Write(&header, sizeof(header))); + + ProcessSnapshotMinidump process_snapshot; + EXPECT_TRUE(process_snapshot.Initialize(&string_file)); + + const ExceptionSnapshot* s = process_snapshot.Exception(); + + EXPECT_EQ(s->ThreadID(), 5UL); + EXPECT_EQ(s->Exception(), exception_signo); + EXPECT_EQ(s->ExceptionInfo(), 2U); + EXPECT_EQ(s->ExceptionAddress(), 0xdeedb00f); + + const std::vector<uint64_t> codes = s->Codes(); + EXPECT_EQ(codes.size(), 2UL); + EXPECT_EQ(codes[0], 51UL); + EXPECT_EQ(codes[1], 62UL); +} + +TEST(ProcessSnapshotMinidump, NoExceptionInMinidump) { + StringFile string_file; + + MINIDUMP_HEADER header = {}; + EXPECT_TRUE(string_file.Write(&header, sizeof(header))); + + header.Signature = MINIDUMP_SIGNATURE; + header.Version = MINIDUMP_VERSION; + header.NumberOfStreams = 0; + EXPECT_TRUE(string_file.SeekSet(0)); + EXPECT_TRUE(string_file.Write(&header, sizeof(header))); + + ProcessSnapshotMinidump process_snapshot; + EXPECT_TRUE(process_snapshot.Initialize(&string_file)); + + const ExceptionSnapshot* s = process_snapshot.Exception(); + EXPECT_EQ(s, nullptr); +} + } // namespace } // namespace test } // namespace crashpad
diff --git a/third_party/crashpad/crashpad/snapshot/snapshot.gyp b/third_party/crashpad/crashpad/snapshot/snapshot.gyp index 8c563f52..0b4e157 100644 --- a/third_party/crashpad/crashpad/snapshot/snapshot.gyp +++ b/third_party/crashpad/crashpad/snapshot/snapshot.gyp
@@ -116,6 +116,8 @@ 'minidump/minidump_string_list_reader.h', 'minidump/minidump_string_reader.cc', 'minidump/minidump_string_reader.h', + 'minidump/exception_snapshot_minidump.cc', + 'minidump/exception_snapshot_minidump.h', 'minidump/memory_snapshot_minidump.cc', 'minidump/memory_snapshot_minidump.h', 'minidump/module_snapshot_minidump.cc',
diff --git a/third_party/crashpad/crashpad/third_party/fuchsia/BUILD.gn b/third_party/crashpad/crashpad/third_party/fuchsia/BUILD.gn index f712af24..f10ccd0d 100644 --- a/third_party/crashpad/crashpad/third_party/fuchsia/BUILD.gn +++ b/third_party/crashpad/crashpad/third_party/fuchsia/BUILD.gn
@@ -17,6 +17,7 @@ if (crashpad_is_in_fuchsia) { group("fuchsia") { public_deps = [ + "//zircon/public/fidl/fuchsia-mem", "//zircon/public/fidl/fuchsia-sysinfo:fuchsia-sysinfo_c", "//zircon/public/lib/fdio", "//zircon/public/lib/zx", @@ -26,6 +27,7 @@ group("fuchsia") { public_deps = [ "//third_party/fuchsia-sdk/sdk:fdio", + "//third_party/fuchsia-sdk/sdk:mem", "//third_party/fuchsia-sdk/sdk:sysinfo", "//third_party/fuchsia-sdk/sdk:zx", ] @@ -36,42 +38,105 @@ sdk_fidl_sources_path = "$sdk_path/fidl" config("zx_config") { - visibility = [ ":fuchsia" ] include_dirs = [ "$sdk_pkg_path/zx/include" ] } fidl_root_gen_dir = "$root_gen_dir/fidl/include" config("fidl_config") { - visibility = [ ":fuchsia" ] include_dirs = [ fidl_root_gen_dir, "$sdk_pkg_path/fidl/include", "$sdk_pkg_path/fidl_base/include", + "$sdk_pkg_path/async/include", + "$sdk_pkg_path/fidl_cpp/include", + "$sdk_pkg_path/fidl_cpp_base/include", + "$sdk_pkg_path/fidl_cpp_sync/include", + "$sdk_pkg_path/fit/include", + ] + } + + source_set("zx") { + sources = [ + "$sdk_pkg_path/zx/channel.cpp", + "$sdk_pkg_path/zx/event.cpp", + "$sdk_pkg_path/zx/eventpair.cpp", + "$sdk_pkg_path/zx/fifo.cpp", + "$sdk_pkg_path/zx/guest.cpp", + "$sdk_pkg_path/zx/interrupt.cpp", + "$sdk_pkg_path/zx/job.cpp", + "$sdk_pkg_path/zx/port.cpp", + "$sdk_pkg_path/zx/process.cpp", + "$sdk_pkg_path/zx/resource.cpp", + "$sdk_pkg_path/zx/socket.cpp", + "$sdk_pkg_path/zx/thread.cpp", + "$sdk_pkg_path/zx/timer.cpp", + "$sdk_pkg_path/zx/vmar.cpp", + "$sdk_pkg_path/zx/vmo.cpp", + ] + + public_configs = [ ":zx_config" ] + } + + source_set("fidl_base") { + sources = [ + "$sdk_pkg_path/fidl_base/builder.cpp", + "$sdk_pkg_path/fidl_base/decoding.cpp", + "$sdk_pkg_path/fidl_base/encoding.cpp", + "$sdk_pkg_path/fidl_base/envelope_frames.h", + "$sdk_pkg_path/fidl_base/formatting.cpp", + "$sdk_pkg_path/fidl_base/linearizing.cpp", + "$sdk_pkg_path/fidl_base/message.cpp", + "$sdk_pkg_path/fidl_base/message_buffer.cpp", + "$sdk_pkg_path/fidl_base/message_builder.cpp", + "$sdk_pkg_path/fidl_base/validating.cpp", + "$sdk_pkg_path/fidl_base/visitor.h", + "$sdk_pkg_path/fidl_base/walker.cpp", + "$sdk_pkg_path/fidl_base/walker.h", + ] + + public_configs = [ ":fidl_config" ] + } + + source_set("fidl_cpp_base") { + sources = [ + "$sdk_pkg_path/fidl_cpp_base/clone.cc", + "$sdk_pkg_path/fidl_cpp_base/decoder.cc", + "$sdk_pkg_path/fidl_cpp_base/encoder.cc", + "$sdk_pkg_path/fidl_cpp_base/string.cc", + ] + + public_configs = [ + ":fidl_config", + ":zx_config", ] } fidl_sources = [ { + fidl = "$sdk_fidl_sources_path/fuchsia.mem/buffer.fidl" + header_stem = "fuchsia/mem" + library_name = "fuchsia.mem" + }, + { fidl = "$sdk_fidl_sources_path/fuchsia.sysinfo/sysinfo.fidl" header_stem = "fuchsia/sysinfo" library_name = "fuchsia.sysinfo" }, ] - fidl_gen_sources = [] foreach(fidl_source, fidl_sources) { fidl_stem = "$target_gen_dir/fidl/${fidl_source.library_name}" + json_representation = "$fidl_stem/intermediary_representation.json" c_stem = "$fidl_root_gen_dir/${fidl_source.header_stem}/c" c_header = "$c_stem/fidl.h" c_client = "$c_stem/client.cc" + cpp_stem = "$fidl_root_gen_dir/${fidl_source.header_stem}/cpp/fidl" + cpp_header = "$cpp_stem.h" + cpp_source = "$cpp_stem.cc" coding_tables = "$fidl_stem/tables.cc" - fidl_gen_sources += [ - c_client, - coding_tables, - ] - - # Compiles the .fidl file and generates the C bindings. + # Compiles the .fidl file, outputs the intermediary JSON representation + # and generates the C bindings. action("fidlc_${fidl_source.library_name}") { visibility = [ ":*" ] @@ -85,6 +150,8 @@ rebase_path(c_client, root_build_dir), "--tables", rebase_path(coding_tables, root_build_dir), + "--json", + rebase_path(json_representation, root_build_dir), "--name", fidl_source.library_name, "--files", @@ -100,80 +167,94 @@ c_client, c_header, coding_tables, + json_representation, + ] + } + + # Generates the C++ bindings from the intermediary JSON representation. + action("fidlgen_cpp_${fidl_source.library_name}") { + visibility = [ ":*" ] + + script = "runner.py" + + args = [ + rebase_path("$sdk_path/tools/fidlgen", root_build_dir), + "--json", + rebase_path(json_representation, root_build_dir), + "--include-base", + rebase_path(fidl_root_gen_dir, root_build_dir), + "--output-base", + rebase_path(cpp_stem, root_build_dir), + "--generators", + "cpp", + ] + + inputs = [ + "$sdk_path/tools/fidlgen", + json_representation, + ] + + outputs = [ + cpp_header, + cpp_source, + ] + + deps = [ + ":fidlc_${fidl_source.library_name}", + ] + } + + source_set("${fidl_source.library_name}_tables") { + sources = [ + coding_tables, + ] + + deps = [ + ":fidlc_${fidl_source.library_name}", + ] + + public_configs = [ ":fidl_config" ] + } + + source_set("${fidl_source.library_name}_c") { + sources = [ + c_client, + c_header, + ] + + deps = [ + ":${fidl_source.library_name}_tables", + ":fidlc_${fidl_source.library_name}", + ] + + public_configs = [ ":fidl_config" ] + } + + source_set("${fidl_source.library_name}_cpp") { + sources = [ + cpp_header, + cpp_source, + ] + + deps = [ + ":${fidl_source.library_name}_tables", + ":fidlgen_cpp_${fidl_source.library_name}", + ] + + public_configs = [ + ":fidl_config", + ":zx_config", ] } } static_library("fuchsia") { - sources = - [ - # This is the zx library. - "$sdk_pkg_path/zx/channel.cpp", - "$sdk_pkg_path/zx/event.cpp", - "$sdk_pkg_path/zx/eventpair.cpp", - "$sdk_pkg_path/zx/fifo.cpp", - "$sdk_pkg_path/zx/guest.cpp", - "$sdk_pkg_path/zx/include/lib/zx/bti.h", - "$sdk_pkg_path/zx/include/lib/zx/channel.h", - "$sdk_pkg_path/zx/include/lib/zx/event.h", - "$sdk_pkg_path/zx/include/lib/zx/eventpair.h", - "$sdk_pkg_path/zx/include/lib/zx/fifo.h", - "$sdk_pkg_path/zx/include/lib/zx/guest.h", - "$sdk_pkg_path/zx/include/lib/zx/handle.h", - "$sdk_pkg_path/zx/include/lib/zx/interrupt.h", - "$sdk_pkg_path/zx/include/lib/zx/job.h", - "$sdk_pkg_path/zx/include/lib/zx/object.h", - "$sdk_pkg_path/zx/include/lib/zx/object_traits.h", - "$sdk_pkg_path/zx/include/lib/zx/pmt.h", - "$sdk_pkg_path/zx/include/lib/zx/port.h", - "$sdk_pkg_path/zx/include/lib/zx/process.h", - "$sdk_pkg_path/zx/include/lib/zx/resource.h", - "$sdk_pkg_path/zx/include/lib/zx/socket.h", - "$sdk_pkg_path/zx/include/lib/zx/task.h", - "$sdk_pkg_path/zx/include/lib/zx/thread.h", - "$sdk_pkg_path/zx/include/lib/zx/time.h", - "$sdk_pkg_path/zx/include/lib/zx/timer.h", - "$sdk_pkg_path/zx/include/lib/zx/vmar.h", - "$sdk_pkg_path/zx/include/lib/zx/vmo.h", - "$sdk_pkg_path/zx/interrupt.cpp", - "$sdk_pkg_path/zx/job.cpp", - "$sdk_pkg_path/zx/port.cpp", - "$sdk_pkg_path/zx/process.cpp", - "$sdk_pkg_path/zx/resource.cpp", - "$sdk_pkg_path/zx/socket.cpp", - "$sdk_pkg_path/zx/thread.cpp", - "$sdk_pkg_path/zx/timer.cpp", - "$sdk_pkg_path/zx/vmar.cpp", - "$sdk_pkg_path/zx/vmo.cpp", - - # This is the fidl_base library. - "$sdk_pkg_path/fidl_base/builder.cpp", - "$sdk_pkg_path/fidl_base/decoding.cpp", - "$sdk_pkg_path/fidl_base/encoding.cpp", - "$sdk_pkg_path/fidl_base/envelope_frames.h", - "$sdk_pkg_path/fidl_base/formatting.cpp", - "$sdk_pkg_path/fidl_base/include/lib/fidl/coding.h", - "$sdk_pkg_path/fidl_base/include/lib/fidl/cpp/builder.h", - "$sdk_pkg_path/fidl_base/include/lib/fidl/cpp/message.h", - "$sdk_pkg_path/fidl_base/include/lib/fidl/cpp/message_buffer.h", - "$sdk_pkg_path/fidl_base/include/lib/fidl/cpp/message_builder.h", - "$sdk_pkg_path/fidl_base/include/lib/fidl/cpp/message_part.h", - "$sdk_pkg_path/fidl_base/include/lib/fidl/cpp/string_view.h", - "$sdk_pkg_path/fidl_base/include/lib/fidl/cpp/vector_view.h", - "$sdk_pkg_path/fidl_base/include/lib/fidl/internal.h", - "$sdk_pkg_path/fidl_base/include/lib/fidl/internal_callable_traits.h", - "$sdk_pkg_path/fidl_base/linearizing.cpp", - "$sdk_pkg_path/fidl_base/message.cpp", - "$sdk_pkg_path/fidl_base/message_buffer.cpp", - "$sdk_pkg_path/fidl_base/message_builder.cpp", - "$sdk_pkg_path/fidl_base/validating.cpp", - "$sdk_pkg_path/fidl_base/visitor.h", - "$sdk_pkg_path/fidl_base/walker.cpp", - "$sdk_pkg_path/fidl_base/walker.h", - ] + fidl_gen_sources - deps = [ - ":fidlc_fuchsia.sysinfo", + ":fidl_base", + ":fidl_cpp_base", + ":fuchsia.mem_cpp", + ":fuchsia.sysinfo_c", + ":zx", ] public_configs = [
diff --git a/third_party/crashpad/crashpad/util/file/directory_reader_posix.cc b/third_party/crashpad/crashpad/util/file/directory_reader_posix.cc index b33e19b..475b0b1 100644 --- a/third_party/crashpad/crashpad/util/file/directory_reader_posix.cc +++ b/third_party/crashpad/crashpad/util/file/directory_reader_posix.cc
@@ -39,7 +39,7 @@ bool DirectoryReader::Open(const base::FilePath& path) { dir_.reset(HANDLE_EINTR_IF_EQ(opendir(path.value().c_str()), nullptr)); if (!dir_.is_valid()) { - PLOG(ERROR) << "opendir"; + PLOG(ERROR) << "opendir " << path.value(); return false; } return true; @@ -52,7 +52,7 @@ dirent* entry = HANDLE_EINTR_IF_EQ(readdir(dir_.get()), nullptr); if (!entry) { if (errno) { - PLOG(ERROR) << "readdir"; + PLOG(ERROR) << "readdir " << filename->value(); return Result::kError; } else { return Result::kNoMoreFiles;
diff --git a/third_party/crashpad/crashpad/util/linux/exception_handler_client.cc b/third_party/crashpad/crashpad/util/linux/exception_handler_client.cc index 6333351..e4548d62 100644 --- a/third_party/crashpad/crashpad/util/linux/exception_handler_client.cc +++ b/third_party/crashpad/crashpad/util/linux/exception_handler_client.cc
@@ -25,6 +25,7 @@ #include "build/build_config.h" #include "util/file/file_io.h" #include "util/linux/ptrace_broker.h" +#include "util/misc/from_pointer_cast.h" #include "util/posix/signals.h" namespace crashpad { @@ -35,7 +36,9 @@ ExceptionHandlerClient::~ExceptionHandlerClient() = default; int ExceptionHandlerClient::RequestCrashDump(const ClientInformation& info) { - int status = SendCrashDumpRequest(info); + VMAddress sp = FromPointerCast<VMAddress>(&sp); + + int status = SendCrashDumpRequest(info, sp); if (status != 0) { return status; } @@ -61,10 +64,11 @@ can_set_ptracer_ = can_set_ptracer; } -int ExceptionHandlerClient::SendCrashDumpRequest( - const ClientInformation& info) { +int ExceptionHandlerClient::SendCrashDumpRequest(const ClientInformation& info, + VMAddress stack_pointer) { ClientToServerMessage message; message.type = ClientToServerMessage::kCrashDumpRequest; + message.requesting_thread_stack_address = stack_pointer; message.client_info = info; iovec iov;
diff --git a/third_party/crashpad/crashpad/util/linux/exception_handler_client.h b/third_party/crashpad/crashpad/util/linux/exception_handler_client.h index a60b065..25a8a44 100644 --- a/third_party/crashpad/crashpad/util/linux/exception_handler_client.h +++ b/third_party/crashpad/crashpad/util/linux/exception_handler_client.h
@@ -53,7 +53,8 @@ void SetCanSetPtracer(bool can_set_ptracer); private: - int SendCrashDumpRequest(const ClientInformation& info); + int SendCrashDumpRequest(const ClientInformation& info, + VMAddress stack_pointer); int WaitForCrashDumpComplete(); int server_sock_;
diff --git a/third_party/crashpad/crashpad/util/linux/exception_handler_protocol.h b/third_party/crashpad/crashpad/util/linux/exception_handler_protocol.h index 4ba1b5d0..0ab3ffd0 100644 --- a/third_party/crashpad/crashpad/util/linux/exception_handler_protocol.h +++ b/third_party/crashpad/crashpad/util/linux/exception_handler_protocol.h
@@ -57,6 +57,9 @@ //! \brief Indicates what message version is being used. int32_t version; + //! \brief A stack address of the thread sending the message. + VMAddress requesting_thread_stack_address; + enum Type : uint32_t { //! \brief Used to request a crash dump for the sending client. kCrashDumpRequest
diff --git a/third_party/crashpad/crashpad/util/stdlib/string_number_conversion.cc b/third_party/crashpad/crashpad/util/stdlib/string_number_conversion.cc index 859a83335..6421184 100644 --- a/third_party/crashpad/crashpad/util/stdlib/string_number_conversion.cc +++ b/third_party/crashpad/crashpad/util/stdlib/string_number_conversion.cc
@@ -97,15 +97,34 @@ } }; -struct StringToInt64Traits - : public StringToSignedIntegerTraits<int64_t, int64_t> { +struct StringToLongTraits + : public StringToSignedIntegerTraits<long, long long> { static LongType Convert(const char* str, char** end, int base) { return strtoll(str, end, base); } }; -struct StringToUnsignedInt64Traits - : public StringToUnsignedIntegerTraits<uint64_t, uint64_t> { +struct StringToUnsignedLongTraits + : public StringToUnsignedIntegerTraits<unsigned long, unsigned long long> { + static LongType Convert(const char* str, char** end, int base) { + if (str[0] == '-') { + *end = const_cast<char*>(str); + return 0; + } + return strtoull(str, end, base); + } +}; + +struct StringToLongLongTraits + : public StringToSignedIntegerTraits<long long, long long> { + static LongType Convert(const char* str, char** end, int base) { + return strtoll(str, end, base); + } +}; + +struct StringToUnsignedLongLongTraits + : public StringToUnsignedIntegerTraits<unsigned long long, + unsigned long long> { static LongType Convert(const char* str, char** end, int base) { if (str[0] == '-') { *end = const_cast<char*>(str); @@ -136,7 +155,7 @@ end != string.data() + string.length()) { return false; } - *number = result; + *number = static_cast<IntType>(result); return true; } @@ -152,12 +171,21 @@ return StringToIntegerInternal<StringToUnsignedIntTraits>(string, number); } -bool StringToNumber(const std::string& string, int64_t* number) { - return StringToIntegerInternal<StringToInt64Traits>(string, number); +bool StringToNumber(const std::string& string, long* number) { + return StringToIntegerInternal<StringToLongTraits>(string, number); } -bool StringToNumber(const std::string& string, uint64_t* number) { - return StringToIntegerInternal<StringToUnsignedInt64Traits>(string, number); +bool StringToNumber(const std::string& string, unsigned long* number) { + return StringToIntegerInternal<StringToUnsignedLongTraits>(string, number); +} + +bool StringToNumber(const std::string& string, long long* number) { + return StringToIntegerInternal<StringToLongLongTraits>(string, number); +} + +bool StringToNumber(const std::string& string, unsigned long long* number) { + return StringToIntegerInternal<StringToUnsignedLongLongTraits>(string, + number); } } // namespace crashpad
diff --git a/third_party/crashpad/crashpad/util/stdlib/string_number_conversion.h b/third_party/crashpad/crashpad/util/stdlib/string_number_conversion.h index b5f1d44a..69e7fdd 100644 --- a/third_party/crashpad/crashpad/util/stdlib/string_number_conversion.h +++ b/third_party/crashpad/crashpad/util/stdlib/string_number_conversion.h
@@ -56,8 +56,10 @@ //! where such prefix recognition is desirable. bool StringToNumber(const std::string& string, int* number); bool StringToNumber(const std::string& string, unsigned int* number); -bool StringToNumber(const std::string& string, int64_t* number); -bool StringToNumber(const std::string& string, uint64_t* number); +bool StringToNumber(const std::string& string, long* number); +bool StringToNumber(const std::string& string, unsigned long* number); +bool StringToNumber(const std::string& string, long long* number); +bool StringToNumber(const std::string& string, unsigned long long* number); //! \} } // namespace crashpad
diff --git a/third_party/crashpad/crashpad/util/stdlib/string_number_conversion_test.cc b/third_party/crashpad/crashpad/util/stdlib/string_number_conversion_test.cc index 689b4ad..760dc4a 100644 --- a/third_party/crashpad/crashpad/util/stdlib/string_number_conversion_test.cc +++ b/third_party/crashpad/crashpad/util/stdlib/string_number_conversion_test.cc
@@ -16,30 +16,39 @@ #include <sys/types.h> +#include <array> #include <limits> +#include <type_traits> #include "base/stl_util.h" #include "gtest/gtest.h" -namespace crashpad { -namespace test { -namespace { +#define STRINGIFY(a) STR(a) +#define STR(a) #a -TEST(StringNumberConversion, StringToInt) { - static constexpr struct { - const char* string; - bool valid; - int value; - } kTestData[] = { +template <typename TValueType> +struct TestSpecification { + const char* string; + bool valid; + TValueType value; +}; + +// Signed 32-bit test data +template <typename TIntType, + typename std::enable_if<std::is_integral<TIntType>::value && + std::is_signed<TIntType>::value && + (sizeof(TIntType) == 4)>::type* = nullptr> +static constexpr std::array<TestSpecification<TIntType>, 61> kTestDataFunc() { + return {{ {"", false, 0}, {"0", true, 0}, {"1", true, 1}, - {"2147483647", true, std::numeric_limits<int>::max()}, + {"2147483647", true, std::numeric_limits<TIntType>::max()}, {"2147483648", false, 0}, {"4294967295", false, 0}, {"4294967296", false, 0}, {"-1", true, -1}, - {"-2147483648", true, std::numeric_limits<int>::min()}, + {"-2147483648", true, std::numeric_limits<TIntType>::min()}, {"-2147483649", false, 0}, {"00", true, 0}, {"01", true, 1}, @@ -50,12 +59,12 @@ {"+0x20", true, 32}, {"0xf", true, 15}, {"0xg", false, 0}, - {"0x7fffffff", true, std::numeric_limits<int>::max()}, - {"0x7FfFfFfF", true, std::numeric_limits<int>::max()}, + {"0x7fffffff", true, std::numeric_limits<TIntType>::max()}, + {"0x7FfFfFfF", true, std::numeric_limits<TIntType>::max()}, {"0x80000000", false, 0}, {"0xFFFFFFFF", false, 0}, {"-0x7fffffff", true, -2147483647}, - {"-0x80000000", true, std::numeric_limits<int>::min()}, + {"-0x80000000", true, std::numeric_limits<TIntType>::min()}, {"-0x80000001", false, 0}, {"-0xffffffff", false, 0}, {"0x100000000", false, 0}, @@ -92,45 +101,22 @@ {"9223372036854775809", false, 0}, {"18446744073709551615", false, 0}, {"18446744073709551616", false, 0}, - }; - - for (size_t index = 0; index < base::size(kTestData); ++index) { - int value; - bool valid = StringToNumber(kTestData[index].string, &value); - if (kTestData[index].valid) { - EXPECT_TRUE(valid) << "index " << index << ", string " - << kTestData[index].string; - if (valid) { - EXPECT_EQ(value, kTestData[index].value) - << "index " << index << ", string " << kTestData[index].string; - } - } else { - EXPECT_FALSE(valid) << "index " << index << ", string " - << kTestData[index].string << ", value " << value; - } - } - - // Ensure that embedded NUL characters are treated as bad input. The string - // is split to avoid MSVC warning: - // "decimal digit terminates octal escape sequence". - static constexpr char input[] = "6\000" "6"; - std::string input_string(input, base::size(input) - 1); - int output; - EXPECT_FALSE(StringToNumber(input_string, &output)); + }}; } -TEST(StringNumberConversion, StringToUnsignedInt) { - static constexpr struct { - const char* string; - bool valid; - unsigned int value; - } kTestData[] = { +// Unsigned 32-bit test data +template <typename TIntType, + typename std::enable_if<std::is_integral<TIntType>::value && + !std::is_signed<TIntType>::value && + (sizeof(TIntType) == 4)>::type* = nullptr> +static constexpr std::array<TestSpecification<TIntType>, 61> kTestDataFunc() { + return {{ {"", false, 0}, {"0", true, 0}, {"1", true, 1}, {"2147483647", true, 2147483647}, {"2147483648", true, 2147483648}, - {"4294967295", true, std::numeric_limits<unsigned int>::max()}, + {"4294967295", true, std::numeric_limits<TIntType>::max()}, {"4294967296", false, 0}, {"-1", false, 0}, {"-2147483648", false, 0}, @@ -186,9 +172,121 @@ {"9223372036854775809", false, 0}, {"18446744073709551615", false, 0}, {"18446744073709551616", false, 0}, - }; + }}; +} - for (size_t index = 0; index < base::size(kTestData); ++index) { +// Signed 64-bit test data +template <typename TIntType, + typename std::enable_if<std::is_integral<TIntType>::value && + std::is_signed<TIntType>::value && + (sizeof(TIntType) == 8)>::type* = nullptr> +static constexpr std::array<TestSpecification<TIntType>, 24> kTestDataFunc() { + return {{ + {"", false, 0}, + {"0", true, 0}, + {"1", true, 1}, + {"2147483647", true, 2147483647}, + {"2147483648", true, 2147483648}, + {"4294967295", true, 4294967295}, + {"4294967296", true, 4294967296}, + {"9223372036854775807", true, std::numeric_limits<TIntType>::max()}, + {"9223372036854775808", false, 0}, + {"18446744073709551615", false, 0}, + {"18446744073709551616", false, 0}, + {"-1", true, -1}, + {"-2147483648", true, INT64_C(-2147483648)}, + {"-2147483649", true, INT64_C(-2147483649)}, + {"-9223372036854775808", true, std::numeric_limits<TIntType>::min()}, + {"-9223372036854775809", false, 0}, + {"0x7fffffffffffffff", true, std::numeric_limits<TIntType>::max()}, + {"0x8000000000000000", false, 0}, + {"0xffffffffffffffff", false, 0}, + {"0x10000000000000000", false, 0}, + {"-0x7fffffffffffffff", true, -9223372036854775807}, + {"-0x8000000000000000", true, std::numeric_limits<TIntType>::min()}, + {"-0x8000000000000001", false, 0}, + {"0x7Fffffffffffffff", true, std::numeric_limits<TIntType>::max()}, + }}; +} + +// Unsigned 64-bit test data +template <typename TIntType, + typename std::enable_if<std::is_integral<TIntType>::value && + !std::is_signed<TIntType>::value && + (sizeof(TIntType) == 8)>::type* = nullptr> +static constexpr std::array<TestSpecification<TIntType>, 25> kTestDataFunc() { + return {{ + {"", false, 0}, + {"0", true, 0}, + {"1", true, 1}, + {"2147483647", true, 2147483647}, + {"2147483648", true, 2147483648}, + {"4294967295", true, 4294967295}, + {"4294967296", true, 4294967296}, + {"9223372036854775807", true, 9223372036854775807}, + {"9223372036854775808", true, 9223372036854775808u}, + {"18446744073709551615", true, std::numeric_limits<TIntType>::max()}, + {"18446744073709551616", false, 0}, + {"-1", false, 0}, + {"-2147483648", false, 0}, + {"-2147483649", false, 0}, + {"-2147483648", false, 0}, + {"-9223372036854775808", false, 0}, + {"-9223372036854775809", false, 0}, + {"0x7fffffffffffffff", true, 9223372036854775807}, + {"0x8000000000000000", true, 9223372036854775808u}, + {"0xffffffffffffffff", true, std::numeric_limits<TIntType>::max()}, + {"0x10000000000000000", false, 0}, + {"-0x7fffffffffffffff", false, 0}, + {"-0x8000000000000000", false, 0}, + {"-0x8000000000000001", false, 0}, + {"0xFfffffffffffffff", true, std::numeric_limits<TIntType>::max()}, + }}; +} + +// This string is split to avoid MSVC warning: +// "decimal digit terminates octal escape sequence". +static constexpr char kEmbeddedNullInputRaw[] = "6\000" "6"; + +namespace crashpad { +namespace test { +namespace { + +TEST(StringNumberConversion, StringToInt) { + static_assert(sizeof(int) == 4, "Test only configured for 32-bit int."); + static constexpr auto kTestData = kTestDataFunc<int>(); + + for (size_t index = 0; index < kTestData.size(); ++index) { + int value; + bool valid = StringToNumber(kTestData[index].string, &value); + if (kTestData[index].valid) { + EXPECT_TRUE(valid) << "index " << index << ", string " + << kTestData[index].string; + if (valid) { + EXPECT_EQ(value, kTestData[index].value) + << "index " << index << ", string " << kTestData[index].string; + } + } else { + EXPECT_FALSE(valid) << "index " << index << ", string " + << kTestData[index].string << ", value " << value; + } + } + + // Ensure that embedded NUL characters are treated as bad input. The string + // is split to avoid MSVC warning: + // "decimal digit terminates octal escape sequence". + int output; + std::string kEmbeddedNullInput(kEmbeddedNullInputRaw, + base::size(kEmbeddedNullInputRaw) - 1); + EXPECT_FALSE(StringToNumber(kEmbeddedNullInput, &output)); +} + +TEST(StringNumberConversion, StringToUnsignedInt) { + static_assert(sizeof(unsigned int) == 4, + "Test only configured for 32-bit unsigned int."); + static constexpr auto kTestData = kTestDataFunc<unsigned int>(); + + for (size_t index = 0; index < kTestData.size(); ++index) { unsigned int value; bool valid = StringToNumber(kTestData[index].string, &value); if (kTestData[index].valid) { @@ -207,46 +305,20 @@ // Ensure that embedded NUL characters are treated as bad input. The string // is split to avoid MSVC warning: // "decimal digit terminates octal escape sequence". - static constexpr char input[] = "6\000" "6"; - std::string input_string(input, base::size(input) - 1); unsigned int output; - EXPECT_FALSE(StringToNumber(input_string, &output)); + std::string kEmbeddedNullInput(kEmbeddedNullInputRaw, + base::size(kEmbeddedNullInputRaw) - 1); + EXPECT_FALSE(StringToNumber(kEmbeddedNullInput, &output)); } -TEST(StringNumberConversion, StringToInt64) { - static constexpr struct { - const char* string; - bool valid; - int64_t value; - } kTestData[] = { - {"", false, 0}, - {"0", true, 0}, - {"1", true, 1}, - {"2147483647", true, 2147483647}, - {"2147483648", true, 2147483648}, - {"4294967295", true, 4294967295}, - {"4294967296", true, 4294967296}, - {"9223372036854775807", true, std::numeric_limits<int64_t>::max()}, - {"9223372036854775808", false, 0}, - {"18446744073709551615", false, 0}, - {"18446744073709551616", false, 0}, - {"-1", true, -1}, - {"-2147483648", true, INT64_C(-2147483648)}, - {"-2147483649", true, INT64_C(-2147483649)}, - {"-9223372036854775808", true, std::numeric_limits<int64_t>::min()}, - {"-9223372036854775809", false, 0}, - {"0x7fffffffffffffff", true, std::numeric_limits<int64_t>::max()}, - {"0x8000000000000000", false, 0}, - {"0xffffffffffffffff", false, 0}, - {"0x10000000000000000", false, 0}, - {"-0x7fffffffffffffff", true, -9223372036854775807}, - {"-0x8000000000000000", true, std::numeric_limits<int64_t>::min()}, - {"-0x8000000000000001", false, 0}, - {"0x7Fffffffffffffff", true, std::numeric_limits<int64_t>::max()}, - }; +TEST(StringNumberConversion, StringToLong) { + static_assert( + sizeof(long) == 4 || sizeof(long) == 8, + "Test not configured for " STRINGIFY(__SIZEOF_LONG__) "-byte long"); + static constexpr auto kTestData = kTestDataFunc<long>(); - for (size_t index = 0; index < base::size(kTestData); ++index) { - int64_t value; + for (size_t index = 0; index < kTestData.size(); ++index) { + long value; bool valid = StringToNumber(kTestData[index].string, &value); if (kTestData[index].valid) { EXPECT_TRUE(valid) << "index " << index << ", string " @@ -262,41 +334,58 @@ } } -TEST(StringNumberConversion, StringToUnsignedInt64) { - static constexpr struct { - const char* string; - bool valid; - uint64_t value; - } kTestData[] = { - {"", false, 0}, - {"0", true, 0}, - {"1", true, 1}, - {"2147483647", true, 2147483647}, - {"2147483648", true, 2147483648}, - {"4294967295", true, 4294967295}, - {"4294967296", true, 4294967296}, - {"9223372036854775807", true, 9223372036854775807}, - {"9223372036854775808", true, 9223372036854775808u}, - {"18446744073709551615", true, std::numeric_limits<uint64_t>::max()}, - {"18446744073709551616", false, 0}, - {"-1", false, 0}, - {"-2147483648", false, 0}, - {"-2147483649", false, 0}, - {"-2147483648", false, 0}, - {"-9223372036854775808", false, 0}, - {"-9223372036854775809", false, 0}, - {"0x7fffffffffffffff", true, 9223372036854775807}, - {"0x8000000000000000", true, 9223372036854775808u}, - {"0xffffffffffffffff", true, std::numeric_limits<uint64_t>::max()}, - {"0x10000000000000000", false, 0}, - {"-0x7fffffffffffffff", false, 0}, - {"-0x8000000000000000", false, 0}, - {"-0x8000000000000001", false, 0}, - {"0xFfffffffffffffff", true, std::numeric_limits<uint64_t>::max()}, - }; +TEST(StringNumberConversion, StringToUnsignedLong) { + static_assert( + sizeof(long) == 4 || sizeof(long) == 8, + "Test not configured for " STRINGIFY(__SIZEOF_LONG__) "-byte long"); + static constexpr auto kTestData = kTestDataFunc<unsigned long>(); - for (size_t index = 0; index < base::size(kTestData); ++index) { - uint64_t value; + for (size_t index = 0; index < kTestData.size(); ++index) { + unsigned long value; + bool valid = StringToNumber(kTestData[index].string, &value); + if (kTestData[index].valid) { + EXPECT_TRUE(valid) << "index " << index << ", string " + << kTestData[index].string; + if (valid) { + EXPECT_EQ(value, kTestData[index].value) + << "index " << index << ", string " << kTestData[index].string; + } + } else { + EXPECT_FALSE(valid) << "index " << index << ", string " + << kTestData[index].string << ", value " << value; + } + } +} + +TEST(StringNumberConversion, StringToLongLong) { + static_assert(sizeof(long long) == 8, + "Test only configured for 64-bit long long."); + static constexpr auto kTestData = kTestDataFunc<long long>(); + + for (size_t index = 0; index < kTestData.size(); ++index) { + long long value; + bool valid = StringToNumber(kTestData[index].string, &value); + if (kTestData[index].valid) { + EXPECT_TRUE(valid) << "index " << index << ", string " + << kTestData[index].string; + if (valid) { + EXPECT_EQ(value, kTestData[index].value) + << "index " << index << ", string " << kTestData[index].string; + } + } else { + EXPECT_FALSE(valid) << "index " << index << ", string " + << kTestData[index].string << ", value " << value; + } + } +} + +TEST(StringNumberConversion, StringToUnsignedLongLong) { + static_assert(sizeof(unsigned long long) == 8, + "Test only configured for 64-bit unsigned long long."); + static constexpr auto kTestData = kTestDataFunc<unsigned long long>(); + + for (size_t index = 0; index < kTestData.size(); ++index) { + unsigned long long value; bool valid = StringToNumber(kTestData[index].string, &value); if (kTestData[index].valid) { EXPECT_TRUE(valid) << "index " << index << ", string "
diff --git a/third_party/libpng/LICENSE b/third_party/libpng/LICENSE index c1d22b1f..e0c5b53 100644 --- a/third_party/libpng/LICENSE +++ b/third_party/libpng/LICENSE
@@ -1,55 +1,82 @@ +COPYRIGHT NOTICE, DISCLAIMER, and LICENSE +========================================= -This copy of the libpng notices is provided for your convenience. In case of -any discrepancy between this copy and the notices in the file png.h that is -included in the libpng distribution, the latter shall prevail. +PNG Reference Library License version 2 +--------------------------------------- -COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: + * Copyright (c) 1995-2019 The PNG Reference Library Authors. + * Copyright (c) 2018-2019 Cosmin Truta. + * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson. + * Copyright (c) 1996-1997 Andreas Dilger. + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. -If you modify libpng you may insert additional notices immediately following -this sentence. +The software is supplied "as is", without warranty of any kind, +express or implied, including, without limitation, the warranties +of merchantability, fitness for a particular purpose, title, and +non-infringement. In no event shall the Copyright owners, or +anyone distributing the software, be liable for any damages or +other liability, whether in contract, tort or otherwise, arising +from, out of, or in connection with the software, or the use or +other dealings in the software, even if advised of the possibility +of such damage. -Using custom versions of pnglibconf.h and pngprefix.h for Chrome. +Permission is hereby granted to use, copy, modify, and distribute +this software, or portions hereof, for any purpose, without fee, +subject to the following restrictions: -This code is released under the libpng license. + 1. The origin of this software must not be misrepresented; you + must not claim that you wrote the original software. If you + use this software in a product, an acknowledgment in the product + documentation would be appreciated, but is not required. -libpng versions 1.0.7, July 1, 2000 through 1.6.34, September 29, 2017 are -Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are + 2. Altered source versions must be plainly marked as such, and must + not be misrepresented as being the original software. + + 3. This Copyright notice may not be removed or altered from any + source or altered source distribution. + + +PNG Reference Library License version 1 (for libpng 0.5 through 1.6.35) +----------------------------------------------------------------------- + +libpng versions 1.0.7, July 1, 2000, through 1.6.35, July 15, 2018 are +Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are derived from libpng-1.0.6, and are distributed according to the same disclaimer and license as libpng-1.0.6 with the following individuals added to the list of Contributing Authors: - Simon-Pierre Cadieux - Eric S. Raymond - Mans Rullgard - Cosmin Truta - Gilles Vollant - James Yu - Mandar Sahastrabuddhe - Google Inc. - Vadim Barkov + Simon-Pierre Cadieux + Eric S. Raymond + Mans Rullgard + Cosmin Truta + Gilles Vollant + James Yu + Mandar Sahastrabuddhe + Google Inc. + Vadim Barkov and with the following additions to the disclaimer: - There is no warranty against interference with your enjoyment of the - library or against infringement. There is no warranty that our - efforts or the library will fulfill any of your particular purposes - or needs. This library is provided with all faults, and the entire - risk of satisfactory quality, performance, accuracy, and effort is with - the user. + There is no warranty against interference with your enjoyment of + the library or against infringement. There is no warranty that our + efforts or the library will fulfill any of your particular purposes + or needs. This library is provided with all faults, and the entire + risk of satisfactory quality, performance, accuracy, and effort is + with the user. Some files in the "contrib" directory and some configure-generated -files that are distributed with libpng have other copyright owners and +files that are distributed with libpng have other copyright owners, and are released under other open source licenses. libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from libpng-0.96, and are distributed according to the same disclaimer and -license as libpng-0.96, with the following individuals added to the list -of Contributing Authors: +license as libpng-0.96, with the following individuals added to the +list of Contributing Authors: - Tom Lane - Glenn Randers-Pehrson - Willem van Schaik + Tom Lane + Glenn Randers-Pehrson + Willem van Schaik libpng versions 0.89, June 1996, through 0.96, May 1997, are Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88, @@ -57,14 +84,14 @@ libpng-0.88, with the following individuals added to the list of Contributing Authors: - John Bowler - Kevin Bracey - Sam Bushell - Magnus Holmgren - Greg Roelofs - Tom Tanner + John Bowler + Kevin Bracey + Sam Bushell + Magnus Holmgren + Greg Roelofs + Tom Tanner -Some files in the "scripts" directory have other copyright owners +Some files in the "scripts" directory have other copyright owners, but are released under this license. libpng versions 0.5, May 1995, through 0.88, January 1996, are @@ -73,63 +100,35 @@ For the purposes of this copyright and license, "Contributing Authors" is defined as the following set of individuals: - Andreas Dilger - Dave Martindale - Guy Eric Schalnat - Paul Schmidt - Tim Wegner + Andreas Dilger + Dave Martindale + Guy Eric Schalnat + Paul Schmidt + Tim Wegner -The PNG Reference Library is supplied "AS IS". The Contributing Authors -and Group 42, Inc. disclaim all warranties, expressed or implied, -including, without limitation, the warranties of merchantability and of -fitness for any purpose. The Contributing Authors and Group 42, Inc. -assume no liability for direct, indirect, incidental, special, exemplary, -or consequential damages, which may result from the use of the PNG -Reference Library, even if advised of the possibility of such damage. +The PNG Reference Library is supplied "AS IS". The Contributing +Authors and Group 42, Inc. disclaim all warranties, expressed or +implied, including, without limitation, the warranties of +merchantability and of fitness for any purpose. The Contributing +Authors and Group 42, Inc. assume no liability for direct, indirect, +incidental, special, exemplary, or consequential damages, which may +result from the use of the PNG Reference Library, even if advised of +the possibility of such damage. Permission is hereby granted to use, copy, modify, and distribute this source code, or portions hereof, for any purpose, without fee, subject to the following restrictions: - 1. The origin of this source code must not be misrepresented. + 1. The origin of this source code must not be misrepresented. - 2. Altered versions must be plainly marked as such and must not - be misrepresented as being the original source. + 2. Altered versions must be plainly marked as such and must not + be misrepresented as being the original source. - 3. This Copyright notice may not be removed or altered from any - source or altered source distribution. + 3. This Copyright notice may not be removed or altered from any + source or altered source distribution. -The Contributing Authors and Group 42, Inc. specifically permit, without -fee, and encourage the use of this source code as a component to -supporting the PNG file format in commercial products. If you use this -source code in a product, acknowledgment is not required but would be -appreciated. - -END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE. - -TRADEMARK: - -The name "libpng" has not been registered by the Copyright owner -as a trademark in any jurisdiction. However, because libpng has -been distributed and maintained world-wide, continually since 1995, -the Copyright owner claims "common-law trademark protection" in any -jurisdiction where common-law trademark is recognized. - -OSI CERTIFICATION: - -Libpng is OSI Certified Open Source Software. OSI Certified Open Source is -a certification mark of the Open Source Initiative. OSI has not addressed -the additional disclaimers inserted at version 1.0.7. - -EXPORT CONTROL: - -The Copyright owner believes that the Export Control Classification -Number (ECCN) for libpng is EAR99, which means not subject to export -controls or International Traffic in Arms Regulations (ITAR) because -it is open source, publicly available software, that does not contain -any encryption software. See the EAR, paragraphs 734.3(b)(3) and -734.7(b). - -Glenn Randers-Pehrson -glennrp at users.sourceforge.net -September 29, 2017 +The Contributing Authors and Group 42, Inc. specifically permit, +without fee, and encourage the use of this source code as a component +to supporting the PNG file format in commercial products. If you use +this source code in a product, acknowledgment is not required but would +be appreciated.
diff --git a/third_party/libpng/README b/third_party/libpng/README index f098b27..cfc1f0e 100644 --- a/third_party/libpng/README +++ b/third_party/libpng/README
@@ -1,15 +1,16 @@ -README for libpng version 1.6.35 - July 15, 2018 (shared library 16.0) -See the note about version numbers near the top of png.h +README for libpng version 1.6.37 - April 14, 2019 +================================================= +See the note about version numbers near the top of png.h. See INSTALL for instructions on how to install libpng. Libpng comes in several distribution formats. Get libpng-*.tar.gz or -libpng-*.tar.xz or if you want UNIX-style line endings in the text files, -or lpng*.7z or lpng*.zip if you want DOS-style line endings. +libpng-*.tar.xz or if you want UNIX-style line endings in the text +files, or lpng*.7z or lpng*.zip if you want DOS-style line endings. Version 0.89 was the first official release of libpng. Don't let the -fact that it's the first release fool you. The libpng library has been in -extensive use and testing since mid-1995. By late 1997 it had +fact that it's the first release fool you. The libpng library has been +in extensive use and testing since mid-1995. By late 1997 it had finally gotten to the stage where there hadn't been significant changes to the API in some time, and people have a bad feeling about libraries with versions < 1.0. Version 1.0.0 was released in @@ -60,59 +61,37 @@ to set different actions based on whether the CRC error occurred in a critical or an ancillary chunk. -The changes made to the library, and bugs fixed are based on discussions -on the PNG-implement mailing list and not on material submitted -privately to Guy, Andreas, or Glenn. They will forward any good -suggestions to the list. - -For a detailed description on using libpng, read libpng-manual.txt. For -examples of libpng in a program, see example.c and pngtest.c. For usage -information and restrictions (what little they are) on libpng, see -png.h. For a description on using zlib (the compression library used by -libpng) and zlib's restrictions, see zlib.h +For a detailed description on using libpng, read libpng-manual.txt. +For examples of libpng in a program, see example.c and pngtest.c. For +usage information and restrictions (what little they are) on libpng, +see png.h. For a description on using zlib (the compression library +used by libpng) and zlib's restrictions, see zlib.h I have included a general makefile, as well as several machine and -compiler specific ones, but you may have to modify one for your own needs. +compiler specific ones, but you may have to modify one for your own +needs. You should use zlib 1.0.4 or later to run this, but it MAY work with versions as old as zlib 0.95. Even so, there are bugs in older zlib versions which can cause the output of invalid compression streams for -some images. You will definitely need zlib 1.0.4 or later if you are -taking advantage of the MS-DOS "far" structure allocation for the small -and medium memory models. You should also note that zlib is a -compression library that is useful for more things than just PNG files. -You can use zlib as a drop-in replacement for fread() and fwrite() if -you are so inclined. +some images. -zlib should be available at the same place that libpng is, or at zlib.net. +You should also note that zlib is a compression library that is useful +for more things than just PNG files. You can use zlib as a drop-in +replacement for fread() and fwrite(), if you are so inclined. + +zlib should be available at the same place that libpng is, or at +https://zlib.net. You may also want a copy of the PNG specification. It is available as an RFC, a W3C Recommendation, and an ISO/IEC Standard. You can find these at http://www.libpng.org/pub/png/pngdocs.html . This code is currently being archived at libpng.sourceforge.io in the -[DOWNLOAD] area, and at http://libpng.download/src . If you -can't find it in any of those places, e-mail me, and I'll help you find it. +[DOWNLOAD] area, and at http://libpng.download/src . -I am not a lawyer, but I believe that the Export Control Classification -Number (ECCN) for libpng is EAR99, which means not subject to export -controls or International Traffic in Arms Regulations (ITAR) because it -is open source, publicly available software, that does not contain any -encryption software. See the EAR, paragraphs 734.3(b)(3) and 734.7(b). - -If you have any code changes, requests, problems, etc., please e-mail -them to me. Also, I'd appreciate any make files or project files, -and any modifications you needed to make to get libpng to compile, -along with a #define variable to tell what compiler/system you are on. -If you needed to add transformations to libpng, or wish libpng would -provide the image in a different way, drop me a note (and code, if -possible), so I can consider supporting the transformation. -Finally, if you get any warning messages when compiling libpng -(note: not zlib), and they are easy to fix, I'd appreciate the -fix. Please mention "libpng" somewhere in the subject line. Thanks. - -This release was created and will be supported by myself (of course -based in a large way on Guy's and Andreas' earlier work), and the PNG +This release, based in a large way on Glenn's, Guy's and Andreas' +earlier work, was created and will be supported by myself and the PNG development group. Send comments/corrections/commendations to png-mng-implement at @@ -120,34 +99,21 @@ https://lists.sourceforge.net/lists/listinfo/png-mng-implement to subscribe). -You can't reach Guy, the original libpng author, at the addresses -given in previous versions of this document. He and Andreas will -read mail addressed to the png-implement list, however. - -Please do not send general questions about PNG. Send them to -png-mng-misc at lists.sf.net (subscription required; visit +Send general questions about the PNG specification to png-mng-misc +at lists.sourceforge.net (subscription required; visit https://lists.sourceforge.net/lists/listinfo/png-mng-misc to -subscribe). If you have a question about something -in the PNG specification that is related to using libpng, send it -to me. Send me any questions that start with "I was using libpng, -and ...". If in doubt, send questions to me. I'll bounce them -to others, if necessary. - -Please do not send suggestions on how to change PNG. We have -been discussing PNG for twenty years now, and it is official and -finished. If you have suggestions for libpng, however, I'll -gladly listen. Even if your suggestion is not used immediately, -it may be used later. +subscribe). Files in this distribution: ANNOUNCE => Announcement of this version, with recent changes + AUTHORS => List of contributing authors CHANGES => Description of changes between libpng versions KNOWNBUG => List of known bugs and deficiencies LICENSE => License to use and redistribute libpng README => This file TODO => Things not implemented in the current library - Y2KINFO => Statement of Y2K compliance + TRADEMARK => Trademark information example.c => Example code for using libpng functions libpng.3 => manual page for libpng (includes libpng-manual.txt) libpng-manual.txt => Description of libpng and its functions @@ -208,15 +174,10 @@ scripts => Directory containing scripts for building libpng: (see scripts/README.txt for the list of scripts) -Good luck, and happy coding. +Good luck, and happy coding! --Glenn Randers-Pehrson (current maintainer, since 1998) - Internet: glennrp at users.sourceforge.net - --Andreas Eric Dilger (former maintainer, 1996-1997) - Internet: adilger at enel.ucalgary.ca - Web: http://www-mddsp.enel.ucalgary.ca/People/adilger/ - --Guy Eric Schalnat (original author and former maintainer, 1995-1996) - (formerly of Group 42, Inc) - Internet: gschal at infinet.com + * Cosmin Truta (current maintainer, since 2018) + * Glenn Randers-Pehrson (former maintainer, 1998-2018) + * Andreas Eric Dilger (former maintainer, 1996-1997) + * Guy Eric Schalnat (original author and former maintainer, 1995-1996) + (formerly of Group 42, Inc.)
diff --git a/third_party/libpng/README.chromium b/third_party/libpng/README.chromium index ada0e67..119187f 100644 --- a/third_party/libpng/README.chromium +++ b/third_party/libpng/README.chromium
@@ -1,25 +1,23 @@ Name: libpng URL: http://libpng.org/ -Version: 1.6.35 +Version: 1.6.37 Security Critical: yes License: libpng license License Android Compatible: yes Description: -Updated to 1.6.35, stripped all unneeded files. +Updated to 1.6.37, stripped all unneeded files. - Use custom configuration file pnglibconf.h, which turns off all features that are not in use. - Use custom prefix file pngprefix.h, which avoids namespace conflicts with pdfium's copy of libpng. - Configures custom png chunk user limits (crbug.com/117369) in pnglibconf.h. -- Applies the patch in patches/0000-plte.patch for ARM NEON optimizations (this - change has been accepted to upstream [1] but not yet released). - Applies the patch in patches/0001-chunkerror.patch (modify png_check_chunk_length to call png_benign_error instead of png_chunk_error -- see crbug.com/827754). - Keeps the fuzz target in contrib/oss-fuzz/ for running on clusterfuzz. - Applies the patch in patches/0002-fuzzeroom.patch to prevent clusterfuzz running into OOM errors. - -[1] https://github.com/glennrp/libpng/pull/203 \ No newline at end of file +- Applies the patch from https://github.com/glennrp/libpng/pull/285 to keep + clang-cl build working.
diff --git a/third_party/libpng/arm/arm_init.c b/third_party/libpng/arm/arm_init.c index 02df812..a34ecdbe 100644 --- a/third_party/libpng/arm/arm_init.c +++ b/third_party/libpng/arm/arm_init.c
@@ -1,14 +1,15 @@ /* arm_init.c - NEON optimised filter functions * + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 2014,2016 Glenn Randers-Pehrson * Written by Mans Rullgard, 2011. - * Last changed in libpng 1.6.22 [May 26, 2016] * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h */ + /* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are * called. */
diff --git a/third_party/libpng/arm/filter_neon.S b/third_party/libpng/arm/filter_neon.S index 000764cd..2308aad1 100644 --- a/third_party/libpng/arm/filter_neon.S +++ b/third_party/libpng/arm/filter_neon.S
@@ -1,9 +1,9 @@ /* filter_neon.S - NEON optimised filter functions * + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 2014,2017 Glenn Randers-Pehrson * Written by Mans Rullgard, 2011. - * Last changed in libpng 1.6.31 [July 27, 2017] * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer
diff --git a/third_party/libpng/arm/filter_neon_intrinsics.c b/third_party/libpng/arm/filter_neon_intrinsics.c index ea7e356b..0647bfa 100644 --- a/third_party/libpng/arm/filter_neon_intrinsics.c +++ b/third_party/libpng/arm/filter_neon_intrinsics.c
@@ -1,12 +1,11 @@ /* filter_neon_intrinsics.c - NEON optimised filter functions * + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 2014,2016 Glenn Randers-Pehrson * Written by James Yu <james.yu at linaro.org>, October 2013. * Based on filter_neon.S, written by Mans Rullgard, 2011. * - * Last changed in libpng 1.6.22 [May 26, 2016] - * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h @@ -19,7 +18,11 @@ /* This code requires -mfpu=neon on the command line: */ #if PNG_ARM_NEON_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */ -#include <arm_neon.h> +#if defined(_MSC_VER) && defined(_M_ARM64) && !defined(__clang__) +# include <arm64_neon.h> +#else +# include <arm_neon.h> +#endif /* libpng row pointers are not necessarily aligned to any particular boundary, * however this code will only work with appropriate alignment. arm/arm_init.c @@ -33,6 +36,11 @@ * 'type'. This is written this way just to hide the GCC strict aliasing * warning; note that the code is safe because there never is an alias between * the input and output pointers. + * + * When compiling with MSVC ARM64, the png_ldr macro can't be passed directly + * to vst4_lane_u32, because of an internal compiler error inside MSVC. + * To avoid this compiler bug, we use a temporary variable (vdest_val) to store + * the result of png_ldr. */ #define png_ldr(type,pointer)\ (temp_pointer = png_ptr(type,pointer), *temp_pointer) @@ -125,12 +133,15 @@ uint8x8x4_t *vrpt = png_ptr(uint8x8x4_t,&vtmp); uint8x8x4_t vrp = *vrpt; uint32x2x4_t *temp_pointer; + uint32x2x4_t vdest_val; vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]); vdest.val[1] = vadd_u8(vdest.val[0], vrp.val[1]); vdest.val[2] = vadd_u8(vdest.val[1], vrp.val[2]); vdest.val[3] = vadd_u8(vdest.val[2], vrp.val[3]); - vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0); + + vdest_val = png_ldr(uint32x2x4_t, &vdest); + vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0); } PNG_UNUSED(prev_row) @@ -223,6 +234,7 @@ uint8x8x4_t *vrpt, *vppt; uint8x8x4_t vrp, vpp; uint32x2x4_t *temp_pointer; + uint32x2x4_t vdest_val; vtmp = vld4_u32(png_ptr(uint32_t,rp)); vrpt = png_ptr(uint8x8x4_t,&vtmp); @@ -240,7 +252,8 @@ vdest.val[3] = vhadd_u8(vdest.val[2], vpp.val[3]); vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]); - vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0); + vdest_val = png_ldr(uint32x2x4_t, &vdest); + vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0); } } @@ -359,6 +372,7 @@ uint8x8x4_t *vrpt, *vppt; uint8x8x4_t vrp, vpp; uint32x2x4_t *temp_pointer; + uint32x2x4_t vdest_val; vtmp = vld4_u32(png_ptr(uint32_t,rp)); vrpt = png_ptr(uint8x8x4_t,&vtmp); @@ -378,7 +392,8 @@ vlast = vpp.val[3]; - vst4_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2x4_t,&vdest), 0); + vdest_val = png_ldr(uint32x2x4_t, &vdest); + vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0); } }
diff --git a/third_party/libpng/arm/palette_neon_intrinsics.c b/third_party/libpng/arm/palette_neon_intrinsics.c index 703b9ff..8217d65 100644 --- a/third_party/libpng/arm/palette_neon_intrinsics.c +++ b/third_party/libpng/arm/palette_neon_intrinsics.c
@@ -1,6 +1,8 @@ + /* palette_neon_intrinsics.c - NEON optimised palette expansion functions * - * Copyright (c) 2017 The Chromium Authors. All rights reserved. + * Copyright (c) 2018-2019 Cosmin Truta + * Copyright (c) 2017-2018 Arm Holdings. All rights reserved. * Written by Richard Townsend <Richard.Townsend@arm.com>, February 2017. * * This code is released under the libpng license. @@ -12,21 +14,23 @@ #if PNG_ARM_NEON_IMPLEMENTATION == 1 -#include <arm_neon.h> +#if defined(_MSC_VER) && defined(_M_ARM64) && !defined(__clang__) +# include <arm64_neon.h> +#else +# include <arm_neon.h> +#endif -/* Build an RGBA palette from the RGB and separate alpha palettes. */ +/* Build an RGBA8 palette from the separate RGB and alpha palettes. */ void -png_riffle_palette_rgba(png_structrp png_ptr, png_row_infop row_info) +png_riffle_palette_neon(png_structrp png_ptr) { png_const_colorp palette = png_ptr->palette; png_bytep riffled_palette = png_ptr->riffled_palette; png_const_bytep trans_alpha = png_ptr->trans_alpha; int num_trans = png_ptr->num_trans; + int i; - if (row_info->bit_depth != 8) { - png_error(png_ptr, "bit_depth must be 8 for png_riffle_palette_rgba"); - return; - } + png_debug(1, "in png_riffle_palette_neon"); /* Initially black, opaque. */ uint8x16x4_t w = {{ @@ -36,10 +40,11 @@ vdupq_n_u8(0xff), }}; - int i; - /* First, riffle the RGB colours into a RGBA palette, the A value is - * set to opaque for now. */ - for (i = 0; i < (1 << row_info->bit_depth); i += 16) { + /* First, riffle the RGB colours into an RGBA8 palette. + * The alpha component is set to opaque for now. + */ + for (i = 0; i < 256; i += 16) + { uint8x16x3_t v = vld3q_u8((png_const_bytep)(palette + i)); w.val[0] = v.val[0]; w.val[1] = v.val[1]; @@ -48,33 +53,34 @@ } /* Fix up the missing transparency values. */ - for (i = 0; i < num_trans; i++) { + for (i = 0; i < num_trans; i++) riffled_palette[(i << 2) + 3] = trans_alpha[i]; - } } - -/* Expands a palettized row into RGBA. */ +/* Expands a palettized row into RGBA8. */ int -png_do_expand_palette_neon_rgba(png_structrp png_ptr, png_row_infop row_info, - png_const_bytep row, const png_bytepp ssp, const png_bytepp ddp) +png_do_expand_palette_rgba8_neon(png_structrp png_ptr, png_row_infop row_info, + png_const_bytep row, png_bytepp ssp, png_bytepp ddp) { - png_uint_32 row_width = row_info->width; - const png_uint_32 *riffled_palette = (const png_uint_32*)png_ptr->riffled_palette; + const png_uint_32 *riffled_palette = + (const png_uint_32 *)png_ptr->riffled_palette; const png_int_32 pixels_per_chunk = 4; + int i; - if (row_width < pixels_per_chunk) { + png_debug(1, "in png_do_expand_palette_rgba8_neon"); + + if (row_width < pixels_per_chunk) return 0; - } /* This function originally gets the last byte of the output row. - The NEON part writes forward from a given position, so we have - to seek this back by 4 pixels x 4 bytes. */ + * The NEON part writes forward from a given position, so we have + * to seek this back by 4 pixels x 4 bytes. + */ *ddp = *ddp - ((pixels_per_chunk * sizeof(png_uint_32)) - 1); - int i; - for (i = 0; i < row_width; i += pixels_per_chunk) { + for (i = 0; i < row_width; i += pixels_per_chunk) + { uint32x4_t cur; png_bytep sp = *ssp - i, dp = *ddp - (i << 2); cur = vld1q_dup_u32 (riffled_palette + *(sp - 3)); @@ -83,8 +89,10 @@ cur = vld1q_lane_u32(riffled_palette + *(sp - 0), cur, 3); vst1q_u32((void *)dp, cur); } - if (i != row_width) { - i -= pixels_per_chunk; /* Remove the amount that wasn't processed. */ + if (i != row_width) + { + /* Remove the amount that wasn't processed. */ + i -= pixels_per_chunk; } /* Decrement output pointers. */ @@ -93,24 +101,26 @@ return i; } -/* Expands a palettized row into RGB format. */ +/* Expands a palettized row into RGB8. */ int -png_do_expand_palette_neon_rgb(png_structrp png_ptr, png_row_infop row_info, - png_const_bytep row, const png_bytepp ssp, const png_bytepp ddp) +png_do_expand_palette_rgb8_neon(png_structrp png_ptr, png_row_infop row_info, + png_const_bytep row, png_bytepp ssp, png_bytepp ddp) { png_uint_32 row_width = row_info->width; png_const_bytep palette = (png_const_bytep)png_ptr->palette; const png_uint_32 pixels_per_chunk = 8; + int i; - if (row_width <= pixels_per_chunk) { + png_debug(1, "in png_do_expand_palette_rgb8_neon"); + + if (row_width <= pixels_per_chunk) return 0; - } /* Seeking this back by 8 pixels x 3 bytes. */ *ddp = *ddp - ((pixels_per_chunk * sizeof(png_color)) - 1); - int i; - for (i = 0; i < row_width; i += pixels_per_chunk) { + for (i = 0; i < row_width; i += pixels_per_chunk) + { uint8x8x3_t cur; png_bytep sp = *ssp - i, dp = *ddp - ((i << 1) + i); cur = vld3_dup_u8(palette + sizeof(png_color) * (*(sp - 7))); @@ -124,8 +134,10 @@ vst3_u8((void *)dp, cur); } - if (i != row_width) { - i -= pixels_per_chunk; /* Remove the amount that wasn't processed. */ + if (i != row_width) + { + /* Remove the amount that wasn't processed. */ + i -= pixels_per_chunk; } /* Decrement output pointers. */
diff --git a/third_party/libpng/contrib/oss-fuzz/libpng_read_fuzzer.cc b/third_party/libpng/contrib/oss-fuzz/libpng_read_fuzzer.cc index 50032d6..2064a84 100644 --- a/third_party/libpng/contrib/oss-fuzz/libpng_read_fuzzer.cc +++ b/third_party/libpng/contrib/oss-fuzz/libpng_read_fuzzer.cc
@@ -60,7 +60,7 @@ png_free(png_ptr, row_ptr); if (end_info_ptr) png_destroy_read_struct(&png_ptr, &info_ptr, &end_info_ptr); - else if (info_ptr) + else if (info_ptr) png_destroy_read_struct(&png_ptr, &info_ptr, nullptr); else png_destroy_read_struct(&png_ptr, nullptr, nullptr);
diff --git a/third_party/libpng/intel/filter_sse2_intrinsics.c b/third_party/libpng/intel/filter_sse2_intrinsics.c index ef1fc7d..f52aaa8 100644 --- a/third_party/libpng/intel/filter_sse2_intrinsics.c +++ b/third_party/libpng/intel/filter_sse2_intrinsics.c
@@ -1,12 +1,11 @@ /* filter_sse2_intrinsics.c - SSE2 optimized filter functions * + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 2016-2017 Glenn Randers-Pehrson * Written by Mike Klein and Matt Sarett * Derived from arm/filter_neon_intrinsics.c * - * Last changed in libpng 1.6.31 [July 27, 2017] - * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h @@ -29,39 +28,25 @@ */ static __m128i load4(const void* p) { - return _mm_cvtsi32_si128(*(const int*)p); + int tmp; + memcpy(&tmp, p, sizeof(tmp)); + return _mm_cvtsi32_si128(tmp); } static void store4(void* p, __m128i v) { - *(int*)p = _mm_cvtsi128_si32(v); + int tmp = _mm_cvtsi128_si32(v); + memcpy(p, &tmp, sizeof(int)); } static __m128i load3(const void* p) { - /* We'll load 2 bytes, then 1 byte, - * then mask them together, and finally load into SSE. - */ - const png_uint_16* p01 = (png_const_uint_16p)p; - const png_byte* p2 = (const png_byte*)(p01+1); - - png_uint_32 v012 = (png_uint_32)(*p01) - | (png_uint_32)(*p2) << 16; - return load4(&v012); + png_uint_32 tmp = 0; + memcpy(&tmp, p, 3); + return _mm_cvtsi32_si128(tmp); } static void store3(void* p, __m128i v) { - /* We'll pull from SSE as a 32-bit int, then write - * its bottom two bytes, then its third byte. - */ - png_uint_32 v012; - png_uint_16* p01; - png_byte* p2; - - store4(&v012, v); - - p01 = (png_uint_16p)p; - p2 = (png_byte*)(p01+1); - *p01 = (png_uint_16)v012; - *p2 = (png_byte)(v012 >> 16); + int tmp = _mm_cvtsi128_si32(v); + memcpy(p, &tmp, 3); } void png_read_filter_row_sub3_sse2(png_row_infop row_info, png_bytep row,
diff --git a/third_party/libpng/intel/intel_init.c b/third_party/libpng/intel/intel_init.c index 8f08baf..2f8168b 100644 --- a/third_party/libpng/intel/intel_init.c +++ b/third_party/libpng/intel/intel_init.c
@@ -1,12 +1,11 @@ /* intel_init.c - SSE2 optimized filter functions * + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 2016-2017 Glenn Randers-Pehrson * Written by Mike Klein and Matt Sarett, Google, Inc. * Derived from arm/arm_init.c * - * Last changed in libpng 1.6.29 [March 16, 2017] - * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h
diff --git a/third_party/libpng/mips/filter_msa_intrinsics.c b/third_party/libpng/mips/filter_msa_intrinsics.c index 57056280..a5791794 100644 --- a/third_party/libpng/mips/filter_msa_intrinsics.c +++ b/third_party/libpng/mips/filter_msa_intrinsics.c
@@ -1,14 +1,15 @@ /* filter_msa_intrinsics.c - MSA optimised filter functions * + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 2016 Glenn Randers-Pehrson * Written by Mandar Sahastrabuddhe, August 2016. - * Last changed in libpng 1.6.25 [September 1, 2016] * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h */ + #include <stdio.h> #include <stdint.h> #include "../pngpriv.h"
diff --git a/third_party/libpng/mips/mips_init.c b/third_party/libpng/mips/mips_init.c index 0bfb7a3..8dd283d 100644 --- a/third_party/libpng/mips/mips_init.c +++ b/third_party/libpng/mips/mips_init.c
@@ -1,14 +1,15 @@ /* mips_init.c - MSA optimised filter functions * + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 2016 Glenn Randers-Pehrson * Written by Mandar Sahastrabuddhe, 2016. - * Last changed in libpng 1.6.25 [September 1, 2016] * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer * and license in png.h */ + /* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are * called. */
diff --git a/third_party/libpng/patches/0000-plte.patch b/third_party/libpng/patches/0000-plte.patch deleted file mode 100644 index 45a5dcf..0000000 --- a/third_party/libpng/patches/0000-plte.patch +++ /dev/null
@@ -1,1180 +0,0 @@ -From b764276b183d379d5b80e3f601ac42f574da5455 Mon Sep 17 00:00:00 2001 -From: Chris Blume <cblume@chromium.org> -Date: Tue, 16 Jan 2018 21:19:28 +0000 -Subject: [PATCH] Revert "Revert "libpng: Optimize png_do_expand_palette with - NEON."" - -This reverts commit 20a18ebc02429a40e4bc33fa28c4de29a39b609c. - -Reason for revert: <INSERT REASONING HERE> - -Original change's description: -> Revert "libpng: Optimize png_do_expand_palette with NEON." -> -> This reverts commit c4811af6d72836d44a3630beecebb0ff55875ab1. -> -> Reason for revert: This is failing to compile on ios-device-xcode-clang bot. -> -> https://uberchromegw.corp.google.com/i/chromium.mac/builders/ios-device-xcode-clang/builds/50225 -> -> Original change's description: -> > libpng: Optimize png_do_expand_palette with NEON. -> > -> > ARM-specific optimization processes 8 or 4 pixels at once. -> > -> > * Without transparency: 22% performance gain on the A53 little core. -> > * With transparency: 10% improvement on a big A72 core, 24% on little. -> > -> > (Numbers from image_decode_bench with PNG140 on the elm chromebook). -> > -> > Bug: 706134 -> > Change-Id: I7b4a93d72a0afa2823f3bf9ff5f798b88c843e54 -> > Reviewed-on: https://chromium-review.googlesource.com/817116 -> > Reviewed-by: Adenilson Cavalcanti <cavalcantii@chromium.org> -> > Reviewed-by: Mike Klein <mtklein@chromium.org> -> > Reviewed-by: Leon Scroggins <scroggo@chromium.org> -> > Reviewed-by: Chris Blume <cblume@chromium.org> -> > Commit-Queue: Adenilson Cavalcanti <cavalcantii@chromium.org> -> > Cr-Commit-Position: refs/heads/master@{#529473} -> -> TBR=scroggo@chromium.org,cavalcantii@chromium.org,richard.townsend@arm.com,cblume@chromium.org,mtklein@chromium.org -> -> Change-Id: I2cd943e15ceadf4311b1b49a56de00d10684e294 -> No-Presubmit: true -> No-Tree-Checks: true -> No-Try: true -> Bug: 706134 -> Reviewed-on: https://chromium-review.googlesource.com/868770 -> Reviewed-by: Jonathan Ross <jonross@chromium.org> -> Commit-Queue: Jonathan Ross <jonross@chromium.org> -> Cr-Commit-Position: refs/heads/master@{#529484} - -TBR=scroggo@chromium.org,jonross@chromium.org,cavalcantii@chromium.org,richard.townsend@arm.com,cblume@chromium.org,mtklein@chromium.org - -Change-Id: I6baf17d35efbd5c6bc348d4f81264e8e1023be4f -No-Presubmit: true -No-Tree-Checks: true -No-Try: true -Bug: 706134 ---- - third_party/libpng/BUILD.gn | 1 + - third_party/libpng/arm/palette_neon_intrinsics.c | 137 ++++ - third_party/libpng/patches/0000-plte.patch | 776 +++++++++++++++++++++++ - third_party/libpng/patches/README | 4 + - third_party/libpng/pngpriv.h | 23 + - third_party/libpng/pngrtran.c | 49 +- - third_party/libpng/pngstruct.h | 4 + - third_party/libpng/pngwrite.c | 4 + - 8 files changed, 990 insertions(+), 8 deletions(-) - create mode 100644 third_party/libpng/arm/palette_neon_intrinsics.c - create mode 100644 third_party/libpng/patches/0000-plte.patch - create mode 100644 third_party/libpng/patches/README - -diff --git a/third_party/libpng/BUILD.gn b/third_party/libpng/BUILD.gn -index e2658a7ba623..e48c790326c7 100644 ---- a/third_party/libpng/BUILD.gn -+++ b/third_party/libpng/BUILD.gn -@@ -75,6 +75,7 @@ source_set("libpng_sources") { - sources += [ - "arm/arm_init.c", - "arm/filter_neon_intrinsics.c", -+ "arm/palette_neon_intrinsics.c", - ] - defines += [ - "PNG_ARM_NEON_OPT=2", -diff --git a/third_party/libpng/arm/palette_neon_intrinsics.c b/third_party/libpng/arm/palette_neon_intrinsics.c -new file mode 100644 -index 000000000000..703b9ff25053 ---- /dev/null -+++ b/third_party/libpng/arm/palette_neon_intrinsics.c -@@ -0,0 +1,137 @@ -+/* palette_neon_intrinsics.c - NEON optimised palette expansion functions -+ * -+ * Copyright (c) 2017 The Chromium Authors. All rights reserved. -+ * Written by Richard Townsend <Richard.Townsend@arm.com>, February 2017. -+ * -+ * This code is released under the libpng license. -+ * For conditions of distribution and use, see the disclaimer -+ * and license in png.h -+ */ -+ -+#include "../pngpriv.h" -+ -+#if PNG_ARM_NEON_IMPLEMENTATION == 1 -+ -+#include <arm_neon.h> -+ -+/* Build an RGBA palette from the RGB and separate alpha palettes. */ -+void -+png_riffle_palette_rgba(png_structrp png_ptr, png_row_infop row_info) -+{ -+ png_const_colorp palette = png_ptr->palette; -+ png_bytep riffled_palette = png_ptr->riffled_palette; -+ png_const_bytep trans_alpha = png_ptr->trans_alpha; -+ int num_trans = png_ptr->num_trans; -+ -+ if (row_info->bit_depth != 8) { -+ png_error(png_ptr, "bit_depth must be 8 for png_riffle_palette_rgba"); -+ return; -+ } -+ -+ /* Initially black, opaque. */ -+ uint8x16x4_t w = {{ -+ vdupq_n_u8(0x00), -+ vdupq_n_u8(0x00), -+ vdupq_n_u8(0x00), -+ vdupq_n_u8(0xff), -+ }}; -+ -+ int i; -+ /* First, riffle the RGB colours into a RGBA palette, the A value is -+ * set to opaque for now. */ -+ for (i = 0; i < (1 << row_info->bit_depth); i += 16) { -+ uint8x16x3_t v = vld3q_u8((png_const_bytep)(palette + i)); -+ w.val[0] = v.val[0]; -+ w.val[1] = v.val[1]; -+ w.val[2] = v.val[2]; -+ vst4q_u8(riffled_palette + (i << 2), w); -+ } -+ -+ /* Fix up the missing transparency values. */ -+ for (i = 0; i < num_trans; i++) { -+ riffled_palette[(i << 2) + 3] = trans_alpha[i]; -+ } -+} -+ -+ -+/* Expands a palettized row into RGBA. */ -+int -+png_do_expand_palette_neon_rgba(png_structrp png_ptr, png_row_infop row_info, -+ png_const_bytep row, const png_bytepp ssp, const png_bytepp ddp) -+{ -+ -+ png_uint_32 row_width = row_info->width; -+ const png_uint_32 *riffled_palette = (const png_uint_32*)png_ptr->riffled_palette; -+ const png_int_32 pixels_per_chunk = 4; -+ -+ if (row_width < pixels_per_chunk) { -+ return 0; -+ } -+ -+ /* This function originally gets the last byte of the output row. -+ The NEON part writes forward from a given position, so we have -+ to seek this back by 4 pixels x 4 bytes. */ -+ *ddp = *ddp - ((pixels_per_chunk * sizeof(png_uint_32)) - 1); -+ -+ int i; -+ for (i = 0; i < row_width; i += pixels_per_chunk) { -+ uint32x4_t cur; -+ png_bytep sp = *ssp - i, dp = *ddp - (i << 2); -+ cur = vld1q_dup_u32 (riffled_palette + *(sp - 3)); -+ cur = vld1q_lane_u32(riffled_palette + *(sp - 2), cur, 1); -+ cur = vld1q_lane_u32(riffled_palette + *(sp - 1), cur, 2); -+ cur = vld1q_lane_u32(riffled_palette + *(sp - 0), cur, 3); -+ vst1q_u32((void *)dp, cur); -+ } -+ if (i != row_width) { -+ i -= pixels_per_chunk; /* Remove the amount that wasn't processed. */ -+ } -+ -+ /* Decrement output pointers. */ -+ *ssp = *ssp - i; -+ *ddp = *ddp - (i << 2); -+ return i; -+} -+ -+/* Expands a palettized row into RGB format. */ -+int -+png_do_expand_palette_neon_rgb(png_structrp png_ptr, png_row_infop row_info, -+ png_const_bytep row, const png_bytepp ssp, const png_bytepp ddp) -+{ -+ png_uint_32 row_width = row_info->width; -+ png_const_bytep palette = (png_const_bytep)png_ptr->palette; -+ const png_uint_32 pixels_per_chunk = 8; -+ -+ if (row_width <= pixels_per_chunk) { -+ return 0; -+ } -+ -+ /* Seeking this back by 8 pixels x 3 bytes. */ -+ *ddp = *ddp - ((pixels_per_chunk * sizeof(png_color)) - 1); -+ -+ int i; -+ for (i = 0; i < row_width; i += pixels_per_chunk) { -+ uint8x8x3_t cur; -+ png_bytep sp = *ssp - i, dp = *ddp - ((i << 1) + i); -+ cur = vld3_dup_u8(palette + sizeof(png_color) * (*(sp - 7))); -+ cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 6)), cur, 1); -+ cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 5)), cur, 2); -+ cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 4)), cur, 3); -+ cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 3)), cur, 4); -+ cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 2)), cur, 5); -+ cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 1)), cur, 6); -+ cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 0)), cur, 7); -+ vst3_u8((void *)dp, cur); -+ } -+ -+ if (i != row_width) { -+ i -= pixels_per_chunk; /* Remove the amount that wasn't processed. */ -+ } -+ -+ /* Decrement output pointers. */ -+ *ssp = *ssp - i; -+ *ddp = *ddp - ((i << 1) + i); -+ return i; -+} -+ -+#endif /* PNG_ARM_NEON_IMPLEMENTATION */ -diff --git a/third_party/libpng/patches/0000-plte.patch b/third_party/libpng/patches/0000-plte.patch -new file mode 100644 -index 000000000000..feea4d874335 ---- /dev/null -+++ b/third_party/libpng/patches/0000-plte.patch -@@ -0,0 +1,776 @@ -+From 5d94e310951211886ee460701176cb36c6e4bc88 Mon Sep 17 00:00:00 2001 -+From: Chris Blume <cblume@chromium.org> -+Date: Tue, 16 Jan 2018 21:19:28 +0000 -+Subject: [PATCH 1/2] Revert "Revert "libpng: Optimize png_do_expand_palette -+ with NEON."" -+ -+This reverts commit 20a18ebc02429a40e4bc33fa28c4de29a39b609c. -+ -+Reason for revert: <INSERT REASONING HERE> -+ -+Original change's description: -+> Revert "libpng: Optimize png_do_expand_palette with NEON." -+> -+> This reverts commit c4811af6d72836d44a3630beecebb0ff55875ab1. -+> -+> Reason for revert: This is failing to compile on ios-device-xcode-clang bot. -+> -+> https://uberchromegw.corp.google.com/i/chromium.mac/builders/ios-device-xcode-clang/builds/50225 -+> -+> Original change's description: -+> > libpng: Optimize png_do_expand_palette with NEON. -+> > -+> > ARM-specific optimization processes 8 or 4 pixels at once. -+> > -+> > * Without transparency: 22% performance gain on the A53 little core. -+> > * With transparency: 10% improvement on a big A72 core, 24% on little. -+> > -+> > (Numbers from image_decode_bench with PNG140 on the elm chromebook). -+> > -+> > Bug: 706134 -+> > Change-Id: I7b4a93d72a0afa2823f3bf9ff5f798b88c843e54 -+> > Reviewed-on: https://chromium-review.googlesource.com/817116 -+> > Reviewed-by: Adenilson Cavalcanti <cavalcantii@chromium.org> -+> > Reviewed-by: Mike Klein <mtklein@chromium.org> -+> > Reviewed-by: Leon Scroggins <scroggo@chromium.org> -+> > Reviewed-by: Chris Blume <cblume@chromium.org> -+> > Commit-Queue: Adenilson Cavalcanti <cavalcantii@chromium.org> -+> > Cr-Commit-Position: refs/heads/master@{#529473} -+> -+> TBR=scroggo@chromium.org,cavalcantii@chromium.org,richard.townsend@arm.com,cblume@chromium.org,mtklein@chromium.org -+> -+> Change-Id: I2cd943e15ceadf4311b1b49a56de00d10684e294 -+> No-Presubmit: true -+> No-Tree-Checks: true -+> No-Try: true -+> Bug: 706134 -+> Reviewed-on: https://chromium-review.googlesource.com/868770 -+> Reviewed-by: Jonathan Ross <jonross@chromium.org> -+> Commit-Queue: Jonathan Ross <jonross@chromium.org> -+> Cr-Commit-Position: refs/heads/master@{#529484} -+ -+TBR=scroggo@chromium.org,jonross@chromium.org,cavalcantii@chromium.org,richard.townsend@arm.com,cblume@chromium.org,mtklein@chromium.org -+ -+Change-Id: I6baf17d35efbd5c6bc348d4f81264e8e1023be4f -+No-Presubmit: true -+No-Tree-Checks: true -+No-Try: true -+Bug: 706134 -+--- -+ third_party/libpng/BUILD.gn | 1 + -+ third_party/libpng/arm/palette_neon_intrinsics.c | 137 +++++++++ -+ third_party/libpng/patches/0000-plte.patch | 340 +++++++++++++++++++++++ -+ third_party/libpng/patches/README | 4 + -+ third_party/libpng/pngpriv.h | 23 ++ -+ third_party/libpng/pngrtran.c | 49 +++- -+ third_party/libpng/pngstruct.h | 4 + -+ third_party/libpng/pngwrite.c | 4 + -+ 8 files changed, 554 insertions(+), 8 deletions(-) -+ create mode 100644 third_party/libpng/arm/palette_neon_intrinsics.c -+ create mode 100644 third_party/libpng/patches/0000-plte.patch -+ create mode 100644 third_party/libpng/patches/README -+ -+diff --git a/third_party/libpng/BUILD.gn b/third_party/libpng/BUILD.gn -+index e2658a7ba623..e48c790326c7 100644 -+--- a/third_party/libpng/BUILD.gn -++++ b/third_party/libpng/BUILD.gn -+@@ -75,6 +75,7 @@ source_set("libpng_sources") { -+ sources += [ -+ "arm/arm_init.c", -+ "arm/filter_neon_intrinsics.c", -++ "arm/palette_neon_intrinsics.c", -+ ] -+ defines += [ -+ "PNG_ARM_NEON_OPT=2", -+diff --git a/third_party/libpng/arm/palette_neon_intrinsics.c b/third_party/libpng/arm/palette_neon_intrinsics.c -+new file mode 100644 -+index 000000000000..0c0c0a909f8d -+--- /dev/null -++++ b/third_party/libpng/arm/palette_neon_intrinsics.c -+@@ -0,0 +1,137 @@ -++/* palette_neon_intrinsics.c - NEON optimised palette expansion functions -++ * -++ * Copyright (c) 2017 The Chromium Authors. All rights reserved. -++ * Written by Richard Townsend <Richard.Townsend@arm.com>, February 2017. -++ * -++ * This code is released under the libpng license. -++ * For conditions of distribution and use, see the disclaimer -++ * and license in png.h -++ */ -++ -++#include "../pngpriv.h" -++ -++#if PNG_ARM_NEON_IMPLEMENTATION == 1 -++ -++#include <arm_neon.h> -++ -++/* Build an RGBA palette from the RGB and separate alpha palettes. */ -++void -++png_riffle_palette_rgba(png_structrp png_ptr, png_row_infop row_info) -++{ -++ png_const_colorp palette = png_ptr->palette; -++ png_bytep riffled_palette = png_ptr->riffled_palette; -++ png_const_bytep trans_alpha = png_ptr->trans_alpha; -++ int num_trans = png_ptr->num_trans; -++ -++ if (row_info->bit_depth != 8) { -++ png_error(png_ptr, "bit_depth must be 8 for png_riffle_palette_rgba"); -++ return; -++ } -++ -++ /* Initially black, opaque. */ -++ uint8x16x4_t w = { -++ vdupq_n_u8(0x00), -++ vdupq_n_u8(0x00), -++ vdupq_n_u8(0x00), -++ vdupq_n_u8(0xff), -++ }; -++ -++ int i; -++ /* First, riffle the RGB colours into a RGBA palette, the A value is -++ * set to opaque for now. */ -++ for (i = 0; i < (1 << row_info->bit_depth); i += 16) { -++ uint8x16x3_t v = vld3q_u8((png_const_bytep)(palette + i)); -++ w.val[0] = v.val[0]; -++ w.val[1] = v.val[1]; -++ w.val[2] = v.val[2]; -++ vst4q_u8(riffled_palette + (i << 2), w); -++ } -++ -++ /* Fix up the missing transparency values. */ -++ for (i = 0; i < num_trans; i++) { -++ riffled_palette[(i << 2) + 3] = trans_alpha[i]; -++ } -++} -++ -++ -++/* Expands a palettized row into RGBA. */ -++int -++png_do_expand_palette_neon_rgba(png_structrp png_ptr, png_row_infop row_info, -++ png_const_bytep row, const png_bytepp ssp, const png_bytepp ddp) -++{ -++ -++ png_uint_32 row_width = row_info->width; -++ const png_uint_32 *riffled_palette = (const png_uint_32*)png_ptr->riffled_palette; -++ const png_int_32 pixels_per_chunk = 4; -++ -++ if (row_width < pixels_per_chunk) { -++ return 0; -++ } -++ -++ /* This function originally gets the last byte of the output row. -++ The NEON part writes forward from a given position, so we have -++ to seek this back by 4 pixels x 4 bytes. */ -++ *ddp = *ddp - ((pixels_per_chunk * sizeof(png_uint_32)) - 1); -++ -++ int i; -++ for (i = 0; i < row_width; i += pixels_per_chunk) { -++ uint32x4_t cur; -++ png_bytep sp = *ssp - i, dp = *ddp - (i << 2); -++ cur = vld1q_dup_u32 (riffled_palette + *(sp - 3)); -++ cur = vld1q_lane_u32(riffled_palette + *(sp - 2), cur, 1); -++ cur = vld1q_lane_u32(riffled_palette + *(sp - 1), cur, 2); -++ cur = vld1q_lane_u32(riffled_palette + *(sp - 0), cur, 3); -++ vst1q_u32((void *)dp, cur); -++ } -++ if (i != row_width) { -++ i -= pixels_per_chunk; /* Remove the amount that wasn't processed. */ -++ } -++ -++ /* Decrement output pointers. */ -++ *ssp = *ssp - i; -++ *ddp = *ddp - (i << 2); -++ return i; -++} -++ -++/* Expands a palettized row into RGB format. */ -++int -++png_do_expand_palette_neon_rgb(png_structrp png_ptr, png_row_infop row_info, -++ png_const_bytep row, const png_bytepp ssp, const png_bytepp ddp) -++{ -++ png_uint_32 row_width = row_info->width; -++ png_const_bytep palette = (png_const_bytep)png_ptr->palette; -++ const png_uint_32 pixels_per_chunk = 8; -++ -++ if (row_width <= pixels_per_chunk) { -++ return 0; -++ } -++ -++ /* Seeking this back by 8 pixels x 3 bytes. */ -++ *ddp = *ddp - ((pixels_per_chunk * sizeof(png_color)) - 1); -++ -++ int i; -++ for (i = 0; i < row_width; i += pixels_per_chunk) { -++ uint8x8x3_t cur; -++ png_bytep sp = *ssp - i, dp = *ddp - ((i << 1) + i); -++ cur = vld3_dup_u8(palette + sizeof(png_color) * (*(sp - 7))); -++ cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 6)), cur, 1); -++ cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 5)), cur, 2); -++ cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 4)), cur, 3); -++ cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 3)), cur, 4); -++ cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 2)), cur, 5); -++ cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 1)), cur, 6); -++ cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 0)), cur, 7); -++ vst3_u8((void *)dp, cur); -++ } -++ -++ if (i != row_width) { -++ i -= pixels_per_chunk; /* Remove the amount that wasn't processed. */ -++ } -++ -++ /* Decrement output pointers. */ -++ *ssp = *ssp - i; -++ *ddp = *ddp - ((i << 1) + i); -++ return i; -++} -++ -++#endif /* PNG_ARM_NEON_IMPLEMENTATION */ -+diff --git a/third_party/libpng/patches/0000-plte.patch b/third_party/libpng/patches/0000-plte.patch -+new file mode 100644 -+index 000000000000..6fceb2f2275a -+--- /dev/null -++++ b/third_party/libpng/patches/0000-plte.patch -+@@ -0,0 +1,340 @@ -++From aa270a19f7bb9d9cba207b38c0a98cb3a3dc681e Mon Sep 17 00:00:00 2001 -++From: Richard Townsend <Richard.Townsend@arm.com> -++Date: Mon, 20 Feb 2017 14:06:14 +0000 -++Subject: [PATCH] libpng: Optimize png_do_expand_palette with NEON. -++ -++ARM-specific optimization processes 8 or 4 pixels at once. -++ -++* Without transparency: 22% performance gain on the A53 little core. -++* With transparency: 10% improvement on a big A72 core, 24% on little. -++ -++(Numbers from image_decode_bench with PNG140 on the elm chromebook). -++ -++Bug: 706134 -++Change-Id: I7b4a93d72a0afa2823f3bf9ff5f798b88c843e54 -++--- -++ third_party/libpng/BUILD.gn | 1 + -++ third_party/libpng/arm/palette_neon_intrinsics.c | 137 +++++++++++++++++++++++ -++ third_party/libpng/pngpriv.h | 23 ++++ -++ third_party/libpng/pngrtran.c | 49 ++++++-- -++ third_party/libpng/pngstruct.h | 4 + -++ third_party/libpng/pngwrite.c | 4 + -++ 6 files changed, 210 insertions(+), 8 deletions(-) -++ create mode 100644 third_party/libpng/arm/palette_neon_intrinsics.c -++ -++diff --git a/third_party/libpng/BUILD.gn b/third_party/libpng/BUILD.gn -++index e2658a7ba623..e48c790326c7 100644 -++--- a/third_party/libpng/BUILD.gn -+++++ b/third_party/libpng/BUILD.gn -++@@ -75,6 +75,7 @@ source_set("libpng_sources") { -++ sources += [ -++ "arm/arm_init.c", -++ "arm/filter_neon_intrinsics.c", -+++ "arm/palette_neon_intrinsics.c", -++ ] -++ defines += [ -++ "PNG_ARM_NEON_OPT=2", -++diff --git a/third_party/libpng/arm/palette_neon_intrinsics.c b/third_party/libpng/arm/palette_neon_intrinsics.c -++new file mode 100644 -++index 000000000000..0c0c0a909f8d -++--- /dev/null -+++++ b/third_party/libpng/arm/palette_neon_intrinsics.c -++@@ -0,0 +1,137 @@ -+++/* palette_neon_intrinsics.c - NEON optimised palette expansion functions -+++ * -+++ * Copyright (c) 2017 The Chromium Authors. All rights reserved. -+++ * Written by Richard Townsend <Richard.Townsend@arm.com>, February 2017. -+++ * -+++ * This code is released under the libpng license. -+++ * For conditions of distribution and use, see the disclaimer -+++ * and license in png.h -+++ */ -+++ -+++#include "../pngpriv.h" -+++ -+++#if PNG_ARM_NEON_IMPLEMENTATION == 1 -+++ -+++#include <arm_neon.h> -+++ -+++/* Build an RGBA palette from the RGB and separate alpha palettes. */ -+++void -+++png_riffle_palette_rgba(png_structrp png_ptr, png_row_infop row_info) -+++{ -+++ png_const_colorp palette = png_ptr->palette; -+++ png_bytep riffled_palette = png_ptr->riffled_palette; -+++ png_const_bytep trans_alpha = png_ptr->trans_alpha; -+++ int num_trans = png_ptr->num_trans; -+++ -+++ if (row_info->bit_depth != 8) { -+++ png_error(png_ptr, "bit_depth must be 8 for png_riffle_palette_rgba"); -+++ return; -+++ } -+++ -+++ /* Initially black, opaque. */ -+++ uint8x16x4_t w = { -+++ vdupq_n_u8(0x00), -+++ vdupq_n_u8(0x00), -+++ vdupq_n_u8(0x00), -+++ vdupq_n_u8(0xff), -+++ }; -+++ -+++ int i; -+++ /* First, riffle the RGB colours into a RGBA palette, the A value is -+++ * set to opaque for now. */ -+++ for (i = 0; i < (1 << row_info->bit_depth); i += 16) { -+++ uint8x16x3_t v = vld3q_u8((png_const_bytep)(palette + i)); -+++ w.val[0] = v.val[0]; -+++ w.val[1] = v.val[1]; -+++ w.val[2] = v.val[2]; -+++ vst4q_u8(riffled_palette + (i << 2), w); -+++ } -+++ -+++ /* Fix up the missing transparency values. */ -+++ for (i = 0; i < num_trans; i++) { -+++ riffled_palette[(i << 2) + 3] = trans_alpha[i]; -+++ } -+++} -+++ -+++ -+++/* Expands a palettized row into RGBA. */ -+++int -+++png_do_expand_palette_neon_rgba(png_structrp png_ptr, png_row_infop row_info, -+++ png_const_bytep row, const png_bytepp ssp, const png_bytepp ddp) -+++{ -+++ -+++ png_uint_32 row_width = row_info->width; -+++ const png_uint_32 *riffled_palette = (const png_uint_32*)png_ptr->riffled_palette; -+++ const png_int_32 pixels_per_chunk = 4; -+++ -+++ if (row_width < pixels_per_chunk) { -+++ return 0; -+++ } -+++ -+++ /* This function originally gets the last byte of the output row. -+++ The NEON part writes forward from a given position, so we have -+++ to seek this back by 4 pixels x 4 bytes. */ -+++ *ddp = *ddp - ((pixels_per_chunk * sizeof(png_uint_32)) - 1); -+++ -+++ int i; -+++ for (i = 0; i < row_width; i += pixels_per_chunk) { -+++ uint32x4_t cur; -+++ png_bytep sp = *ssp - i, dp = *ddp - (i << 2); -+++ cur = vld1q_dup_u32 (riffled_palette + *(sp - 3)); -+++ cur = vld1q_lane_u32(riffled_palette + *(sp - 2), cur, 1); -+++ cur = vld1q_lane_u32(riffled_palette + *(sp - 1), cur, 2); -+++ cur = vld1q_lane_u32(riffled_palette + *(sp - 0), cur, 3); -+++ vst1q_u32((void *)dp, cur); -+++ } -+++ if (i != row_width) { -+++ i -= pixels_per_chunk; /* Remove the amount that wasn't processed. */ -+++ } -+++ -+++ /* Decrement output pointers. */ -+++ *ssp = *ssp - i; -+++ *ddp = *ddp - (i << 2); -+++ return i; -+++} -+++ -+++/* Expands a palettized row into RGB format. */ -+++int -+++png_do_expand_palette_neon_rgb(png_structrp png_ptr, png_row_infop row_info, -+++ png_const_bytep row, const png_bytepp ssp, const png_bytepp ddp) -+++{ -+++ png_uint_32 row_width = row_info->width; -+++ png_const_bytep palette = (png_const_bytep)png_ptr->palette; -+++ const png_uint_32 pixels_per_chunk = 8; -+++ -+++ if (row_width <= pixels_per_chunk) { -+++ return 0; -+++ } -+++ -+++ /* Seeking this back by 8 pixels x 3 bytes. */ -+++ *ddp = *ddp - ((pixels_per_chunk * sizeof(png_color)) - 1); -+++ -+++ int i; -+++ for (i = 0; i < row_width; i += pixels_per_chunk) { -+++ uint8x8x3_t cur; -+++ png_bytep sp = *ssp - i, dp = *ddp - ((i << 1) + i); -+++ cur = vld3_dup_u8(palette + sizeof(png_color) * (*(sp - 7))); -+++ cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 6)), cur, 1); -+++ cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 5)), cur, 2); -+++ cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 4)), cur, 3); -+++ cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 3)), cur, 4); -+++ cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 2)), cur, 5); -+++ cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 1)), cur, 6); -+++ cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 0)), cur, 7); -+++ vst3_u8((void *)dp, cur); -+++ } -+++ -+++ if (i != row_width) { -+++ i -= pixels_per_chunk; /* Remove the amount that wasn't processed. */ -+++ } -+++ -+++ /* Decrement output pointers. */ -+++ *ssp = *ssp - i; -+++ *ddp = *ddp - ((i << 1) + i); -+++ return i; -+++} -+++ -+++#endif /* PNG_ARM_NEON_IMPLEMENTATION */ -++diff --git a/third_party/libpng/pngpriv.h b/third_party/libpng/pngpriv.h -++index 1f2e90f2b37b..5652525b2b51 100644 -++--- a/third_party/libpng/pngpriv.h -+++++ b/third_party/libpng/pngpriv.h -++@@ -2108,6 +2108,29 @@ PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2, -++ PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr, -++ png_const_charp key, png_bytep new_key), PNG_EMPTY); -++ -+++#if PNG_ARM_NEON_IMPLEMENTATION == 1 -+++PNG_INTERNAL_FUNCTION(void, -+++ png_riffle_palette_rgba, -+++ (png_structrp, png_row_infop), -+++ PNG_EMPTY); -+++PNG_INTERNAL_FUNCTION(int, -+++ png_do_expand_palette_neon_rgba, -+++ (png_structrp, -+++ png_row_infop, -+++ png_const_bytep, -+++ const png_bytepp, -+++ const png_bytepp), -+++ PNG_EMPTY); -+++PNG_INTERNAL_FUNCTION(int, -+++ png_do_expand_palette_neon_rgb, -+++ (png_structrp, -+++ png_row_infop, -+++ png_const_bytep, -+++ const png_bytepp, -+++ const png_bytepp), -+++ PNG_EMPTY); -+++#endif -+++ -++ /* Maintainer: Put new private prototypes here ^ */ -++ -++ #include "pngdebug.h" -++diff --git a/third_party/libpng/pngrtran.c b/third_party/libpng/pngrtran.c -++index c1896503130e..9dd82c929bdc 100644 -++--- a/third_party/libpng/pngrtran.c -+++++ b/third_party/libpng/pngrtran.c -++@@ -18,6 +18,13 @@ -++ -++ #include "pngpriv.h" -++ -+++#ifdef PNG_ARM_NEON_IMPLEMENTATION -+++#if PNG_ARM_NEON_IMPLEMENTATION == 1 -+++#define PNG_ARM_NEON_INTRINSICS_AVAILABLE -+++#include <arm_neon.h> -+++#endif -+++#endif -+++ -++ #ifdef PNG_READ_SUPPORTED -++ -++ /* Set the action on getting a CRC error for an ancillary or critical chunk. */ -++@@ -4202,8 +4209,9 @@ png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr) -++ * upon whether you supply trans and num_trans. -++ */ -++ static void -++-png_do_expand_palette(png_row_infop row_info, png_bytep row, -++- png_const_colorp palette, png_const_bytep trans_alpha, int num_trans) -+++png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info, -+++ png_bytep row, png_const_colorp palette, png_const_bytep trans_alpha, -+++ int num_trans) -++ { -++ int shift, value; -++ png_bytep sp, dp; -++@@ -4307,14 +4315,22 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, -++ sp = row + (png_size_t)row_width - 1; -++ dp = row + ((png_size_t)row_width << 2) - 1; -++ -++- for (i = 0; i < row_width; i++) -+++ i = 0; -+++#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE -+++ if (png_ptr->riffled_palette != NULL) { -+++ /* The RGBA optimization works with png_ptr->bit_depth == 8 -+++ but sometimes row_info->bit_depth has been changed to 8. -+++ In these cases, the palette hasn't been riffled. */ -+++ i = png_do_expand_palette_neon_rgba(png_ptr, row_info, row, &sp, &dp); -+++ } -+++#endif -+++ -+++ for (; i < row_width; i++) -++ { -++ if ((int)(*sp) >= num_trans) -++ *dp-- = 0xff; -++- -++ else -++ *dp-- = trans_alpha[*sp]; -++- -++ *dp-- = palette[*sp].blue; -++ *dp-- = palette[*sp].green; -++ *dp-- = palette[*sp].red; -++@@ -4331,8 +4347,12 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, -++ { -++ sp = row + (png_size_t)row_width - 1; -++ dp = row + (png_size_t)(row_width * 3) - 1; -+++ i = 0; -+++#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE -+++ i = png_do_expand_palette_neon_rgb(png_ptr, row_info, row, &sp, &dp); -+++#endif -++ -++- for (i = 0; i < row_width; i++) -+++ for (; i < row_width; i++) -++ { -++ *dp-- = palette[*sp].blue; -++ *dp-- = palette[*sp].green; -++@@ -4748,8 +4768,21 @@ png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info) -++ { -++ if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) -++ { -++- png_do_expand_palette(row_info, png_ptr->row_buf + 1, -++- png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); -+++#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE -+++ if ((png_ptr->num_trans > 0) && (png_ptr->bit_depth == 8)) { -+++ /* Allocate space for the decompressed full palette. */ -+++ if (png_ptr->riffled_palette == NULL) { -+++ png_ptr->riffled_palette = png_malloc(png_ptr, 256*4); -+++ if (png_ptr->riffled_palette == NULL) { -+++ png_error(png_ptr, "NULL row buffer"); -+++ } -+++ /* Build the RGBA palette. */ -+++ png_riffle_palette_rgba(png_ptr, row_info); -+++ } -+++ } -+++#endif -+++ png_do_expand_palette(png_ptr, row_info, png_ptr->row_buf + 1, -+++ png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); -++ } -++ -++ else -++diff --git a/third_party/libpng/pngstruct.h b/third_party/libpng/pngstruct.h -++index d83f971253fe..aac88df02d32 100644 -++--- a/third_party/libpng/pngstruct.h -+++++ b/third_party/libpng/pngstruct.h -++@@ -228,6 +228,10 @@ struct png_struct_def -++ * big_row_buf; while writing it is separately -++ * allocated. -++ */ -+++#ifdef PNG_READ_EXPAND_SUPPORTED -+++ /* Buffer to accelerate palette transformations. */ -+++ png_bytep riffled_palette; -+++#endif -++ #ifdef PNG_WRITE_FILTER_SUPPORTED -++ png_bytep try_row; /* buffer to save trial row when filtering */ -++ png_bytep tst_row; /* buffer to save best trial row when filtering */ -++diff --git a/third_party/libpng/pngwrite.c b/third_party/libpng/pngwrite.c -++index a16d77ce00c6..e25e5dcfdc18 100644 -++--- a/third_party/libpng/pngwrite.c -+++++ b/third_party/libpng/pngwrite.c -++@@ -948,6 +948,10 @@ png_write_destroy(png_structrp png_ptr) -++ png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); -++ png_free(png_ptr, png_ptr->row_buf); -++ png_ptr->row_buf = NULL; -+++#ifdef PNG_READ_EXPANDED_SUPPORTED -+++ png_free(png_ptr, png_ptr->riffled_palette); -+++ png_ptr->riffled_palette = NULL; -+++#endif -++ #ifdef PNG_WRITE_FILTER_SUPPORTED -++ png_free(png_ptr, png_ptr->prev_row); -++ png_free(png_ptr, png_ptr->try_row); -++-- -++2.15.1 -++ -+diff --git a/third_party/libpng/patches/README b/third_party/libpng/patches/README -+new file mode 100644 -+index 000000000000..786aeabede37 -+--- /dev/null -++++ b/third_party/libpng/patches/README -+@@ -0,0 +1,4 @@ -++This directory contains patches applied on top of libpng, which haven't been -++upstreamed to the canonical libpng repository [1] yet. -++ -++[1] https://github.com/glennrp/libpng -+diff --git a/third_party/libpng/pngpriv.h b/third_party/libpng/pngpriv.h -+index 1f2e90f2b37b..5652525b2b51 100644 -+--- a/third_party/libpng/pngpriv.h -++++ b/third_party/libpng/pngpriv.h -+@@ -2108,6 +2108,29 @@ PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2, -+ PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr, -+ png_const_charp key, png_bytep new_key), PNG_EMPTY); -+ -++#if PNG_ARM_NEON_IMPLEMENTATION == 1 -++PNG_INTERNAL_FUNCTION(void, -++ png_riffle_palette_rgba, -++ (png_structrp, png_row_infop), -++ PNG_EMPTY); -++PNG_INTERNAL_FUNCTION(int, -++ png_do_expand_palette_neon_rgba, -++ (png_structrp, -++ png_row_infop, -++ png_const_bytep, -++ const png_bytepp, -++ const png_bytepp), -++ PNG_EMPTY); -++PNG_INTERNAL_FUNCTION(int, -++ png_do_expand_palette_neon_rgb, -++ (png_structrp, -++ png_row_infop, -++ png_const_bytep, -++ const png_bytepp, -++ const png_bytepp), -++ PNG_EMPTY); -++#endif -++ -+ /* Maintainer: Put new private prototypes here ^ */ -+ -+ #include "pngdebug.h" -+diff --git a/third_party/libpng/pngrtran.c b/third_party/libpng/pngrtran.c -+index c1896503130e..9dd82c929bdc 100644 -+--- a/third_party/libpng/pngrtran.c -++++ b/third_party/libpng/pngrtran.c -+@@ -18,6 +18,13 @@ -+ -+ #include "pngpriv.h" -+ -++#ifdef PNG_ARM_NEON_IMPLEMENTATION -++#if PNG_ARM_NEON_IMPLEMENTATION == 1 -++#define PNG_ARM_NEON_INTRINSICS_AVAILABLE -++#include <arm_neon.h> -++#endif -++#endif -++ -+ #ifdef PNG_READ_SUPPORTED -+ -+ /* Set the action on getting a CRC error for an ancillary or critical chunk. */ -+@@ -4202,8 +4209,9 @@ png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr) -+ * upon whether you supply trans and num_trans. -+ */ -+ static void -+-png_do_expand_palette(png_row_infop row_info, png_bytep row, -+- png_const_colorp palette, png_const_bytep trans_alpha, int num_trans) -++png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info, -++ png_bytep row, png_const_colorp palette, png_const_bytep trans_alpha, -++ int num_trans) -+ { -+ int shift, value; -+ png_bytep sp, dp; -+@@ -4307,14 +4315,22 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, -+ sp = row + (png_size_t)row_width - 1; -+ dp = row + ((png_size_t)row_width << 2) - 1; -+ -+- for (i = 0; i < row_width; i++) -++ i = 0; -++#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE -++ if (png_ptr->riffled_palette != NULL) { -++ /* The RGBA optimization works with png_ptr->bit_depth == 8 -++ but sometimes row_info->bit_depth has been changed to 8. -++ In these cases, the palette hasn't been riffled. */ -++ i = png_do_expand_palette_neon_rgba(png_ptr, row_info, row, &sp, &dp); -++ } -++#endif -++ -++ for (; i < row_width; i++) -+ { -+ if ((int)(*sp) >= num_trans) -+ *dp-- = 0xff; -+- -+ else -+ *dp-- = trans_alpha[*sp]; -+- -+ *dp-- = palette[*sp].blue; -+ *dp-- = palette[*sp].green; -+ *dp-- = palette[*sp].red; -+@@ -4331,8 +4347,12 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, -+ { -+ sp = row + (png_size_t)row_width - 1; -+ dp = row + (png_size_t)(row_width * 3) - 1; -++ i = 0; -++#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE -++ i = png_do_expand_palette_neon_rgb(png_ptr, row_info, row, &sp, &dp); -++#endif -+ -+- for (i = 0; i < row_width; i++) -++ for (; i < row_width; i++) -+ { -+ *dp-- = palette[*sp].blue; -+ *dp-- = palette[*sp].green; -+@@ -4748,8 +4768,21 @@ png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info) -+ { -+ if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) -+ { -+- png_do_expand_palette(row_info, png_ptr->row_buf + 1, -+- png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); -++#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE -++ if ((png_ptr->num_trans > 0) && (png_ptr->bit_depth == 8)) { -++ /* Allocate space for the decompressed full palette. */ -++ if (png_ptr->riffled_palette == NULL) { -++ png_ptr->riffled_palette = png_malloc(png_ptr, 256*4); -++ if (png_ptr->riffled_palette == NULL) { -++ png_error(png_ptr, "NULL row buffer"); -++ } -++ /* Build the RGBA palette. */ -++ png_riffle_palette_rgba(png_ptr, row_info); -++ } -++ } -++#endif -++ png_do_expand_palette(png_ptr, row_info, png_ptr->row_buf + 1, -++ png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); -+ } -+ -+ else -+diff --git a/third_party/libpng/pngstruct.h b/third_party/libpng/pngstruct.h -+index d83f971253fe..aac88df02d32 100644 -+--- a/third_party/libpng/pngstruct.h -++++ b/third_party/libpng/pngstruct.h -+@@ -228,6 +228,10 @@ struct png_struct_def -+ * big_row_buf; while writing it is separately -+ * allocated. -+ */ -++#ifdef PNG_READ_EXPAND_SUPPORTED -++ /* Buffer to accelerate palette transformations. */ -++ png_bytep riffled_palette; -++#endif -+ #ifdef PNG_WRITE_FILTER_SUPPORTED -+ png_bytep try_row; /* buffer to save trial row when filtering */ -+ png_bytep tst_row; /* buffer to save best trial row when filtering */ -+diff --git a/third_party/libpng/pngwrite.c b/third_party/libpng/pngwrite.c -+index a16d77ce00c6..e25e5dcfdc18 100644 -+--- a/third_party/libpng/pngwrite.c -++++ b/third_party/libpng/pngwrite.c -+@@ -948,6 +948,10 @@ png_write_destroy(png_structrp png_ptr) -+ png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); -+ png_free(png_ptr, png_ptr->row_buf); -+ png_ptr->row_buf = NULL; -++#ifdef PNG_READ_EXPANDED_SUPPORTED -++ png_free(png_ptr, png_ptr->riffled_palette); -++ png_ptr->riffled_palette = NULL; -++#endif -+ #ifdef PNG_WRITE_FILTER_SUPPORTED -+ png_free(png_ptr, png_ptr->prev_row); -+ png_free(png_ptr, png_ptr->try_row); -+-- -+2.16.0.rc1.238.g530d649a79-goog -+ -+ -+From 736276e0ec02b5078ca98cfe6ed0bb3f86524a8b Mon Sep 17 00:00:00 2001 -+From: Chris Blume <cblume@google.com> -+Date: Tue, 16 Jan 2018 13:25:38 -0800 -+Subject: [PATCH 2/2] Explicitly initialize the member of the variable -+ -+--- -+ third_party/libpng/arm/palette_neon_intrinsics.c | 4 ++-- -+ 1 file changed, 2 insertions(+), 2 deletions(-) -+ -+diff --git a/third_party/libpng/arm/palette_neon_intrinsics.c b/third_party/libpng/arm/palette_neon_intrinsics.c -+index 0c0c0a909f8d..703b9ff25053 100644 -+--- a/third_party/libpng/arm/palette_neon_intrinsics.c -++++ b/third_party/libpng/arm/palette_neon_intrinsics.c -+@@ -29,12 +29,12 @@ png_riffle_palette_rgba(png_structrp png_ptr, png_row_infop row_info) -+ } -+ -+ /* Initially black, opaque. */ -+- uint8x16x4_t w = { -++ uint8x16x4_t w = {{ -+ vdupq_n_u8(0x00), -+ vdupq_n_u8(0x00), -+ vdupq_n_u8(0x00), -+ vdupq_n_u8(0xff), -+- }; -++ }}; -+ -+ int i; -+ /* First, riffle the RGB colours into a RGBA palette, the A value is -+-- -+2.16.0.rc1.238.g530d649a79-goog -+ -diff --git a/third_party/libpng/patches/README b/third_party/libpng/patches/README -new file mode 100644 -index 000000000000..786aeabede37 ---- /dev/null -+++ b/third_party/libpng/patches/README -@@ -0,0 +1,4 @@ -+This directory contains patches applied on top of libpng, which haven't been -+upstreamed to the canonical libpng repository [1] yet. -+ -+[1] https://github.com/glennrp/libpng -diff --git a/third_party/libpng/pngpriv.h b/third_party/libpng/pngpriv.h -index 1f2e90f2b37b..5652525b2b51 100644 ---- a/third_party/libpng/pngpriv.h -+++ b/third_party/libpng/pngpriv.h -@@ -2108,6 +2108,29 @@ PNG_INTERNAL_FUNCTION(void, png_init_filter_functions_sse2, - PNG_INTERNAL_FUNCTION(png_uint_32, png_check_keyword, (png_structrp png_ptr, - png_const_charp key, png_bytep new_key), PNG_EMPTY); - -+#if PNG_ARM_NEON_IMPLEMENTATION == 1 -+PNG_INTERNAL_FUNCTION(void, -+ png_riffle_palette_rgba, -+ (png_structrp, png_row_infop), -+ PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(int, -+ png_do_expand_palette_neon_rgba, -+ (png_structrp, -+ png_row_infop, -+ png_const_bytep, -+ const png_bytepp, -+ const png_bytepp), -+ PNG_EMPTY); -+PNG_INTERNAL_FUNCTION(int, -+ png_do_expand_palette_neon_rgb, -+ (png_structrp, -+ png_row_infop, -+ png_const_bytep, -+ const png_bytepp, -+ const png_bytepp), -+ PNG_EMPTY); -+#endif -+ - /* Maintainer: Put new private prototypes here ^ */ - - #include "pngdebug.h" -diff --git a/third_party/libpng/pngrtran.c b/third_party/libpng/pngrtran.c -index c1896503130e..9dd82c929bdc 100644 ---- a/third_party/libpng/pngrtran.c -+++ b/third_party/libpng/pngrtran.c -@@ -18,6 +18,13 @@ - - #include "pngpriv.h" - -+#ifdef PNG_ARM_NEON_IMPLEMENTATION -+#if PNG_ARM_NEON_IMPLEMENTATION == 1 -+#define PNG_ARM_NEON_INTRINSICS_AVAILABLE -+#include <arm_neon.h> -+#endif -+#endif -+ - #ifdef PNG_READ_SUPPORTED - - /* Set the action on getting a CRC error for an ancillary or critical chunk. */ -@@ -4202,8 +4209,9 @@ png_do_encode_alpha(png_row_infop row_info, png_bytep row, png_structrp png_ptr) - * upon whether you supply trans and num_trans. - */ - static void --png_do_expand_palette(png_row_infop row_info, png_bytep row, -- png_const_colorp palette, png_const_bytep trans_alpha, int num_trans) -+png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info, -+ png_bytep row, png_const_colorp palette, png_const_bytep trans_alpha, -+ int num_trans) - { - int shift, value; - png_bytep sp, dp; -@@ -4307,14 +4315,22 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, - sp = row + (png_size_t)row_width - 1; - dp = row + ((png_size_t)row_width << 2) - 1; - -- for (i = 0; i < row_width; i++) -+ i = 0; -+#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE -+ if (png_ptr->riffled_palette != NULL) { -+ /* The RGBA optimization works with png_ptr->bit_depth == 8 -+ but sometimes row_info->bit_depth has been changed to 8. -+ In these cases, the palette hasn't been riffled. */ -+ i = png_do_expand_palette_neon_rgba(png_ptr, row_info, row, &sp, &dp); -+ } -+#endif -+ -+ for (; i < row_width; i++) - { - if ((int)(*sp) >= num_trans) - *dp-- = 0xff; -- - else - *dp-- = trans_alpha[*sp]; -- - *dp-- = palette[*sp].blue; - *dp-- = palette[*sp].green; - *dp-- = palette[*sp].red; -@@ -4331,8 +4347,12 @@ png_do_expand_palette(png_row_infop row_info, png_bytep row, - { - sp = row + (png_size_t)row_width - 1; - dp = row + (png_size_t)(row_width * 3) - 1; -+ i = 0; -+#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE -+ i = png_do_expand_palette_neon_rgb(png_ptr, row_info, row, &sp, &dp); -+#endif - -- for (i = 0; i < row_width; i++) -+ for (; i < row_width; i++) - { - *dp-- = palette[*sp].blue; - *dp-- = palette[*sp].green; -@@ -4748,8 +4768,21 @@ png_do_read_transformations(png_structrp png_ptr, png_row_infop row_info) - { - if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) - { -- png_do_expand_palette(row_info, png_ptr->row_buf + 1, -- png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); -+#ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE -+ if ((png_ptr->num_trans > 0) && (png_ptr->bit_depth == 8)) { -+ /* Allocate space for the decompressed full palette. */ -+ if (png_ptr->riffled_palette == NULL) { -+ png_ptr->riffled_palette = png_malloc(png_ptr, 256*4); -+ if (png_ptr->riffled_palette == NULL) { -+ png_error(png_ptr, "NULL row buffer"); -+ } -+ /* Build the RGBA palette. */ -+ png_riffle_palette_rgba(png_ptr, row_info); -+ } -+ } -+#endif -+ png_do_expand_palette(png_ptr, row_info, png_ptr->row_buf + 1, -+ png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); - } - - else -diff --git a/third_party/libpng/pngstruct.h b/third_party/libpng/pngstruct.h -index d83f971253fe..aac88df02d32 100644 ---- a/third_party/libpng/pngstruct.h -+++ b/third_party/libpng/pngstruct.h -@@ -228,6 +228,10 @@ struct png_struct_def - * big_row_buf; while writing it is separately - * allocated. - */ -+#ifdef PNG_READ_EXPAND_SUPPORTED -+ /* Buffer to accelerate palette transformations. */ -+ png_bytep riffled_palette; -+#endif - #ifdef PNG_WRITE_FILTER_SUPPORTED - png_bytep try_row; /* buffer to save trial row when filtering */ - png_bytep tst_row; /* buffer to save best trial row when filtering */ -diff --git a/third_party/libpng/pngwrite.c b/third_party/libpng/pngwrite.c -index a16d77ce00c6..e25e5dcfdc18 100644 ---- a/third_party/libpng/pngwrite.c -+++ b/third_party/libpng/pngwrite.c -@@ -948,6 +948,10 @@ png_write_destroy(png_structrp png_ptr) - png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); - png_free(png_ptr, png_ptr->row_buf); - png_ptr->row_buf = NULL; -+#ifdef PNG_READ_EXPANDED_SUPPORTED -+ png_free(png_ptr, png_ptr->riffled_palette); -+ png_ptr->riffled_palette = NULL; -+#endif - #ifdef PNG_WRITE_FILTER_SUPPORTED - png_free(png_ptr, png_ptr->prev_row); - png_free(png_ptr, png_ptr->try_row); --- -2.16.0.rc1.238.g530d649a79-goog -
diff --git a/third_party/libpng/patches/README b/third_party/libpng/patches/README index 8412d00..2fd6cc87 100644 --- a/third_party/libpng/patches/README +++ b/third_party/libpng/patches/README
@@ -5,8 +5,7 @@ == Patches applied on top of libpng == - - 0000-plte.patch: ARM NEON optimizations not yet released upstream. - 0001-chunkerror.patch: Change chunk errors into benign errors (https://crrev.com/c/1014027). - 0002-fuzzeroom.patch: Add custom malloc/free to limit too-large - allocations to prevent clusterfuzz OOMs (https://crrev.com/c/1330936). \ No newline at end of file + allocations to prevent clusterfuzz OOMs (https://crrev.com/c/1330936).
diff --git a/third_party/libpng/png.c b/third_party/libpng/png.c index a25afeb..757c755 100644 --- a/third_party/libpng/png.c +++ b/third_party/libpng/png.c
@@ -1,10 +1,10 @@ /* png.c - location for general purpose libpng functions * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018-2019 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -14,7 +14,7 @@ #include "pngpriv.h" /* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_35 Your_png_h_is_not_version_1_6_35; +typedef png_libpng_version_1_6_37 Your_png_h_is_not_version_1_6_37; #ifdef __GNUC__ /* The version tests may need to be added to, but the problem warning has @@ -736,7 +736,7 @@ int PNGAPI png_convert_to_rfc1123_buffer(char out[29], png_const_timep ptime) { - static PNG_CONST char short_months[12][4] = + static const char short_months[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; @@ -814,20 +814,14 @@ #ifdef PNG_STRING_COPYRIGHT return PNG_STRING_COPYRIGHT #else -# ifdef __STDC__ return PNG_STRING_NEWLINE \ - "libpng version 1.6.35 - July 15, 2018" PNG_STRING_NEWLINE \ + "libpng version 1.6.37" PNG_STRING_NEWLINE \ + "Copyright (c) 2018-2019 Cosmin Truta" PNG_STRING_NEWLINE \ "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \ PNG_STRING_NEWLINE \ "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \ "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \ PNG_STRING_NEWLINE; -# else - return "libpng version 1.6.35 - July 15, 2018\ - Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson\ - Copyright (c) 1996-1997 Andreas Dilger\ - Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc."; -# endif #endif } @@ -1121,7 +1115,7 @@ png_colorspacerp colorspace, png_fixed_point gAMA) { /* Changed in libpng-1.5.4 to limit the values to ensure overflow can't - * occur. Since the fixed point representation is asymetrical it is + * occur. Since the fixed point representation is asymmetrical it is * possible for 1/gamma to overflow the limit of 21474 and this means the * gamma value must be at least 5/100000 and hence at most 20000.0. For * safety the limits here are a little narrower. The values are 0.00016 to @@ -3134,11 +3128,11 @@ /* The total output count (max) is now 4+precision */ /* Check for an exponent, if we don't need one we are - * done and just need to terminate the string. At - * this point exp_b10==(-1) is effectively a flag - it got - * to '-1' because of the decrement after outputting - * the decimal point above (the exponent required is - * *not* -1!) + * done and just need to terminate the string. At this + * point, exp_b10==(-1) is effectively a flag: it got + * to '-1' because of the decrement, after outputting + * the decimal point above. (The exponent required is + * *not* -1.) */ if (exp_b10 >= (-1) && exp_b10 <= 2) { @@ -3976,18 +3970,18 @@ */ static void png_build_16bit_table(png_structrp png_ptr, png_uint_16pp *ptable, - PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) + unsigned int shift, png_fixed_point gamma_val) { /* Various values derived from 'shift': */ - PNG_CONST unsigned int num = 1U << (8U - shift); + unsigned int num = 1U << (8U - shift); #ifdef PNG_FLOATING_ARITHMETIC_SUPPORTED /* CSE the division and work round wacky GCC warnings (see the comments * in png_gamma_8bit_correct for where these come from.) */ - PNG_CONST double fmax = 1./(((png_int_32)1 << (16U - shift))-1); + double fmax = 1.0 / (((png_int_32)1 << (16U - shift)) - 1); #endif - PNG_CONST unsigned int max = (1U << (16U - shift))-1U; - PNG_CONST unsigned int max_by_2 = 1U << (15U-shift); + unsigned int max = (1U << (16U - shift)) - 1U; + unsigned int max_by_2 = 1U << (15U - shift); unsigned int i; png_uint_16pp table = *ptable = @@ -4053,10 +4047,10 @@ */ static void png_build_16to8_table(png_structrp png_ptr, png_uint_16pp *ptable, - PNG_CONST unsigned int shift, PNG_CONST png_fixed_point gamma_val) + unsigned int shift, png_fixed_point gamma_val) { - PNG_CONST unsigned int num = 1U << (8U - shift); - PNG_CONST unsigned int max = (1U << (16U - shift))-1U; + unsigned int num = 1U << (8U - shift); + unsigned int max = (1U << (16U - shift))-1U; unsigned int i; png_uint_32 last; @@ -4121,7 +4115,7 @@ */ static void png_build_8bit_table(png_structrp png_ptr, png_bytepp ptable, - PNG_CONST png_fixed_point gamma_val) + png_fixed_point gamma_val) { unsigned int i; png_bytep table = *ptable = (png_bytep)png_malloc(png_ptr, 256); @@ -4594,8 +4588,7 @@ if (image != NULL && image->opaque != NULL && image->opaque->error_buf == NULL) { - /* Ignore errors here: */ - (void)png_safe_execute(image, png_image_free_function, image); + png_image_free_function(image); image->opaque = NULL; } }
diff --git a/third_party/libpng/png.h b/third_party/libpng/png.h index 19e464cc..139eb0dc 100644 --- a/third_party/libpng/png.h +++ b/third_party/libpng/png.h
@@ -1,68 +1,105 @@ /* png.h - header file for PNG reference library * - * libpng version 1.6.35, July 15, 2018 + * libpng version 1.6.37 - April 14, 2019 * + * Copyright (c) 2018-2019 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * - * This code is released under the libpng license (See LICENSE, below) + * This code is released under the libpng license. (See LICENSE, below.) * * Authors and maintainers: * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat * libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger - * libpng versions 0.97, January 1998, through 1.6.35, July 15, 2018: - * Glenn Randers-Pehrson. + * libpng versions 0.97, January 1998, through 1.6.35, July 2018: + * Glenn Randers-Pehrson + * libpng versions 1.6.36, December 2018, through 1.6.37, April 2019: + * Cosmin Truta * See also "Contributing Authors", below. */ /* - * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE: + * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE + * ========================================= * - * If you modify libpng you may insert additional notices immediately following - * this sentence. + * PNG Reference Library License version 2 + * --------------------------------------- * - * This code is released under the libpng license. + * * Copyright (c) 1995-2019 The PNG Reference Library Authors. + * * Copyright (c) 2018-2019 Cosmin Truta. + * * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson. + * * Copyright (c) 1996-1997 Andreas Dilger. + * * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * - * libpng versions 1.0.7, July 1, 2000 through 1.6.35, July 15, 2018 are + * The software is supplied "as is", without warranty of any kind, + * express or implied, including, without limitation, the warranties + * of merchantability, fitness for a particular purpose, title, and + * non-infringement. In no event shall the Copyright owners, or + * anyone distributing the software, be liable for any damages or + * other liability, whether in contract, tort or otherwise, arising + * from, out of, or in connection with the software, or the use or + * other dealings in the software, even if advised of the possibility + * of such damage. + * + * Permission is hereby granted to use, copy, modify, and distribute + * this software, or portions hereof, for any purpose, without fee, + * subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you + * must not claim that you wrote the original software. If you + * use this software in a product, an acknowledgment in the product + * documentation would be appreciated, but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must + * not be misrepresented as being the original software. + * + * 3. This Copyright notice may not be removed or altered from any + * source or altered source distribution. + * + * + * PNG Reference Library License version 1 (for libpng 0.5 through 1.6.35) + * ----------------------------------------------------------------------- + * + * libpng versions 1.0.7, July 1, 2000, through 1.6.35, July 15, 2018 are * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson, are * derived from libpng-1.0.6, and are distributed according to the same * disclaimer and license as libpng-1.0.6 with the following individuals * added to the list of Contributing Authors: * - * Simon-Pierre Cadieux - * Eric S. Raymond - * Mans Rullgard - * Cosmin Truta - * Gilles Vollant - * James Yu - * Mandar Sahastrabuddhe - * Google Inc. - * Vadim Barkov + * Simon-Pierre Cadieux + * Eric S. Raymond + * Mans Rullgard + * Cosmin Truta + * Gilles Vollant + * James Yu + * Mandar Sahastrabuddhe + * Google Inc. + * Vadim Barkov * * and with the following additions to the disclaimer: * - * There is no warranty against interference with your enjoyment of the - * library or against infringement. There is no warranty that our - * efforts or the library will fulfill any of your particular purposes - * or needs. This library is provided with all faults, and the entire - * risk of satisfactory quality, performance, accuracy, and effort is with - * the user. + * There is no warranty against interference with your enjoyment of + * the library or against infringement. There is no warranty that our + * efforts or the library will fulfill any of your particular purposes + * or needs. This library is provided with all faults, and the entire + * risk of satisfactory quality, performance, accuracy, and effort is + * with the user. * * Some files in the "contrib" directory and some configure-generated - * files that are distributed with libpng have other copyright owners and + * files that are distributed with libpng have other copyright owners, and * are released under other open source licenses. * * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are * Copyright (c) 1998-2000 Glenn Randers-Pehrson, are derived from * libpng-0.96, and are distributed according to the same disclaimer and - * license as libpng-0.96, with the following individuals added to the list - * of Contributing Authors: + * license as libpng-0.96, with the following individuals added to the + * list of Contributing Authors: * - * Tom Lane - * Glenn Randers-Pehrson - * Willem van Schaik + * Tom Lane + * Glenn Randers-Pehrson + * Willem van Schaik * * libpng versions 0.89, June 1996, through 0.96, May 1997, are * Copyright (c) 1996-1997 Andreas Dilger, are derived from libpng-0.88, @@ -70,14 +107,14 @@ * libpng-0.88, with the following individuals added to the list of * Contributing Authors: * - * John Bowler - * Kevin Bracey - * Sam Bushell - * Magnus Holmgren - * Greg Roelofs - * Tom Tanner + * John Bowler + * Kevin Bracey + * Sam Bushell + * Magnus Holmgren + * Greg Roelofs + * Tom Tanner * - * Some files in the "scripts" directory have other copyright owners + * Some files in the "scripts" directory have other copyright owners, * but are released under this license. * * libpng versions 0.5, May 1995, through 0.88, January 1996, are @@ -86,62 +123,49 @@ * For the purposes of this copyright and license, "Contributing Authors" * is defined as the following set of individuals: * - * Andreas Dilger - * Dave Martindale - * Guy Eric Schalnat - * Paul Schmidt - * Tim Wegner + * Andreas Dilger + * Dave Martindale + * Guy Eric Schalnat + * Paul Schmidt + * Tim Wegner * - * The PNG Reference Library is supplied "AS IS". The Contributing Authors - * and Group 42, Inc. disclaim all warranties, expressed or implied, - * including, without limitation, the warranties of merchantability and of - * fitness for any purpose. The Contributing Authors and Group 42, Inc. - * assume no liability for direct, indirect, incidental, special, exemplary, - * or consequential damages, which may result from the use of the PNG - * Reference Library, even if advised of the possibility of such damage. + * The PNG Reference Library is supplied "AS IS". The Contributing + * Authors and Group 42, Inc. disclaim all warranties, expressed or + * implied, including, without limitation, the warranties of + * merchantability and of fitness for any purpose. The Contributing + * Authors and Group 42, Inc. assume no liability for direct, indirect, + * incidental, special, exemplary, or consequential damages, which may + * result from the use of the PNG Reference Library, even if advised of + * the possibility of such damage. * * Permission is hereby granted to use, copy, modify, and distribute this * source code, or portions hereof, for any purpose, without fee, subject * to the following restrictions: * - * 1. The origin of this source code must not be misrepresented. + * 1. The origin of this source code must not be misrepresented. * - * 2. Altered versions must be plainly marked as such and must not - * be misrepresented as being the original source. + * 2. Altered versions must be plainly marked as such and must not + * be misrepresented as being the original source. * - * 3. This Copyright notice may not be removed or altered from any - * source or altered source distribution. + * 3. This Copyright notice may not be removed or altered from any + * source or altered source distribution. * - * The Contributing Authors and Group 42, Inc. specifically permit, without - * fee, and encourage the use of this source code as a component to - * supporting the PNG file format in commercial products. If you use this - * source code in a product, acknowledgment is not required but would be - * appreciated. + * The Contributing Authors and Group 42, Inc. specifically permit, + * without fee, and encourage the use of this source code as a component + * to supporting the PNG file format in commercial products. If you use + * this source code in a product, acknowledgment is not required but would + * be appreciated. * * END OF COPYRIGHT NOTICE, DISCLAIMER, and LICENSE. * - * TRADEMARK: + * TRADEMARK + * ========= * - * The name "libpng" has not been registered by the Copyright owner + * The name "libpng" has not been registered by the Copyright owners * as a trademark in any jurisdiction. However, because libpng has * been distributed and maintained world-wide, continually since 1995, - * the Copyright owner claims "common-law trademark protection" in any + * the Copyright owners claim "common-law trademark protection" in any * jurisdiction where common-law trademark is recognized. - * - * OSI CERTIFICATION: - * - * Libpng is OSI Certified Open Source Software. OSI Certified Open Source is - * a certification mark of the Open Source Initiative. OSI has not addressed - * the additional disclaimers inserted at version 1.0.7. - * - * EXPORT CONTROL: - * - * The Copyright owner believes that the Export Control Classification - * Number (ECCN) for libpng is EAR99, which means not subject to export - * controls or International Traffic in Arms Regulations (ITAR) because - * it is open source, publicly available software, that does not contain - * any encryption software. See the EAR, paragraphs 734.3(b)(3) and - * 734.7(b). */ /* @@ -207,23 +231,25 @@ * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible) * 1.0.7 1 10007 (still compatible) * ... - * 1.0.19 10 10019 10.so.0.19[.0] + * 1.0.69 10 10069 10.so.0.69[.0] * ... - * 1.2.59 13 10257 12.so.0.59[.0] + * 1.2.59 13 10259 12.so.0.59[.0] * ... - * 1.5.30 15 10527 15.so.15.30[.0] + * 1.4.20 14 10420 14.so.0.20[.0] * ... - * 1.6.35 16 10635 16.so.16.35[.0] + * 1.5.30 15 10530 15.so.15.30[.0] + * ... + * 1.6.37 16 10637 16.so.16.37[.0] * - * Henceforth the source version will match the shared-library major - * and minor numbers; the shared-library major version number will be - * used for changes in backward compatibility, as it is intended. The - * PNG_LIBPNG_VER macro, which is not used within libpng but is available - * for applications, is an unsigned integer of the form xyyzz corresponding - * to the source version x.y.z (leading zeros in y and z). Beta versions - * were given the previous public release number plus a letter, until - * version 1.0.6j; from then on they were given the upcoming public - * release number plus "betaNN" or "rcNN". + * Henceforth the source version will match the shared-library major and + * minor numbers; the shared-library major version number will be used for + * changes in backward compatibility, as it is intended. + * The PNG_LIBPNG_VER macro, which is not used within libpng but is + * available for applications, is an unsigned integer of the form XYYZZ + * corresponding to the source version X.Y.Z (leading zeros in Y and Z). + * Beta versions were given the previous public release number plus a + * letter, until version 1.0.6j; from then on they were given the upcoming + * public release number plus "betaNN" or "rcNN". * * Binary incompatibility exists only when applications make direct access * to the info_ptr or png_ptr members through png.h, and the compiled @@ -233,65 +259,8 @@ * in binary compatibility (e.g., when a new feature is added). * * See libpng.txt or libpng.3 for more information. The PNG specification - * is available as a W3C Recommendation and as an ISO Specification, - * <https://www.w3.org/TR/2003/REC-PNG-20031110/ - */ - -/* - * Y2K compliance in libpng: - * ========================= - * - * July 15, 2018 - * - * Since the PNG Development group is an ad-hoc body, we can't make - * an official declaration. - * - * This is your unofficial assurance that libpng from version 0.71 and - * upward through 1.6.35 are Y2K compliant. It is my belief that - * earlier versions were also Y2K compliant. - * - * Libpng only has two year fields. One is a 2-byte unsigned integer - * that will hold years up to 65535. The other, which is deprecated, - * holds the date in text format, and will hold years up to 9999. - * - * The integer is - * "png_uint_16 year" in png_time_struct. - * - * The string is - * "char time_buffer[29]" in png_struct. This is no longer used - * in libpng-1.6.x and will be removed from libpng-1.7.0. - * - * There are seven time-related functions: - * png.c: png_convert_to_rfc_1123_buffer() in png.c - * (formerly png_convert_to_rfc_1123() prior to libpng-1.5.x and - * png_convert_to_rfc_1152() in error prior to libpng-0.98) - * png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c - * png_convert_from_time_t() in pngwrite.c - * png_get_tIME() in pngget.c - * png_handle_tIME() in pngrutil.c, called in pngread.c - * png_set_tIME() in pngset.c - * png_write_tIME() in pngwutil.c, called in pngwrite.c - * - * All handle dates properly in a Y2K environment. The - * png_convert_from_time_t() function calls gmtime() to convert from system - * clock time, which returns (year - 1900), which we properly convert to - * the full 4-digit year. There is a possibility that libpng applications - * are not passing 4-digit years into the png_convert_to_rfc_1123_buffer() - * function, or that they are incorrectly passing only a 2-digit year - * instead of "year - 1900" into the png_convert_from_struct_tm() function, - * but this is not under our control. The libpng documentation has always - * stated that it works with 4-digit years, and the APIs have been - * documented as such. - * - * The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned - * integer to hold the year, and can hold years as large as 65535. - * - * zlib, upon which libpng depends, is also Y2K compliant. It contains - * no date-related code. - * - * Glenn Randers-Pehrson - * libpng maintainer - * PNG Development Group + * is available as a W3C Recommendation and as an ISO/IEC Standard; see + * <https://www.w3.org/TR/2003/REC-PNG-20031110/> */ #ifndef PNG_H @@ -309,8 +278,8 @@ */ /* Version information for png.h - this should match the version in png.c */ -#define PNG_LIBPNG_VER_STRING "1.6.35" -#define PNG_HEADER_VERSION_STRING " libpng version 1.6.35 - July 15, 2018\n" +#define PNG_LIBPNG_VER_STRING "1.6.37" +#define PNG_HEADER_VERSION_STRING " libpng version 1.6.37 - April 14, 2019\n" #define PNG_LIBPNG_VER_SONUM 16 #define PNG_LIBPNG_VER_DLLNUM 16 @@ -318,13 +287,12 @@ /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */ #define PNG_LIBPNG_VER_MAJOR 1 #define PNG_LIBPNG_VER_MINOR 6 -#define PNG_LIBPNG_VER_RELEASE 35 +#define PNG_LIBPNG_VER_RELEASE 37 -/* This should match the numeric part of the final component of - * PNG_LIBPNG_VER_STRING, omitting any leading zero: +/* This should be zero for a public release, or non-zero for a + * development version. [Deprecated] */ - -#define PNG_LIBPNG_VER_BUILD 02 +#define PNG_LIBPNG_VER_BUILD 0 /* Release Status */ #define PNG_LIBPNG_BUILD_ALPHA 1 @@ -341,15 +309,16 @@ #define PNG_LIBPNG_BUILD_SPECIAL 32 /* Cannot be OR'ed with PNG_LIBPNG_BUILD_PRIVATE */ -#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_BETA +#define PNG_LIBPNG_BUILD_BASE_TYPE PNG_LIBPNG_BUILD_STABLE -/* Careful here. At one time, Guy wanted to use 082, but that would be octal. - * We must not include leading zeros. - * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only - * version 1.0.0 was mis-numbered 100 instead of 10000). From - * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release +/* Careful here. At one time, Guy wanted to use 082, but that + * would be octal. We must not include leading zeros. + * Versions 0.7 through 1.0.0 were in the range 0 to 100 here + * (only version 1.0.0 was mis-numbered 100 instead of 10000). + * From version 1.0.1 it is: + * XXYYZZ, where XX=major, YY=minor, ZZ=release */ -#define PNG_LIBPNG_VER 10635 /* 1.6.35 */ +#define PNG_LIBPNG_VER 10637 /* 1.6.37 */ /* Library configuration: these options cannot be changed after * the library has been built. @@ -459,7 +428,7 @@ /* This triggers a compiler error in png.c, if png.c and png.h * do not agree upon the version number. */ -typedef char* png_libpng_version_1_6_35; +typedef char* png_libpng_version_1_6_37; /* Basic control structions. Read libpng-manual.txt or libpng.3 for more info. * @@ -2013,12 +1982,12 @@ PNG_EXPORT(246, png_uint_32, png_get_eXIf, (png_const_structrp png_ptr, png_inforp info_ptr, png_bytep *exif)); PNG_EXPORT(247, void, png_set_eXIf, (png_const_structrp png_ptr, - png_inforp info_ptr, const png_bytep exif)); + png_inforp info_ptr, png_bytep exif)); PNG_EXPORT(248, png_uint_32, png_get_eXIf_1, (png_const_structrp png_ptr, png_const_inforp info_ptr, png_uint_32 *num_exif, png_bytep *exif)); PNG_EXPORT(249, void, png_set_eXIf_1, (png_const_structrp png_ptr, - png_inforp info_ptr, const png_uint_32 num_exif, const png_bytep exif)); + png_inforp info_ptr, png_uint_32 num_exif, png_bytep exif)); #endif #ifdef PNG_gAMA_SUPPORTED @@ -2764,7 +2733,7 @@ * * When the simplified API needs to convert between sRGB and linear colorspaces, * the actual sRGB transfer curve defined in the sRGB specification (see the - * article at https://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2 + * article at <https://en.wikipedia.org/wiki/SRGB>) is used, not the gamma=1/2.2 * approximation used elsewhere in libpng. * * When an alpha channel is present it is expected to denote pixel coverage @@ -2967,7 +2936,7 @@ * 'flags' field of png_image. */ #define PNG_IMAGE_FLAG_COLORSPACE_NOT_sRGB 0x01 - /* This indicates the the RGB values of the in-memory bitmap do not + /* This indicates that the RGB values of the in-memory bitmap do not * correspond to the red, green and blue end-points defined by sRGB. */
diff --git a/third_party/libpng/pngconf.h b/third_party/libpng/pngconf.h index a4646ba..927a769d 100644 --- a/third_party/libpng/pngconf.h +++ b/third_party/libpng/pngconf.h
@@ -1,11 +1,12 @@ -/* pngconf.h - machine configurable file for libpng +/* pngconf.h - machine-configurable file for libpng * - * libpng version 1.6.35, July 15, 2018 + * libpng version 1.6.37 * + * Copyright (c) 2018-2019 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -57,14 +58,13 @@ #endif /* PNG_BUILDING_SYMBOL_TABLE */ -/* Prior to 1.6.0 it was possible to turn off 'const' in declarations using - * PNG_NO_CONST; this is no longer supported except for data declarations which - * apparently still cause problems in 2011 on some compilers. +/* Prior to 1.6.0, it was possible to turn off 'const' in declarations, + * using PNG_NO_CONST. This is no longer supported. */ #define PNG_CONST const /* backward compatibility only */ -/* This controls optimization of the reading of 16-bit and 32-bit values - * from PNG files. It can be set on a per-app-file basis - it +/* This controls optimization of the reading of 16-bit and 32-bit + * values from PNG files. It can be set on a per-app-file basis: it * just changes whether a macro is used when the function is called. * The library builder sets the default; if read functions are not * built into the library the macro implementation is forced on.
diff --git a/third_party/libpng/pngdebug.h b/third_party/libpng/pngdebug.h index 15a7ed0c..00d5a45 100644 --- a/third_party/libpng/pngdebug.h +++ b/third_party/libpng/pngdebug.h
@@ -1,10 +1,10 @@ /* pngdebug.h - Debugging macros for libpng, also used in pngtest.c * - * Last changed in libpng 1.6.8 [December 19, 2013] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2013 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer
diff --git a/third_party/libpng/pngerror.c b/third_party/libpng/pngerror.c index ad48bfb..ec3a709b9 100644 --- a/third_party/libpng/pngerror.c +++ b/third_party/libpng/pngerror.c
@@ -1,10 +1,10 @@ /* pngerror.c - stub functions for i/o and memory allocation * - * Last changed in libpng 1.6.31 [July 27, 2017] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -425,7 +425,7 @@ * if the character is invalid. */ #define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) -static PNG_CONST char png_digit[16] = { +static const char png_digit[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; @@ -885,7 +885,7 @@ png_safe_error),(png_structp png_nonconst_ptr, png_const_charp error_message), PNG_NORETURN) { - const png_const_structrp png_ptr = png_nonconst_ptr; + png_const_structrp png_ptr = png_nonconst_ptr; png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr); /* An error is always logged here, overwriting anything (typically a warning) @@ -920,7 +920,7 @@ void /* PRIVATE */ PNGCBAPI png_safe_warning(png_structp png_nonconst_ptr, png_const_charp warning_message) { - const png_const_structrp png_ptr = png_nonconst_ptr; + png_const_structrp png_ptr = png_nonconst_ptr; png_imagep image = png_voidcast(png_imagep, png_ptr->error_ptr); /* A warning is only logged if there is no prior warning or error. */
diff --git a/third_party/libpng/pngget.c b/third_party/libpng/pngget.c index 2325508..5abf1efd 100644 --- a/third_party/libpng/pngget.c +++ b/third_party/libpng/pngget.c
@@ -1,10 +1,10 @@ /* pngget.c - retrieval of values from info struct * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer
diff --git a/third_party/libpng/pnginfo.h b/third_party/libpng/pnginfo.h index 2fcf868..1f98ded 100644 --- a/third_party/libpng/pnginfo.h +++ b/third_party/libpng/pnginfo.h
@@ -1,10 +1,10 @@ /* pnginfo.h - header file for PNG reference library * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2013,2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer
diff --git a/third_party/libpng/pngmem.c b/third_party/libpng/pngmem.c index ff3ef7e..09ed9c1c 100644 --- a/third_party/libpng/pngmem.c +++ b/third_party/libpng/pngmem.c
@@ -1,10 +1,10 @@ /* pngmem.c - stub functions for memory allocation * - * Last changed in libpng 1.6.26 [October 20, 2016] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2014,2016 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer
diff --git a/third_party/libpng/pngpread.c b/third_party/libpng/pngpread.c index c4ba51c..e283627b 100644 --- a/third_party/libpng/pngpread.c +++ b/third_party/libpng/pngpread.c
@@ -1,10 +1,10 @@ /* pngpread.c - read a png file in push mode * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -972,20 +972,20 @@ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - static PNG_CONST png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; + static const png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - static PNG_CONST png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; + static const png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; /* Start of interlace block in the y direction */ - static PNG_CONST png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; + static const png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; /* Offset to next interlace block in the y direction */ - static PNG_CONST png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; + static const png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; /* Height of interlace block. This is not currently used - if you need * it, uncomment it here and in png.h - static PNG_CONST png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; + static const png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; */ #endif
diff --git a/third_party/libpng/pngpriv.h b/third_party/libpng/pngpriv.h index 441a8f98..583c26f 100644 --- a/third_party/libpng/pngpriv.h +++ b/third_party/libpng/pngpriv.h
@@ -1,10 +1,10 @@ /* pngpriv.h - private declarations for use inside libpng * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018-2019 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -174,7 +174,10 @@ # else /* !defined __ARM_NEON__ */ /* The 'intrinsics' code simply won't compile without this -mfpu=neon: */ -# define PNG_ARM_NEON_IMPLEMENTATION 2 +# if !defined(__aarch64__) + /* The assembler code currently does not work on ARM64 */ +# define PNG_ARM_NEON_IMPLEMENTATION 2 +# endif /* __aarch64__ */ # endif /* __ARM_NEON__ */ # endif /* !PNG_ARM_NEON_IMPLEMENTATION */ @@ -1534,10 +1537,10 @@ #endif PNG_INTERNAL_FUNCTION(void,png_check_chunk_name,(png_const_structrp png_ptr, - const png_uint_32 chunk_name),PNG_EMPTY); + png_uint_32 chunk_name),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_check_chunk_length,(png_const_structrp png_ptr, - const png_uint_32 chunk_length),PNG_EMPTY); + png_uint_32 chunk_length),PNG_EMPTY); PNG_INTERNAL_FUNCTION(void,png_handle_unknown,(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length, int keep),PNG_EMPTY); @@ -2116,11 +2119,11 @@ #if PNG_ARM_NEON_IMPLEMENTATION == 1 PNG_INTERNAL_FUNCTION(void, - png_riffle_palette_rgba, - (png_structrp, png_row_infop), + png_riffle_palette_neon, + (png_structrp), PNG_EMPTY); PNG_INTERNAL_FUNCTION(int, - png_do_expand_palette_neon_rgba, + png_do_expand_palette_rgba8_neon, (png_structrp, png_row_infop, png_const_bytep, @@ -2128,7 +2131,7 @@ const png_bytepp), PNG_EMPTY); PNG_INTERNAL_FUNCTION(int, - png_do_expand_palette_neon_rgb, + png_do_expand_palette_rgb8_neon, (png_structrp, png_row_infop, png_const_bytep,
diff --git a/third_party/libpng/pngread.c b/third_party/libpng/pngread.c index bff7503..8fa7d9f 100644 --- a/third_party/libpng/pngread.c +++ b/third_party/libpng/pngread.c
@@ -1,10 +1,10 @@ /* pngread.c - read a PNG file * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018-2019 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -994,6 +994,12 @@ png_ptr->chunk_list = NULL; #endif +#if defined(PNG_READ_EXPAND_SUPPORTED) && \ + defined(PNG_ARM_NEON_IMPLEMENTATION) + png_free(png_ptr, png_ptr->riffled_palette); + png_ptr->riffled_palette = NULL; +#endif + /* NOTE: the 'setjmp' buffer may still be allocated and the memory and error * callbacks are still set at this point. They are required to complete the * destruction of the png_struct itself. @@ -1621,7 +1627,7 @@ * errors (which are unfortunately quite common.) */ { - static PNG_CONST png_byte chunks_to_process[] = { + static const png_byte chunks_to_process[] = { 98, 75, 71, 68, '\0', /* bKGD */ 99, 72, 82, 77, '\0', /* cHRM */ 103, 65, 77, 65, '\0', /* gAMA */ @@ -1758,9 +1764,9 @@ png_uint_32 alpha, int encoding) { png_imagep image = display->image; - const int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ? + int output_encoding = (image->format & PNG_FORMAT_FLAG_LINEAR) != 0 ? P_LINEAR : P_sRGB; - const int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 && + int convert_to_Y = (image->format & PNG_FORMAT_FLAG_COLOR) == 0 && (red != green || green != blue); if (ip > 255) @@ -1869,13 +1875,13 @@ /* Store the value. */ { # ifdef PNG_FORMAT_AFIRST_SUPPORTED - const int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 && + int afirst = (image->format & PNG_FORMAT_FLAG_AFIRST) != 0 && (image->format & PNG_FORMAT_FLAG_ALPHA) != 0; # else # define afirst 0 # endif # ifdef PNG_FORMAT_BGR_SUPPORTED - const int bgr = (image->format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; + int bgr = (image->format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; # else # define bgr 0 # endif @@ -2085,11 +2091,11 @@ { png_image_read_control *display = png_voidcast(png_image_read_control*, argument); - const png_imagep image = display->image; + png_imagep image = display->image; - const png_structrp png_ptr = image->opaque->png_ptr; - const png_uint_32 output_format = image->format; - const int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) != 0 ? + png_structrp png_ptr = image->opaque->png_ptr; + png_uint_32 output_format = image->format; + int output_encoding = (output_format & PNG_FORMAT_FLAG_LINEAR) != 0 ? P_LINEAR : P_sRGB; unsigned int cmap_entries; @@ -2802,7 +2808,7 @@ unsigned int num_trans = png_ptr->num_trans; png_const_bytep trans = num_trans > 0 ? png_ptr->trans_alpha : NULL; png_const_colorp colormap = png_ptr->palette; - const int do_background = trans != NULL && + int do_background = trans != NULL && (output_format & PNG_FORMAT_FLAG_ALPHA) == 0; unsigned int i; @@ -3946,7 +3952,7 @@ */ if (linear != 0) { - PNG_CONST png_uint_16 le = 0x0001; + png_uint_16 le = 0x0001; if ((*(png_const_bytep) & le) != 0) png_set_swap(png_ptr); @@ -4108,7 +4114,7 @@ * original PNG format because it may not occur in the output PNG format * and libpng deals with the issues of reading the original. */ - const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); + unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); /* The following checks just the 'row_stride' calculation to ensure it * fits in a signed 32-bit value. Because channels/components can be @@ -4119,7 +4125,7 @@ if (image->width <= 0x7fffffffU/channels) /* no overflow */ { png_uint_32 check; - const png_uint_32 png_row_stride = image->width * channels; + png_uint_32 png_row_stride = image->width * channels; if (row_stride == 0) row_stride = (png_int_32)/*SAFE*/png_row_stride;
diff --git a/third_party/libpng/pngrio.c b/third_party/libpng/pngrio.c index 3722214..7946358 100644 --- a/third_party/libpng/pngrio.c +++ b/third_party/libpng/pngrio.c
@@ -1,10 +1,10 @@ /* pngrio.c - functions for data input * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer
diff --git a/third_party/libpng/pngrtran.c b/third_party/libpng/pngrtran.c index ffa46bc2..786e0de5 100644 --- a/third_party/libpng/pngrtran.c +++ b/third_party/libpng/pngrtran.c
@@ -1,10 +1,10 @@ /* pngrtran.c - transforms the data in a row for PNG readers * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018-2019 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -19,10 +19,14 @@ #include "pngpriv.h" #ifdef PNG_ARM_NEON_IMPLEMENTATION -#if PNG_ARM_NEON_IMPLEMENTATION == 1 -#define PNG_ARM_NEON_INTRINSICS_AVAILABLE -#include <arm_neon.h> -#endif +# if PNG_ARM_NEON_IMPLEMENTATION == 1 +# define PNG_ARM_NEON_INTRINSICS_AVAILABLE +# if defined(_MSC_VER) && defined(_M_ARM64) && !defined(__clang__) +# include <arm64_neon.h> +# else +# include <arm_neon.h> +# endif +# endif #endif #ifdef PNG_READ_SUPPORTED @@ -1178,20 +1182,20 @@ png_ptr->palette[png_ptr->background.index].blue; #ifdef PNG_READ_INVERT_ALPHA_SUPPORTED - if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) - { - if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0) - { - /* Invert the alpha channel (in tRNS) unless the pixels are - * going to be expanded, in which case leave it for later - */ - int i, istop = png_ptr->num_trans; + if ((png_ptr->transformations & PNG_INVERT_ALPHA) != 0) + { + if ((png_ptr->transformations & PNG_EXPAND_tRNS) == 0) + { + /* Invert the alpha channel (in tRNS) unless the pixels are + * going to be expanded, in which case leave it for later + */ + int i, istop = png_ptr->num_trans; - for (i=0; i<istop; i++) - png_ptr->trans_alpha[i] = (png_byte)(255 - - png_ptr->trans_alpha[i]); - } - } + for (i = 0; i < istop; i++) + png_ptr->trans_alpha[i] = + (png_byte)(255 - png_ptr->trans_alpha[i]); + } + } #endif /* READ_INVERT_ALPHA */ } } /* background expand and (therefore) no alpha association. */ @@ -2993,7 +2997,6 @@ */ static int png_do_rgb_to_gray(png_structrp png_ptr, png_row_infop row_info, png_bytep row) - { int rgb_error = 0; @@ -3002,12 +3005,11 @@ if ((row_info->color_type & PNG_COLOR_MASK_PALETTE) == 0 && (row_info->color_type & PNG_COLOR_MASK_COLOR) != 0) { - PNG_CONST png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; - PNG_CONST png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; - PNG_CONST png_uint_32 bc = 32768 - rc - gc; - PNG_CONST png_uint_32 row_width = row_info->width; - PNG_CONST int have_alpha = - (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0; + png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff; + png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff; + png_uint_32 bc = 32768 - rc - gc; + png_uint_32 row_width = row_info->width; + int have_alpha = (row_info->color_type & PNG_COLOR_MASK_ALPHA) != 0; if (row_info->bit_depth == 8) { @@ -4150,12 +4152,11 @@ { if (row_info->bit_depth == 8) { - PNG_CONST png_bytep table = png_ptr->gamma_from_1; + png_bytep table = png_ptr->gamma_from_1; if (table != NULL) { - PNG_CONST int step = - (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2; + int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 4 : 2; /* The alpha channel is the last component: */ row += step - 1; @@ -4169,13 +4170,12 @@ else if (row_info->bit_depth == 16) { - PNG_CONST png_uint_16pp table = png_ptr->gamma_16_from_1; - PNG_CONST int gamma_shift = png_ptr->gamma_shift; + png_uint_16pp table = png_ptr->gamma_16_from_1; + int gamma_shift = png_ptr->gamma_shift; if (table != NULL) { - PNG_CONST int step = - (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4; + int step = (row_info->color_type & PNG_COLOR_MASK_COLOR) ? 8 : 4; /* The alpha channel is the last component: */ row += step - 2; @@ -4207,8 +4207,8 @@ */ static void png_do_expand_palette(png_structrp png_ptr, png_row_infop row_info, - png_bytep row, png_const_colorp palette, png_const_bytep trans_alpha, - int num_trans) + png_bytep row, png_const_colorp palette, png_const_bytep trans_alpha, + int num_trans) { int shift, value; png_bytep sp, dp; @@ -4314,22 +4314,25 @@ i = 0; #ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE - if (png_ptr->riffled_palette != NULL) { + if (png_ptr->riffled_palette != NULL) + { /* The RGBA optimization works with png_ptr->bit_depth == 8 - but sometimes row_info->bit_depth has been changed to 8. - In these cases, the palette hasn't been riffled. */ - i = png_do_expand_palette_neon_rgba(png_ptr, row_info, row, &sp, &dp); + * but sometimes row_info->bit_depth has been changed to 8. + * In these cases, the palette hasn't been riffled. + */ + i = png_do_expand_palette_rgba8_neon(png_ptr, row_info, row, + &sp, &dp); } +#else + PNG_UNUSED(png_ptr) #endif for (; i < row_width; i++) { if ((int)(*sp) >= num_trans) *dp-- = 0xff; - else *dp-- = trans_alpha[*sp]; - *dp-- = palette[*sp].blue; *dp-- = palette[*sp].green; *dp-- = palette[*sp].red; @@ -4348,7 +4351,10 @@ dp = row + (size_t)(row_width * 3) - 1; i = 0; #ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE - i = png_do_expand_palette_neon_rgb(png_ptr, row_info, row, &sp, &dp); + i = png_do_expand_palette_rgb8_neon(png_ptr, row_info, row, + &sp, &dp); +#else + PNG_UNUSED(png_ptr) #endif for (; i < row_width; i++) @@ -4766,20 +4772,19 @@ if (row_info->color_type == PNG_COLOR_TYPE_PALETTE) { #ifdef PNG_ARM_NEON_INTRINSICS_AVAILABLE - if ((png_ptr->num_trans > 0) && (png_ptr->bit_depth == 8)) { - /* Allocate space for the decompressed full palette. */ - if (png_ptr->riffled_palette == NULL) { - png_ptr->riffled_palette = png_malloc(png_ptr, 256*4); - if (png_ptr->riffled_palette == NULL) { - png_error(png_ptr, "NULL row buffer"); - } - /* Build the RGBA palette. */ - png_riffle_palette_rgba(png_ptr, row_info); - } - } + if ((png_ptr->num_trans > 0) && (png_ptr->bit_depth == 8)) + { + if (png_ptr->riffled_palette == NULL) + { + /* Initialize the accelerated palette expansion. */ + png_ptr->riffled_palette = + (png_bytep)png_malloc(png_ptr, 256 * 4); + png_riffle_palette_neon(png_ptr); + } + } #endif png_do_expand_palette(png_ptr, row_info, png_ptr->row_buf + 1, - png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); + png_ptr->palette, png_ptr->trans_alpha, png_ptr->num_trans); } else
diff --git a/third_party/libpng/pngrutil.c b/third_party/libpng/pngrutil.c index 4bb5a89..3007414 100644 --- a/third_party/libpng/pngrutil.c +++ b/third_party/libpng/pngrutil.c
@@ -1,10 +1,10 @@ /* pngrutil.c - utilities to read a PNG file * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -1461,8 +1461,7 @@ { /* We have the ICC profile header; do the basic header checks. */ - const png_uint_32 profile_length = - png_get_uint_32(profile_header); + png_uint_32 profile_length = png_get_uint_32(profile_header); if (png_icc_check_length(png_ptr, &png_ptr->colorspace, keyword, profile_length) != 0) @@ -1479,8 +1478,8 @@ * profile. The header check has already validated * that none of this stuff will overflow. */ - const png_uint_32 tag_count = png_get_uint_32( - profile_header+128); + png_uint_32 tag_count = + png_get_uint_32(profile_header + 128); png_bytep profile = png_read_buffer(png_ptr, profile_length, 2/*silent*/); @@ -3132,7 +3131,7 @@ */ void /* PRIVATE */ -png_check_chunk_name(png_const_structrp png_ptr, const png_uint_32 chunk_name) +png_check_chunk_name(png_const_structrp png_ptr, png_uint_32 chunk_name) { int i; png_uint_32 cn=chunk_name; @@ -3151,7 +3150,7 @@ } void /* PRIVATE */ -png_check_chunk_length(png_const_structrp png_ptr, const png_uint_32 length) +png_check_chunk_length(png_const_structrp png_ptr, png_uint_32 length) { png_alloc_size_t limit = PNG_UINT_31_MAX; @@ -3363,7 +3362,7 @@ /* Hence the pre-compiled masks indexed by PACKSWAP (or not), depth and * then pass: */ - static PNG_CONST png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] = + static const png_uint_32 row_mask[2/*PACKSWAP*/][3/*depth*/][6] = { /* Little-endian byte masks for PACKSWAP */ { S_MASKS(1,0), S_MASKS(2,0), S_MASKS(4,0) }, @@ -3374,7 +3373,7 @@ /* display_mask has only three entries for the odd passes, so index by * pass>>1. */ - static PNG_CONST png_uint_32 display_mask[2][3][3] = + static const png_uint_32 display_mask[2][3][3] = { /* Little-endian byte masks for PACKSWAP */ { B_MASKS(1,0), B_MASKS(2,0), B_MASKS(4,0) }, @@ -3687,7 +3686,7 @@ { /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Offset to next interlace block */ - static PNG_CONST unsigned int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static const unsigned int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; png_debug(1, "in png_do_read_interlace"); if (row != NULL && row_info != NULL) @@ -4329,16 +4328,16 @@ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; /* Start of interlace block in the y direction */ - static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; /* Offset to next interlace block in the y direction */ - static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; png_debug(1, "in png_read_finish_row"); png_ptr->row_number++; @@ -4394,16 +4393,16 @@ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; /* Start of interlace block in the y direction */ - static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; /* Offset to next interlace block in the y direction */ - static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; unsigned int max_pixel_depth; size_t row_bytes;
diff --git a/third_party/libpng/pngset.c b/third_party/libpng/pngset.c index 7cf54d9..ec75dbe 100644 --- a/third_party/libpng/pngset.c +++ b/third_party/libpng/pngset.c
@@ -1,10 +1,10 @@ /* pngset.c - storage of image information into info struct * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -137,7 +137,7 @@ #ifdef PNG_eXIf_SUPPORTED void PNGAPI png_set_eXIf(png_const_structrp png_ptr, png_inforp info_ptr, - const png_bytep eXIf_buf) + png_bytep eXIf_buf) { png_warning(png_ptr, "png_set_eXIf does not work; use png_set_eXIf_1"); PNG_UNUSED(info_ptr) @@ -146,7 +146,7 @@ void PNGAPI png_set_eXIf_1(png_const_structrp png_ptr, png_inforp info_ptr, - const png_uint_32 num_exif, const png_bytep eXIf_buf) + png_uint_32 num_exif, png_bytep eXIf_buf) { int i; @@ -1399,7 +1399,7 @@ /* Ignore all unknown chunks and all chunks recognized by * libpng except for IHDR, PLTE, tRNS, IDAT, and IEND */ - static PNG_CONST png_byte chunks_to_ignore[] = { + static const png_byte chunks_to_ignore[] = { 98, 75, 71, 68, '\0', /* bKGD */ 99, 72, 82, 77, '\0', /* cHRM */ 101, 88, 73, 102, '\0', /* eXIf */
diff --git a/third_party/libpng/pngstruct.h b/third_party/libpng/pngstruct.h index 1656ac23..8bdc7ce 100644 --- a/third_party/libpng/pngstruct.h +++ b/third_party/libpng/pngstruct.h
@@ -1,10 +1,10 @@ /* pngstruct.h - header file for PNG reference library * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018-2019 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -228,10 +228,6 @@ * big_row_buf; while writing it is separately * allocated. */ -#ifdef PNG_READ_EXPAND_SUPPORTED - /* Buffer to accelerate palette transformations. */ - png_bytep riffled_palette; -#endif #ifdef PNG_WRITE_FILTER_SUPPORTED png_bytep try_row; /* buffer to save trial row when filtering */ png_bytep tst_row; /* buffer to save best trial row when filtering */ @@ -396,6 +392,12 @@ /* deleted in 1.5.5: rgb_to_gray_blue_coeff; */ #endif +/* New member added in libpng-1.6.36 */ +#if defined(PNG_READ_EXPAND_SUPPORTED) && \ + defined(PNG_ARM_NEON_IMPLEMENTATION) + png_bytep riffled_palette; /* buffer for accelerated palette expansion */ +#endif + /* New member added in libpng-1.0.4 (renamed in 1.0.9) */ #if defined(PNG_MNG_FEATURES_SUPPORTED) /* Changed from png_byte to png_uint_32 at version 1.2.0 */
diff --git a/third_party/libpng/pngtest.c b/third_party/libpng/pngtest.c index 4411fd9..a715ae11 100644 --- a/third_party/libpng/pngtest.c +++ b/third_party/libpng/pngtest.c
@@ -1,10 +1,10 @@ /* pngtest.c - a simple test program to test libpng * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018-2019 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -449,13 +449,13 @@ */ typedef struct { - PNG_CONST char *file_name; + const char *file_name; } pngtest_error_parameters; static void PNGCBAPI pngtest_warning(png_structp png_ptr, png_const_charp message) { - PNG_CONST char *name = "UNKNOWN (ERROR!)"; + const char *name = "UNKNOWN (ERROR!)"; pngtest_error_parameters *test = (pngtest_error_parameters*)png_get_error_ptr(png_ptr); @@ -850,7 +850,7 @@ /* Test one file */ static int -test_one_file(PNG_CONST char *inname, PNG_CONST char *outname) +test_one_file(const char *inname, const char *outname) { static png_FILE_p fpin; static png_FILE_p fpout; /* "static" prevents setjmp corruption */ @@ -957,6 +957,8 @@ if (setjmp(png_jmpbuf(write_ptr))) { fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname); + png_free(read_ptr, row_buf); + row_buf = NULL; if (verbose != 0) fprintf(STDERR, " destroying read structs\n"); png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); @@ -1436,7 +1438,7 @@ row_buf = (png_bytep)png_malloc(read_ptr, png_get_rowbytes(read_ptr, read_info_ptr)); - pngtest_debug1("\t0x%08lx", (unsigned long)row_buf); + pngtest_debug1("\t%p", row_buf); #endif /* SINGLE_ROWBUF_ALLOC */ pngtest_debug("Writing row data"); @@ -1490,7 +1492,7 @@ row_buf = (png_bytep)png_malloc(read_ptr, png_get_rowbytes(read_ptr, read_info_ptr)); - pngtest_debug2("\t0x%08lx (%lu bytes)", (unsigned long)row_buf, + pngtest_debug2("\t%p (%lu bytes)", row_buf, (unsigned long)png_get_rowbytes(read_ptr, read_info_ptr)); #endif /* !SINGLE_ROWBUF_ALLOC */ @@ -1809,11 +1811,11 @@ /* Input and output filenames */ #ifdef RISCOS -static PNG_CONST char *inname = "pngtest/png"; -static PNG_CONST char *outname = "pngout/png"; +static const char *inname = "pngtest/png"; +static const char *outname = "pngout/png"; #else -static PNG_CONST char *inname = "pngtest.png"; -static PNG_CONST char *outname = "pngout.png"; +static const char *inname = "pngtest.png"; +static const char *outname = "pngout.png"; #endif int @@ -2153,4 +2155,4 @@ #endif /* Generate a compiler error if there is an old png.h in the search path. */ -typedef png_libpng_version_1_6_35 Your_png_h_is_not_version_1_6_35; +typedef png_libpng_version_1_6_37 Your_png_h_is_not_version_1_6_37;
diff --git a/third_party/libpng/pngtrans.c b/third_party/libpng/pngtrans.c index de84aa6..1100f46e 100644 --- a/third_party/libpng/pngtrans.c +++ b/third_party/libpng/pngtrans.c
@@ -1,10 +1,10 @@ /* pngtrans.c - transforms the data in a row (used by both readers and writers) * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -345,7 +345,7 @@ #endif #if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED) -static PNG_CONST png_byte onebppswaptable[256] = { +static const png_byte onebppswaptable[256] = { 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, @@ -380,7 +380,7 @@ 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF }; -static PNG_CONST png_byte twobppswaptable[256] = { +static const png_byte twobppswaptable[256] = { 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0, 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0, 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4, @@ -415,7 +415,7 @@ 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF }; -static PNG_CONST png_byte fourbppswaptable[256] = { +static const png_byte fourbppswaptable[256] = { 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0, 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
diff --git a/third_party/libpng/pngwio.c b/third_party/libpng/pngwio.c index e5391687..10e919d 100644 --- a/third_party/libpng/pngwio.c +++ b/third_party/libpng/pngwio.c
@@ -1,10 +1,10 @@ /* pngwio.c - functions for data output * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2014,2016,2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer
diff --git a/third_party/libpng/pngwrite.c b/third_party/libpng/pngwrite.c index a831f48..59377a4dd 100644 --- a/third_party/libpng/pngwrite.c +++ b/third_party/libpng/pngwrite.c
@@ -1,10 +1,10 @@ /* pngwrite.c - general routines to write a PNG file * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018-2019 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -469,7 +469,7 @@ #ifdef PNG_CONVERT_tIME_SUPPORTED void PNGAPI -png_convert_from_struct_tm(png_timep ptime, PNG_CONST struct tm * ttime) +png_convert_from_struct_tm(png_timep ptime, const struct tm * ttime) { png_debug(1, "in png_convert_from_struct_tm"); @@ -948,10 +948,6 @@ png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list); png_free(png_ptr, png_ptr->row_buf); png_ptr->row_buf = NULL; -#ifdef PNG_READ_EXPANDED_SUPPORTED - png_free(png_ptr, png_ptr->riffled_palette); - png_ptr->riffled_palette = NULL; -#endif #ifdef PNG_WRITE_FILTER_SUPPORTED png_free(png_ptr, png_ptr->prev_row); png_free(png_ptr, png_ptr->try_row); @@ -1540,7 +1536,7 @@ display->first_row); png_uint_16p output_row = png_voidcast(png_uint_16p, display->local_row); png_uint_16p row_end; - const unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? + unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; int aindex = 0; png_uint_32 y = image->height; @@ -1577,7 +1573,7 @@ while (out_ptr < row_end) { - const png_uint_16 alpha = in_ptr[aindex]; + png_uint_16 alpha = in_ptr[aindex]; png_uint_32 reciprocal = 0; int c; @@ -1699,7 +1695,7 @@ display->first_row); png_bytep output_row = png_voidcast(png_bytep, display->local_row); png_uint_32 y = image->height; - const unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? + unsigned int channels = (image->format & PNG_FORMAT_FLAG_COLOR) != 0 ? 3 : 1; if ((image->format & PNG_FORMAT_FLAG_ALPHA) != 0) @@ -1787,25 +1783,25 @@ static void png_image_set_PLTE(png_image_write_control *display) { - const png_imagep image = display->image; + png_imagep image = display->image; const void *cmap = display->colormap; - const int entries = image->colormap_entries > 256 ? 256 : + int entries = image->colormap_entries > 256 ? 256 : (int)image->colormap_entries; /* NOTE: the caller must check for cmap != NULL and entries != 0 */ - const png_uint_32 format = image->format; - const unsigned int channels = PNG_IMAGE_SAMPLE_CHANNELS(format); + png_uint_32 format = image->format; + unsigned int channels = PNG_IMAGE_SAMPLE_CHANNELS(format); # if defined(PNG_FORMAT_BGR_SUPPORTED) &&\ defined(PNG_SIMPLIFIED_WRITE_AFIRST_SUPPORTED) - const int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 && + int afirst = (format & PNG_FORMAT_FLAG_AFIRST) != 0 && (format & PNG_FORMAT_FLAG_ALPHA) != 0; # else # define afirst 0 # endif # ifdef PNG_FORMAT_BGR_SUPPORTED - const int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; + int bgr = (format & PNG_FORMAT_FLAG_BGR) != 0 ? 2 : 0; # else # define bgr 0 # endif @@ -1955,12 +1951,12 @@ * and total image size to ensure that they are within the system limits. */ { - const unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); + unsigned int channels = PNG_IMAGE_PIXEL_CHANNELS(image->format); if (image->width <= 0x7fffffffU/channels) /* no overflow */ { png_uint_32 check; - const png_uint_32 png_row_stride = image->width * channels; + png_uint_32 png_row_stride = image->width * channels; if (display->row_stride == 0) display->row_stride = (png_int_32)/*SAFE*/png_row_stride; @@ -2056,7 +2052,7 @@ */ if (write_16bit != 0) { - PNG_CONST png_uint_16 le = 0x0001; + png_uint_16 le = 0x0001; if ((*(png_const_bytep) & le) != 0) png_set_swap(png_ptr); @@ -2170,7 +2166,7 @@ { png_image_write_control *display = png_voidcast(png_image_write_control*, png_ptr->io_ptr/*backdoor: png_get_io_ptr(png_ptr)*/); - const png_alloc_size_t ob = display->output_bytes; + png_alloc_size_t ob = display->output_bytes; /* Check for overflow; this should never happen: */ if (size <= ((png_alloc_size_t)-1) - ob)
diff --git a/third_party/libpng/pngwtran.c b/third_party/libpng/pngwtran.c index 3a1e0a21..49a13c1 100644 --- a/third_party/libpng/pngwtran.c +++ b/third_party/libpng/pngwtran.c
@@ -1,10 +1,10 @@ /* pngwtran.c - transforms the data in a row for PNG writers * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -254,8 +254,7 @@ for (i = 0; i < istop; i++, bp++) { - - const unsigned int c = i%channels; + unsigned int c = i%channels; int j; unsigned int v, out; @@ -283,7 +282,7 @@ for (bp = row, i = 0; i < istop; i++) { - const unsigned int c = i%channels; + unsigned int c = i%channels; int j; unsigned int value, v;
diff --git a/third_party/libpng/pngwutil.c b/third_party/libpng/pngwutil.c index ab431e7..16345e4 100644 --- a/third_party/libpng/pngwutil.c +++ b/third_party/libpng/pngwutil.c
@@ -1,10 +1,10 @@ /* pngwutil.c - utilities to write a PNG file * - * Last changed in libpng 1.6.35 [July 15, 2018] + * Copyright (c) 2018 Cosmin Truta * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson - * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) - * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + * Copyright (c) 1996-1997 Andreas Dilger + * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc. * * This code is released under the libpng license. * For conditions of distribution and use, see the disclaimer @@ -1893,16 +1893,16 @@ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; /* Start of interlace block in the y direction */ - static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; /* Offset to next interlace block in the y direction */ - static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; #endif png_alloc_size_t buf_size; @@ -2008,16 +2008,16 @@ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; /* Start of interlace block in the y direction */ - static PNG_CONST png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; + static const png_byte png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; /* Offset to next interlace block in the y direction */ - static PNG_CONST png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; + static const png_byte png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; #endif png_debug(1, "in png_write_finish_row"); @@ -2098,10 +2098,10 @@ /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ - static PNG_CONST png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; + static const png_byte png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; /* Offset to next interlace block */ - static PNG_CONST png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; + static const png_byte png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; png_debug(1, "in png_do_write_interlace"); @@ -2276,7 +2276,7 @@ #ifdef PNG_WRITE_FILTER_SUPPORTED static size_t /* PRIVATE */ -png_setup_sub_row(png_structrp png_ptr, const png_uint_32 bpp, +png_setup_sub_row(png_structrp png_ptr, png_uint_32 bpp, size_t row_bytes, size_t lmins) { png_bytep rp, dp, lp; @@ -2315,7 +2315,7 @@ } static void /* PRIVATE */ -png_setup_sub_row_only(png_structrp png_ptr, const png_uint_32 bpp, +png_setup_sub_row_only(png_structrp png_ptr, png_uint_32 bpp, size_t row_bytes) { png_bytep rp, dp, lp; @@ -2380,7 +2380,7 @@ } static size_t /* PRIVATE */ -png_setup_avg_row(png_structrp png_ptr, const png_uint_32 bpp, +png_setup_avg_row(png_structrp png_ptr, png_uint_32 bpp, size_t row_bytes, size_t lmins) { png_bytep rp, dp, pp, lp; @@ -2420,7 +2420,7 @@ return (sum); } static void /* PRIVATE */ -png_setup_avg_row_only(png_structrp png_ptr, const png_uint_32 bpp, +png_setup_avg_row_only(png_structrp png_ptr, png_uint_32 bpp, size_t row_bytes) { png_bytep rp, dp, pp, lp; @@ -2442,7 +2442,7 @@ } static size_t /* PRIVATE */ -png_setup_paeth_row(png_structrp png_ptr, const png_uint_32 bpp, +png_setup_paeth_row(png_structrp png_ptr, png_uint_32 bpp, size_t row_bytes, size_t lmins) { png_bytep rp, dp, pp, cp, lp; @@ -2503,7 +2503,7 @@ return (sum); } static void /* PRIVATE */ -png_setup_paeth_row_only(png_structrp png_ptr, const png_uint_32 bpp, +png_setup_paeth_row_only(png_structrp png_ptr, png_uint_32 bpp, size_t row_bytes) { png_bytep rp, dp, pp, cp, lp;
diff --git a/third_party/r8/README.chromium b/third_party/r8/README.chromium index 1a7e0df..209d12b 100644 --- a/third_party/r8/README.chromium +++ b/third_party/r8/README.chromium
@@ -1,7 +1,7 @@ Name: R8 URL: https://r8.googlesource.com/r8 Revision: 03ab76ff37d7995f76b639dec680cd49ff6fbc41 -Version: 1.5.18-dev +Version: 1.4.14-dev License: BSD 3-Clause License File: NOT_SHIPPED Security Critical: no
diff --git a/third_party/zlib/BUILD.gn b/third_party/zlib/BUILD.gn index 8d54d2a5..1a9cd3b 100644 --- a/third_party/zlib/BUILD.gn +++ b/third_party/zlib/BUILD.gn
@@ -78,7 +78,9 @@ defines += [ "ARMV8_OS_LINUX" ] } else if (is_fuchsia) { defines += [ "ARMV8_OS_FUCHSIA" ] - } else if (!is_win) { + } else if (is_win) { + defines += [ "ARMV8_OS_WINDOWS" ] + } else { assert(false, "Unsupported ARM OS") } }
diff --git a/third_party/zlib/arm_features.c b/third_party/zlib/arm_features.c index 73aca420..f5641c3 100644 --- a/third_party/zlib/arm_features.c +++ b/third_party/zlib/arm_features.c
@@ -7,14 +7,14 @@ #include "arm_features.h" #include "zutil.h" +#include <stdint.h> int ZLIB_INTERNAL arm_cpu_enable_crc32 = 0; int ZLIB_INTERNAL arm_cpu_enable_pmull = 0; -#if !defined(_MSC_VER) - +#if defined(ARMV8_OS_ANDROID) || defined(ARMV8_OS_LINUX) || defined(ARMV8_OS_FUCHSIA) #include <pthread.h> -#include <stdint.h> +#endif #if defined(ARMV8_OS_ANDROID) #include <cpu-features.h> @@ -25,18 +25,33 @@ #include <zircon/features.h> #include <zircon/syscalls.h> #include <zircon/types.h> +#elif defined(ARMV8_OS_WINDOWS) +#include <windows.h> #else #error arm_features.c ARM feature detection in not defined for your platform #endif -static pthread_once_t cpu_check_inited_once = PTHREAD_ONCE_INIT; - static void _arm_check_features(void); +#if defined(ARMV8_OS_ANDROID) || defined(ARMV8_OS_LINUX) || defined(ARMV8_OS_FUCHSIA) +static pthread_once_t cpu_check_inited_once = PTHREAD_ONCE_INIT; void ZLIB_INTERNAL arm_check_features(void) { pthread_once(&cpu_check_inited_once, _arm_check_features); } +#elif defined(ARMV8_OS_WINDOWS) +static INIT_ONCE cpu_check_inited_once = INIT_ONCE_STATIC_INIT; +static BOOL CALLBACK _arm_check_features_forwarder(PINIT_ONCE once, PVOID param, PVOID* context) +{ + _arm_check_features(); + return TRUE; +} +void ZLIB_INTERNAL arm_check_features(void) +{ + InitOnceExecuteOnce(&cpu_check_inited_once, _arm_check_features_forwarder, + NULL, NULL); +} +#endif /* * See http://bit.ly/2CcoEsr for run-time detection of ARM features and also @@ -68,36 +83,8 @@ return; /* Report nothing if ASIMD(NEON) is missing */ arm_cpu_enable_crc32 = !!(features & ZX_ARM64_FEATURE_ISA_CRC32); arm_cpu_enable_pmull = !!(features & ZX_ARM64_FEATURE_ISA_PMULL); +#elif defined(ARMV8_OS_WINDOWS) + arm_cpu_enable_crc32 = IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE); + arm_cpu_enable_pmull = IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE); #endif } - -#else /* _MSC_VER */ - -#include <windows.h> - -static INIT_ONCE cpu_check_inited_once = INIT_ONCE_STATIC_INIT; - -static BOOL CALLBACK _arm_check_features(PINIT_ONCE once, - PVOID param, - PVOID *context); - -void ZLIB_INTERNAL arm_check_features(void) -{ - InitOnceExecuteOnce(&cpu_check_inited_once, _arm_check_features, - NULL, NULL); -} - -static BOOL CALLBACK _arm_check_features(PINIT_ONCE once, - PVOID param, - PVOID *context) -{ - if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE)) - arm_cpu_enable_crc32 = 1; - - if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE)) - arm_cpu_enable_pmull = 1; - - return TRUE; -} - -#endif /* _MSC_VER */
diff --git a/tools/determinism/deterministic_build_whitelist.pyl b/tools/determinism/deterministic_build_whitelist.pyl index f6a4238..896abc4 100644 --- a/tools/determinism/deterministic_build_whitelist.pyl +++ b/tools/determinism/deterministic_build_whitelist.pyl
@@ -30,6 +30,11 @@ # https://crbug.com/937268 'swiftshader/libGLESv2.so', 'swiftshader_vertex_routine_fuzzer', + + # https://crbug.com/954056 + 'nacl_test_data/nonsfi/irt_exception_test_pnacl_newlib_x32_nonsfi.nexe', + 'nacl_test_data/nonsfi/irt_manifest_file_pnacl_newlib_x32_nonsfi.nexe', + 'test_data/ppapi/tests/extensions/packaged_app/nonsfi/ppapi_tests_extensions_packaged_app_pnacl_newlib_x32_nonsfi.nexe', ], # https://crbug.com/330262
diff --git a/tools/fuchsia/local-sdk.py b/tools/fuchsia/local-sdk.py index 6559018..3ad6db9 100755 --- a/tools/fuchsia/local-sdk.py +++ b/tools/fuchsia/local-sdk.py
@@ -33,11 +33,9 @@ def BuildForArch(arch): build_dir = 'out/release-' + arch - Run('scripts/fx', 'set', 'sdk_image.' + arch, - '--with=//topaz/packages/sdk:topaz', - '--args=is_debug=false', '--args=build_sdk_archives=true', - '--build-dir=' + build_dir) - Run('scripts/fx', 'build-zircon') + Run('scripts/fx', '--dir', build_dir, 'set', 'sdk_image.' + arch, + '--with=//topaz/packages/sdk:topaz', '--args=is_debug=false', + '--args=build_sdk_archives=true') Run('scripts/fx', 'build', 'topaz/public/sdk:topaz')
diff --git a/tools/gritsettings/resource_ids b/tools/gritsettings/resource_ids index 33dc989..364209b 100644 --- a/tools/gritsettings/resource_ids +++ b/tools/gritsettings/resource_ids
@@ -193,7 +193,8 @@ "messages": [15070], }, "components/components_strings.grd": { - "messages": [15100], + "includes": [15100], + "messages": [15110], }, "components/policy/resources/policy_templates.grd": { "structures": [17200],
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index cbe4bf5..8362887d 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -2042,6 +2042,13 @@ <int value="3" label="Camera"/> </enum> +<enum name="AppListLaunchedFrom"> + <int value="1" label="Launched From Grid"/> + <int value="2" label="Launched From SuggestionChip"/> + <int value="3" label="Launched From Shelf"/> + <int value="4" label="Launched From SearchBox"/> +</enum> + <enum name="AppListOmniboxResult"> <int value="0" label="QUERY_SUGGESTION"/> <int value="1" label="ZERO_STATE_SUGEESTION"/> @@ -10584,6 +10591,7 @@ <int value="19" label="User Cancelled While Setting Up Container"/> <int value="20" label="User Cancelled While Fetching SSH Keys"/> <int value="21" label="User Cancelled While Mounting Container"/> + <int value="22" label="Insufficient Disk Space"/> </enum> <enum name="CrostiniUISurface"> @@ -16601,6 +16609,7 @@ <int value="553" label="DeviceUsbPowerShareEnabled"/> <int value="554" label="PolicyListMultipleSourceMergeList"/> <int value="555" label="SamlPasswordExpirationAdvanceWarningDays"/> + <int value="556" label="DeviceScheduledUpdateCheck"/> </enum> <enum name="EnterprisePolicyInvalidations">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 5395e1d..9b3f88e 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -3819,15 +3819,21 @@ </histogram> <histogram name="Apps.AppListAppLaunched" enum="SuggestedAppListAppLaunched"> + <obsolete> + Deprecated as of 04/2019 in favor Apps.AppListAppLaunchedV2. + </obsolete> <owner>newcomer@chromium.org</owner> <summary> The number of apps launched from the launcher. This is logged each time an - app is launched. + app is launched. The bucket denotes whether the app is suggested. </summary> </histogram> <histogram name="Apps.AppListAppLaunchedFullscreen" enum="SuggestedAppListAppLaunched"> + <obsolete> + Deprecated as of 04/2019 in favor Apps.AppListAppLaunchedV2. + </obsolete> <owner>newcomer@chromium.org</owner> <summary> The number of apps launched from the fullscreen launcher. This is logged @@ -3836,6 +3842,19 @@ </summary> </histogram> +<histogram name="Apps.AppListAppLaunchedV2" enum="AppListLaunchedFrom" + expires_after="2020-04-01"> +<!-- Name completed by histogram_suffixes name="AppListState" --> + + <owner>mmourgos@chromium.org</owner> + <owner>newcomer@chromium.org</owner> + <summary> + The number of apps launched from the launcher and shelf for each launcher + state. This is incremented each time an app is launched. Each bucket + represents where in the launcher or shelf the app was launched from. + </summary> +</histogram> + <histogram name="Apps.AppListAppMovingType" enum="AppListAppMovingType"> <owner>weidongg@chromium.org</owner> <summary> @@ -142545,6 +142564,18 @@ <affected-histogram name="Apps.AppsInFolders"/> </histogram_suffixes> +<histogram_suffixes name="AppListState" separator="."> + <suffix name="Closed"/> + <suffix name="FullscreenAllApps"/> + <suffix name="FullscreenSearch"/> + <suffix name="Half"/> + <suffix name="HomecherAllApps"/> + <suffix name="HomecherClosed"/> + <suffix name="HomecherSearch"/> + <suffix name="Peeking"/> + <affected-histogram name="Apps.AppListAppLaunchedV2"/> +</histogram_suffixes> + <histogram_suffixes name="AppListTargetState" separator="."> <suffix name="Close.ClamshellMode" label="Closing the app list"/> <suffix name="FullscreenAllApps.ClamshellMode" @@ -146546,8 +146577,6 @@ </histogram_suffixes> <histogram_suffixes name="ImageFetcherClients" separator="."> - <suffix name="AnswerSuggestions" - label="Showing cache patterns only for AnswerSuggestions."/> <suffix name="AssistantDetails" label="Showing cache patterns only for AssistantDetails."/> <suffix name="ContextualSuggestions" @@ -151269,6 +151298,9 @@ <suffix name="Clients.SignedExchange" label="PageLoadMetrics for page loads for which the document was served through a signed exchange."/> + <suffix name="Clients.SignedExchange.Cached" + label="PageLoadMetrics for page loads for which the document was served + through a cached signed exchange."/> <affected-histogram name="PageLoad.DocumentTiming.NavigationToDOMContentLoadedEventFired"/> <affected-histogram
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index c59f462..6b9f0ad 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -2639,6 +2639,13 @@ Metrics recorded each time we commit a history navigation, which are needed to estimate benefits of back-forward cache. </summary> + <metric name="CrossOriginSubframesFeatures"> + <summary> + Bitmask of features used by the cross origin subframes of the previous + page load. See blink::SchedulingPolicy::Feature for the meaning for the + individual features. + </summary> + </metric> <metric name="LastCommittedSourceIdForTheSameDocument"> <summary> For history navigations and reloads, the source id of the previous @@ -2666,6 +2673,13 @@ It's expected to be rare, but might be problematic for back-forward cache. </summary> </metric> + <metric name="SameOriginSubframesFeatures"> + <summary> + Bitmask of features used by the same origin subframes of the previous page + load. See blink::SchedulingPolicy::Feature for the meaning for the + individual features. + </summary> + </metric> <metric name="TimeSinceNavigatedAwayFromDocument"> <summary> Time in milliseconds from the moment the current navigation stopped being
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index 4a8095f..47d8dc7 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -244,6 +244,7 @@ <item id="service_worker_update_checker" hash_code="130931413" type="0" content_hash_code="46608086" os_list="linux,windows" file_path="content/browser/service_worker/service_worker_single_script_update_checker.cc"/> <item id="services_http_server_error_response" hash_code="59302801" type="0" content_hash_code="127774041" os_list="linux,windows" file_path="services/network/public/cpp/server/http_server.cc"/> <item id="sigined_exchange_cert_fetcher" hash_code="79442849" type="0" content_hash_code="8138156" os_list="linux,windows" file_path="content/browser/web_package/signed_exchange_cert_fetcher.cc"/> +<item id="sigined_exchange_validity_pinger" hash_code="57114284" type="0" content_hash_code="119482488" os_list="linux,windows" file_path="content/browser/web_package/signed_exchange_validity_pinger.cc"/> <item id="signed_in_profile_avatar" hash_code="108903331" type="0" content_hash_code="72850619" os_list="linux,windows" file_path="chrome/browser/profiles/profile_downloader.cc"/> <item id="socket_bio_adapter" hash_code="516551" type="0" content_hash_code="21643352" os_list="linux,windows" file_path="net/socket/socket_bio_adapter.cc"/> <item id="spdy_push_stream" hash_code="36915753" type="0" content_hash_code="69224629" os_list="linux,windows" file_path="net/spdy/spdy_session.cc"/>
diff --git a/ui/android/java/res/values/color_palette.xml b/ui/android/java/res/values/color_palette.xml index 9117047..6aa2966 100644 --- a/ui/android/java/res/values/color_palette.xml +++ b/ui/android/java/res/values/color_palette.xml
@@ -59,6 +59,11 @@ <color name="default_text_color_light">@android:color/white</color> <color name="default_text_color_dark_secondary">@color/modern_grey_700</color> + <!-- TODO(https://crbug.com/953917): Update the highlight colors to meet accessibility + contrast ratio. --> + <color name="highlight_color_on_light_text" tools:ignore="UnusedResources">#CC5595FE</color> + <color name="highlight_color_on_dark_text" tools:ignore="UnusedResources">#C6DAFC</color> + <color name="default_red_light" tools:ignore="UnusedResources">@color/google_red_300</color> <color name="default_red_dark" tools:ignore="UnusedResources">@color/google_red_600</color>
diff --git a/ui/android/java/src/org/chromium/ui/DropdownPopupWindowImpl.java b/ui/android/java/src/org/chromium/ui/DropdownPopupWindowImpl.java index f756a4a5..0d088f664 100644 --- a/ui/android/java/src/org/chromium/ui/DropdownPopupWindowImpl.java +++ b/ui/android/java/src/org/chromium/ui/DropdownPopupWindowImpl.java
@@ -140,12 +140,17 @@ boolean wasShowing = mAnchoredPopupWindow.isShowing(); mAnchoredPopupWindow.setVerticalOverlapAnchor(false); mAnchoredPopupWindow.setHorizontalOverlapAnchor(true); + + int windowWidthPx = mContext.getResources().getDisplayMetrics().widthPixels; int contentWidth = measureContentWidth(); - if (mAnchorView.getWidth() < contentWidth) { + if (windowWidthPx < contentWidth + mHorizontalPadding) { + mAnchoredPopupWindow.setMaxWidth(windowWidthPx - mHorizontalPadding); + } else if (mAnchorView.getWidth() < contentWidth) { mAnchoredPopupWindow.setMaxWidth(contentWidth + mHorizontalPadding); } else { mAnchoredPopupWindow.setMaxWidth(mAnchorView.getWidth() + mHorizontalPadding); } + mAnchoredPopupWindow.show(); mListView.setDividerHeight(0); int layoutDirection = mRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR;
diff --git a/ui/android/java/src/org/chromium/ui/base/LocalizationUtils.java b/ui/android/java/src/org/chromium/ui/base/LocalizationUtils.java index b8b084b..f41bf20f 100644 --- a/ui/android/java/src/org/chromium/ui/base/LocalizationUtils.java +++ b/ui/android/java/src/org/chromium/ui/base/LocalizationUtils.java
@@ -108,6 +108,34 @@ } /** + * Return one default locale-specific PAK file name associated with a given language. + * + * @param language Language name (e.g. "en"). + * @return A Chromium-specific locale name (e.g. "en-US") matching the input language + * that can be used to access compressed locale pak files. + */ + public static String getDefaultCompressedPakLocaleForLanguage(String language) { + // IMPORTANT: Keep in sync with the mapping found in: + // //build/android/gyp/resource_utils.py + + // NOTE: All languages provide locale files named '<language>.pak', except + // for a few exceptions listed below. E.g. for the English language, + // the 'en-US.pak' and 'en-GB.pak' files are provided, and there is + // no 'en.pak' file. + switch (language) { + case "en": + return "en-US"; + case "pt": + return "pt-PT"; + case "zh": + return "zh-CN"; + default: + // NOTE: for Spanish (es), both es.pak and es-419.pak are used. Hence this works. + return language; + } + } + + /** * Return true iff a locale string matches a specific language string. * * @param locale Chromium locale name (e.g. "fil", or "en-US").
diff --git a/ui/android/java/src/org/chromium/ui/base/ResourceBundle.java b/ui/android/java/src/org/chromium/ui/base/ResourceBundle.java index 69f7f4c..25aef12 100644 --- a/ui/android/java/src/org/chromium/ui/base/ResourceBundle.java +++ b/ui/android/java/src/org/chromium/ui/base/ResourceBundle.java
@@ -4,17 +4,10 @@ package org.chromium.ui.base; -import android.content.res.AssetFileDescriptor; -import android.content.res.AssetManager; - import org.chromium.base.BuildConfig; -import org.chromium.base.ContextUtils; -import org.chromium.base.LocaleUtils; -import org.chromium.base.Log; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; -import java.io.IOException; import java.util.Arrays; /** @@ -25,51 +18,10 @@ final class ResourceBundle { private ResourceBundle() {} - private static final String TAG = "ResourceBundle"; - - /** - * Return the location of a locale-specific uncompress .pak file asset. - * - * @param locale Chromium locale name. - * @param inBundle If true, return the path of the uncompressed .pak file - * containing Chromium UI strings within app bundles. If - * false, return the path of the uncompressed WebView UI - * strings instead. Note that APK .pak files are stored - * compressed and handled differently. - * @return Asset path to uncompressed .pak file, or null if the locale is - * not supported by this version of Chromium, or the file is - * missing. - */ @CalledByNative - private static String getLocalePakResourcePath(String locale, boolean inBundle) { - if (Arrays.binarySearch(BuildConfig.UNCOMPRESSED_LOCALES, locale) < 0) { - // This locale is not supported by Chromium. - return null; - } - String pathPrefix = "assets/stored-locales/"; - if (inBundle) { - if (locale.equals("en-US")) { - pathPrefix = "assets/fallback-locales/"; - } else { - String lang = LocalizationUtils.getSplitLanguageForAndroid( - LocaleUtils.toLanguage(locale)); - pathPrefix = "assets/locales#lang_" + lang + "/"; - } - } - String assetPath = pathPrefix + locale + ".pak"; - AssetManager manager = ContextUtils.getApplicationContext().getAssets(); - try (AssetFileDescriptor afd = manager.openNonAssetFd(assetPath)) { - return assetPath; - } catch (IOException e) { - // It makes sense to log here when the file exists, but is unable to be opened as an fd - // because (for example) it is unexpectedly compressed in an apk. In that case, the log - // message might save someone some time working out what has gone wrong. - // For that reason, we only suppress the message when the exception message doesn't look - // informative (Android framework passes the filename as the message on actual file not - // found, and the empty string also wouldn't give any useful information for debugging) - if (!e.getMessage().equals("") && !e.getMessage().equals(assetPath)) { - Log.e(TAG, "Error while loading asset %s: %s", assetPath, e); - } + private static String getLocalePakResourcePath(String locale) { + if (Arrays.binarySearch(BuildConfig.UNCOMPRESSED_LOCALES, locale) >= 0) { + return "assets/stored-locales/" + locale + ".pak"; } return null; }
diff --git a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java index 0779d0a6..cb12a04 100644 --- a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java +++ b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java
@@ -155,15 +155,12 @@ new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION)); List<String> missingPermissions = new ArrayList<>(); - if (shouldUsePhotoPicker()) { - if (BuildInfo.isAtLeastQ()) { - String newImagePermission = "android.permission.READ_MEDIA_IMAGES"; - if (!window.hasPermission(newImagePermission)) { - missingPermissions.add(newImagePermission); - } - } else if (!window.hasPermission(Manifest.permission.READ_EXTERNAL_STORAGE)) { - missingPermissions.add(Manifest.permission.READ_EXTERNAL_STORAGE); - } + String storagePermission = BuildInfo.isAtLeastQ() + ? "android.permission.READ_MEDIA_IMAGES" + : Manifest.permission.READ_EXTERNAL_STORAGE; + boolean shouldUsePhotoPicker = shouldUsePhotoPicker(); + if (shouldUsePhotoPicker) { + if (!window.hasPermission(storagePermission)) missingPermissions.add(storagePermission); } else { if (((mSupportsImageCapture && shouldShowImageTypes()) || (mSupportsVideoCapture && shouldShowVideoTypes())) @@ -183,9 +180,17 @@ missingPermissions.toArray(new String[missingPermissions.size()]); window.requestPermissions(requestPermissions, (permissions, grantResults) -> { for (int i = 0; i < grantResults.length; i++) { - if (grantResults[i] == PackageManager.PERMISSION_DENIED && mCapture) { - onFileNotSelected(); - return; + if (grantResults[i] == PackageManager.PERMISSION_DENIED) { + if (mCapture) { + onFileNotSelected(); + return; + } + + if (shouldUsePhotoPicker + && requestPermissions[i].equals(storagePermission)) { + onFileNotSelected(); + return; + } } } launchSelectFileIntent();
diff --git a/ui/android/java/src/org/chromium/ui/resources/ResourceExtractor.java b/ui/android/java/src/org/chromium/ui/resources/ResourceExtractor.java index 75370d6..123c8f1f 100644 --- a/ui/android/java/src/org/chromium/ui/resources/ResourceExtractor.java +++ b/ui/android/java/src/org/chromium/ui/resources/ResourceExtractor.java
@@ -39,8 +39,8 @@ private static final String V8_SNAPSHOT_DATA_FILENAME = "snapshot_blob.bin"; private static final String FALLBACK_LOCALE = "en-US"; private static final String COMPRESSED_LOCALES_DIR = "locales"; + private static final String COMPRESSED_LOCALES_FALLBACK_DIR = "fallback-locales"; private static final int BUFFER_SIZE = 16 * 1024; - private static final boolean DEBUG = false; private class ExtractTask implements Runnable { private final List<Runnable> mCompletionCallbacks = new ArrayList<Runnable>(); @@ -159,10 +159,8 @@ // NOTE: The UI language will differ from the application's language // when the system locale is not directly supported by Chrome's // resources. - if (DEBUG) { - Log.i(TAG, "Using UI language %s, system language: %s (Android name: %s)", uiLanguage, - chromiumLanguage, androidLanguage); - } + Log.i(TAG, "Using UI locale %s, system locale: %s (Android name: %s)", uiLanguage, + chromiumLanguage, androidLanguage); // Currenty (Apr 2018), this array can be as big as 6 entries, so using a capacity // that allows a bit of growth, but is still in the right ballpark.. @@ -178,35 +176,64 @@ activeLocales.add(FALLBACK_LOCALE); } - // * For bundles, locale pak files are always stored uncompressed - // either under base.apk!/assets/fallback-locales/<locale>.pak or - // base-<lang>.apk!/assets/locales#lang_<lang>/<locale>.pak. They - // never need to be extracted. - // // * For regular APKs, the locale pak files are stored under: // base.apk!/assets/locales/<locale>.pak // // where <locale> is a Chromium-specific locale name. // + // * When using app bundles, the locale pak files are stored in + // language-specific directories that look like: + // <split>.apk!/assets/locales#lang_<lang>/<locale>.pak + // + // Where <lang> is an Android-specific ISO-639-1 language identifier. + // + // * With the exception of the fallback (English) pak files which are stored + // in the base module under: + // assets/locales-fallback/<locale>.pak + // + // Moreover, when the bundle uses APK splits, there is no guarantee that the split + // corresponding to the current device locale is installed yet, but the one matching + // uiLanguage should be there, since the value is determined by loading a resource string + // from the current application's asset manager. + // AssetManager assetManager = ContextUtils.getApplicationAssets(); - if (!assetPathHasFile( - assetManager, COMPRESSED_LOCALES_DIR, activeLocales.get(0) + ".pak")) { - if (DEBUG) { - Log.i(TAG, "No locale pak files to extract, assuming app bundle."); - } + String localesSrcDir; + String androidSplitLanguage = LocalizationUtils.getSplitLanguageForAndroid(uiLanguage); + String langSpecificPath = COMPRESSED_LOCALES_DIR + "#lang_" + androidSplitLanguage; + String defaultLocalePakName = + LocalizationUtils.getDefaultCompressedPakLocaleForLanguage(uiLanguage) + ".pak"; + + if (assetPathHasFile(assetManager, langSpecificPath, defaultLocalePakName)) { + // This is an app bundle, and the split containing the pak files for + // the current locale is installed. + localesSrcDir = langSpecificPath; + } else if (assetPathHasFile( + assetManager, COMPRESSED_LOCALES_DIR, activeLocales.get(0) + ".pak")) { + // This is a regular APK, and all pak files are available. + localesSrcDir = COMPRESSED_LOCALES_DIR; + } else if (assetPathHasFile(assetManager, COMPRESSED_LOCALES_FALLBACK_DIR, + activeLocales.get(0) + ".pak")) { + // This is a fallback language pak file. + localesSrcDir = COMPRESSED_LOCALES_FALLBACK_DIR; + } else { + // This is an app bundle, but the split containing the pak files for the current UI + // locale is *not* installed yet. This should never happen in theory, and there is + // little that can be done at this point, so return an empty list. Nothing will get + // extracted, and Chromium may later crash when trying to access the PAK file from + // native code. + Log.e(TAG, "Android Locale: %s misses split for .pak files: %s", defaultLocale, + Arrays.toString(activeLocales.toArray())); return new String[] {}; } - // This is a regular APK, and all pak files are available. // Return the list of locale pak file paths corresponding to the current language. String[] localePakFiles = new String[activeLocales.size()]; for (int n = 0; n < activeLocales.size(); ++n) { - localePakFiles[n] = COMPRESSED_LOCALES_DIR + '/' + activeLocales.get(n) + ".pak"; + localePakFiles[n] = localesSrcDir + '/' + activeLocales.get(n) + ".pak"; } - if (DEBUG) { - Log.i(TAG, "UI Language '%s' will use %s.", uiLanguage, - Arrays.toString(localePakFiles)); - } + Log.i(TAG, "Using app bundle locale directory: " + localesSrcDir); + Log.i(TAG, "UI Language: %s requires .pak files: %s", uiLanguage, + Arrays.toString(activeLocales.toArray())); return localePakFiles; } @@ -225,14 +252,10 @@ try { InputStream input = assetManager.open(assetFilePath); input.close(); - if (DEBUG) { - Log.i(TAG, "Found asset file: " + assetFilePath); - } + Log.i(TAG, "Found asset file: " + assetFilePath); return true; } catch (IOException e) { - if (DEBUG) { - Log.i(TAG, "No asset file at: " + assetFilePath); - } + Log.i(TAG, "Missing asset file: " + assetFilePath); return false; } }
diff --git a/ui/android/junit/src/org/chromium/ui/base/LocalizationUtilsTest.java b/ui/android/junit/src/org/chromium/ui/base/LocalizationUtilsTest.java index 09724c4..d061381 100644 --- a/ui/android/junit/src/org/chromium/ui/base/LocalizationUtilsTest.java +++ b/ui/android/junit/src/org/chromium/ui/base/LocalizationUtilsTest.java
@@ -24,6 +24,16 @@ public class LocalizationUtilsTest { @Test @SmallTest + public void testGetDefaultCompressedPakLocaleForLanguage() { + assertEquals("fr", LocalizationUtils.getDefaultCompressedPakLocaleForLanguage("fr")); + assertEquals("es", LocalizationUtils.getDefaultCompressedPakLocaleForLanguage("es")); + assertEquals("en-US", LocalizationUtils.getDefaultCompressedPakLocaleForLanguage("en")); + assertEquals("pt-PT", LocalizationUtils.getDefaultCompressedPakLocaleForLanguage("pt")); + assertEquals("zh-CN", LocalizationUtils.getDefaultCompressedPakLocaleForLanguage("zh")); + } + + @Test + @SmallTest public void testGetSplitLanguageForAndroid() { assertEquals("en", LocalizationUtils.getSplitLanguageForAndroid("en")); assertEquals("es", LocalizationUtils.getSplitLanguageForAndroid("es"));
diff --git a/ui/base/resource/resource_bundle_android.cc b/ui/base/resource/resource_bundle_android.cc index 0b80d9c7..899bb583 100644 --- a/ui/base/resource/resource_bundle_android.cc +++ b/ui/base/resource/resource_bundle_android.cc
@@ -55,10 +55,9 @@ } int LoadLocalePakFromApk(const std::string& app_locale, - bool in_split, base::MemoryMappedFile::Region* out_region) { std::string locale_path_within_apk = - GetPathForAndroidLocalePakWithinApk(app_locale, in_split); + GetPathForAndroidLocalePakWithinApk(app_locale); if (locale_path_within_apk.empty()) { LOG(WARNING) << "locale_path_within_apk.empty() for locale " << app_locale; @@ -108,10 +107,8 @@ // static bool ResourceBundle::LocaleDataPakExists(const std::string& locale) { if (g_locale_paks_in_apk) { - return !GetPathForAndroidLocalePakWithinApk(locale, false).empty(); + return !GetPathForAndroidLocalePakWithinApk(locale).empty(); } - if (!GetPathForAndroidLocalePakWithinApk(locale, true).empty()) - return true; return !GetLocaleFilePath(locale, true).empty(); } @@ -126,75 +123,23 @@ } std::string app_locale = l10n_util::GetApplicationLocale(pref_locale); - // Some Chromium apps have two sets of .pak files for their UI strings, i.e.: - // - // a) WebView strings, which are always stored uncompressed under - // assets/stored-locales/ inside the APK or App Bundle. - // - // b) For APKs, the Chrome UI strings are stored under assets/locales/ - // in compressed form. The relevant pak files is extracted on startup - // and stored on the /data partition, with a version-specific suffix. - // - // c) For App Bundles, Chrome UI strings are stored uncompressed under - // assets/locales#lang_<lang>/ (where <lang> is an Android language code) - // and assets/fallback-locales/ (for en-US.pak only). - // - // Which .pak files to load are determined here by two global variables with - // the following meaning: - // - // g_locale_paks_in_apk: - // If true, load the WebView strings from stored-locales/<locale>.pak file - // as the primary locale pak file. - // - // If false, try to load it from the app bundle specific location - // (e.g. locales#lang_<language>/<locale>.pak). If the latter does not - // exist, try to lookup the extracted APK-specific locale .pak file - // from /data/app/.../<locale>.pak@<version> instead. - // - // g_locale_paks_in_apk is set by SetLocalePaksStoredInApk() which - // is called from the WebView startup code. - // - // g_load_secondary_locale_paks: - // If true, load the Webview strings from stored-locales/<locale>.pak file - // as the secondary locale pak file. Otherwise don't load a secondary - // locale at all. - // - // This is set by SetLoadSecondaryLocalePaks() which is called - // during ChromeMainDelegate::PostEarlyInitialization() with a value - // that is true iff there are stored-locale/ .pak files. - // - // In other words, if both |g_locale_paks_in_apk| and - // |g_load_secondary_locale_paks| are true, the stored-locales file will be - // loaded twice as both the primary and secondary. However, this should - // never happen in practice. - // Load primary locale .pak file. if (g_locale_paks_in_apk) { - g_locale_pack_fd = - LoadLocalePakFromApk(app_locale, false, &g_locale_pack_region); + g_locale_pack_fd = LoadLocalePakFromApk(app_locale, &g_locale_pack_region); } else { - // Support overridden pak path for testing. base::FilePath locale_file_path = GetOverriddenPakPath(); - if (locale_file_path.empty()) { - // Try to find the uncompressed split-specific asset file. - g_locale_pack_fd = - LoadLocalePakFromApk(app_locale, true, &g_locale_pack_region); - } - if (g_locale_pack_fd < 0) { - // Otherwise, try to locate the extracted locale .pak file. - if (locale_file_path.empty()) - locale_file_path = GetLocaleFilePath(app_locale, true); + if (locale_file_path.empty()) + locale_file_path = GetLocaleFilePath(app_locale, true); - if (locale_file_path.empty()) { - // It's possible that there is no locale.pak. - LOG(WARNING) << "locale_file_path.empty() for locale " << app_locale; - LogLoadLocaleFailureReason(LoadFailureReason::kLocalePakNotFound); - return std::string(); - } - int flags = base::File::FLAG_OPEN | base::File::FLAG_READ; - g_locale_pack_fd = base::File(locale_file_path, flags).TakePlatformFile(); - g_locale_pack_region = base::MemoryMappedFile::Region::kWholeFile; + if (locale_file_path.empty()) { + // It's possible that there is no locale.pak. + LOG(WARNING) << "locale_file_path.empty() for locale " << app_locale; + LogLoadLocaleFailureReason(LoadFailureReason::kLocalePakNotFound); + return std::string(); } + int flags = base::File::FLAG_OPEN | base::File::FLAG_READ; + g_locale_pack_fd = base::File(locale_file_path, flags).TakePlatformFile(); + g_locale_pack_region = base::MemoryMappedFile::Region::kWholeFile; } locale_resources_data_ = LoadDataPackFromLocalePak( @@ -211,7 +156,7 @@ // would have a copy of all the resources in the secondary locale pak. if (g_load_secondary_locale_paks) { g_secondary_locale_pack_fd = LoadLocalePakFromApk( - app_locale, false, &g_secondary_locale_pack_region); + app_locale, &g_secondary_locale_pack_region); secondary_locale_resources_data_ = LoadDataPackFromLocalePak( g_secondary_locale_pack_fd, g_secondary_locale_pack_region); @@ -272,12 +217,11 @@ return g_secondary_locale_pack_fd; } -std::string GetPathForAndroidLocalePakWithinApk(const std::string& locale, - bool in_bundle) { +std::string GetPathForAndroidLocalePakWithinApk(const std::string& locale) { JNIEnv* env = base::android::AttachCurrentThread(); base::android::ScopedJavaLocalRef<jstring> ret = Java_ResourceBundle_getLocalePakResourcePath( - env, base::android::ConvertUTF8ToJavaString(env, locale), in_bundle); + env, base::android::ConvertUTF8ToJavaString(env, locale)); if (ret.obj() == nullptr) { return std::string(); }
diff --git a/ui/base/resource/resource_bundle_android.h b/ui/base/resource/resource_bundle_android.h index 48bea432..57059b0 100644 --- a/ui/base/resource/resource_bundle_android.h +++ b/ui/base/resource/resource_bundle_android.h
@@ -45,12 +45,8 @@ // Returns the path within the apk for the given locale's .pak file, or an // empty string if it doesn't exist. // Only locale paks for the active Android language can be retrieved. -// If |inSplit| is true, look into bundle split-specific location (e.g. -// 'assets/locales#lang_<lang>/<locale>.pak', otherwise use the default -// WebView-related location, i.e. 'assets/stored-locales/<locale>.pak'. UI_BASE_EXPORT std::string GetPathForAndroidLocalePakWithinApk( - const std::string& locale, - bool in_split = false); + const std::string& locale); // Get the density of the primary display. Use this instead of using Display // to avoid initializing Display in child processes.
diff --git a/ui/gfx/buffer_types.h b/ui/gfx/buffer_types.h index be72cf74..2b2fca4 100644 --- a/ui/gfx/buffer_types.h +++ b/ui/gfx/buffer_types.h
@@ -50,11 +50,8 @@ SCANOUT_CPU_READ_WRITE, SCANOUT_VDA_WRITE, GPU_READ_CPU_READ_WRITE, - // TODO(reveman): Merge this with GPU_READ_CPU_READ_WRITE when SurfaceTexture - // backed buffers are single buffered and support it. - GPU_READ_CPU_READ_WRITE_PERSISTENT, - LAST = GPU_READ_CPU_READ_WRITE_PERSISTENT + LAST = GPU_READ_CPU_READ_WRITE }; struct BufferUsageAndFormat {
diff --git a/ui/gfx/buffer_usage_util.cc b/ui/gfx/buffer_usage_util.cc index 78401d53..797dcde 100644 --- a/ui/gfx/buffer_usage_util.cc +++ b/ui/gfx/buffer_usage_util.cc
@@ -22,8 +22,6 @@ return "SCANOUT_VDA_WRITE"; case BufferUsage::GPU_READ_CPU_READ_WRITE: return "GPU_READ_CPU_READ_WRITE"; - case BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: - return "GPU_READ_CPU_READ_WRITE_PERSISTENT"; } return "Invalid Usage"; }
diff --git a/ui/gfx/linux/client_native_pixmap_dmabuf.cc b/ui/gfx/linux/client_native_pixmap_dmabuf.cc index 325ed4d..35ace80 100644 --- a/ui/gfx/linux/client_native_pixmap_dmabuf.cc +++ b/ui/gfx/linux/client_native_pixmap_dmabuf.cc
@@ -85,7 +85,6 @@ #if defined(CHROMECAST_BUILD) switch (usage) { case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: - case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: // TODO(spang): Fix b/121148905 and turn these back on. return false; default: @@ -126,7 +125,6 @@ return false; case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: - case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: return #if defined(ARCH_CPU_X86_FAMILY) // Currently only Intel driver (i.e. minigbm and
diff --git a/ui/gfx/linux/client_native_pixmap_factory_dmabuf.cc b/ui/gfx/linux/client_native_pixmap_factory_dmabuf.cc index 1d779eda..83eba31 100644 --- a/ui/gfx/linux/client_native_pixmap_factory_dmabuf.cc +++ b/ui/gfx/linux/client_native_pixmap_factory_dmabuf.cc
@@ -56,7 +56,6 @@ switch (usage) { case gfx::BufferUsage::SCANOUT_CPU_READ_WRITE: case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: - case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: case gfx::BufferUsage::SCANOUT_CAMERA_READ_WRITE: case gfx::BufferUsage::CAMERA_AND_CPU_READ_WRITE: return ClientNativePixmapDmaBuf::ImportFromDmabuf(std::move(handle),
diff --git a/ui/gfx/mojo/buffer_types.mojom b/ui/gfx/mojo/buffer_types.mojom index 3942de2..c13035d 100644 --- a/ui/gfx/mojo/buffer_types.mojom +++ b/ui/gfx/mojo/buffer_types.mojom
@@ -36,9 +36,8 @@ SCANOUT_CPU_READ_WRITE, SCANOUT_VDA_WRITE, GPU_READ_CPU_READ_WRITE, - GPU_READ_CPU_READ_WRITE_PERSISTENT, - LAST = GPU_READ_CPU_READ_WRITE_PERSISTENT + LAST = GPU_READ_CPU_READ_WRITE }; struct BufferUsageAndFormat {
diff --git a/ui/gfx/mojo/buffer_types_struct_traits.h b/ui/gfx/mojo/buffer_types_struct_traits.h index 01ab375..4f7e666 100644 --- a/ui/gfx/mojo/buffer_types_struct_traits.h +++ b/ui/gfx/mojo/buffer_types_struct_traits.h
@@ -124,8 +124,6 @@ return gfx::mojom::BufferUsage::SCANOUT_VDA_WRITE; case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: return gfx::mojom::BufferUsage::GPU_READ_CPU_READ_WRITE; - case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: - return gfx::mojom::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT; } NOTREACHED(); return gfx::mojom::BufferUsage::LAST; @@ -154,9 +152,6 @@ case gfx::mojom::BufferUsage::GPU_READ_CPU_READ_WRITE: *out = gfx::BufferUsage::GPU_READ_CPU_READ_WRITE; return true; - case gfx::mojom::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: - *out = gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT; - return true; } NOTREACHED(); return false;
diff --git a/ui/message_center/public/cpp/features.cc b/ui/message_center/public/cpp/features.cc index 079e49b..3b923d0 100644 --- a/ui/message_center/public/cpp/features.cc +++ b/ui/message_center/public/cpp/features.cc
@@ -6,13 +6,7 @@ namespace message_center { -const base::Feature kNewStyleNotifications { - "NewStyleNotifications", -#if defined(OS_CHROMEOS) - base::FEATURE_ENABLED_BY_DEFAULT -#else - base::FEATURE_DISABLED_BY_DEFAULT -#endif -}; +const base::Feature kNewStyleNotifications{"NewStyleNotifications", + base::FEATURE_ENABLED_BY_DEFAULT}; } // namespace message_center
diff --git a/ui/message_center/views/notification_view_md.cc b/ui/message_center/views/notification_view_md.cc index 4d7f0ba..6f09667 100644 --- a/ui/message_center/views/notification_view_md.cc +++ b/ui/message_center/views/notification_view_md.cc
@@ -1221,7 +1221,7 @@ } void NotificationViewMD::ToggleInlineSettings(const ui::Event& event) { - if (!settings_row_) + if (!weak_ptr_factory_.GetWeakPtr() || !settings_row_) return; bool inline_settings_visible = !settings_row_->visible(); @@ -1239,6 +1239,11 @@ SetSettingMode(inline_settings_visible); SetExpanded(!inline_settings_visible); + // Check |this| is valid before continuing, because SetExpanded() might + // cause |this| to be deleted. + if (!weak_ptr_factory_.GetWeakPtr()) + return; + PreferredSizeChanged(); if (inline_settings_visible)
diff --git a/ui/ozone/platform/drm/gpu/drm_thread.cc b/ui/ozone/platform/drm/gpu/drm_thread.cc index 48153537..8f8cda3 100644 --- a/ui/ozone/platform/drm/gpu/drm_thread.cc +++ b/ui/ozone/platform/drm/gpu/drm_thread.cc
@@ -56,7 +56,6 @@ return GBM_BO_USE_SCANOUT | GBM_BO_USE_TEXTURING | GBM_BO_USE_HW_VIDEO_DECODER; case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: - case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: return GBM_BO_USE_LINEAR | GBM_BO_USE_TEXTURING; } }
diff --git a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc index 0f3583d..960afcd 100644 --- a/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc +++ b/ui/ozone/platform/wayland/gpu/gbm_pixmap_wayland.cc
@@ -66,7 +66,6 @@ flags = GBM_BO_USE_SCANOUT; break; case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE: - case gfx::BufferUsage::GPU_READ_CPU_READ_WRITE_PERSISTENT: flags = GBM_BO_USE_LINEAR; break; default:
diff --git a/ui/shell_dialogs/BUILD.gn b/ui/shell_dialogs/BUILD.gn index 486d158..935723a2 100644 --- a/ui/shell_dialogs/BUILD.gn +++ b/ui/shell_dialogs/BUILD.gn
@@ -101,9 +101,4 @@ "//ui/resources:ui_test_pak_data", "//ui/strings", ] - - # TODO: Remove once http://crbug.com/951419 is fixed. - if (is_android) { - deps += [ "//ui/android:ui_java" ] - } }
diff --git a/ui/strings/ui_strings.grd b/ui/strings/ui_strings.grd index ca7f8e9..910e125 100644 --- a/ui/strings/ui_strings.grd +++ b/ui/strings/ui_strings.grd
@@ -949,7 +949,7 @@ <!-- Send Tab To Self --> <message name="IDS_SEND_TAB_TO_SELF_INFOBAR_MESSAGE" desc="The message text for the infobar when a user receives a shared tab from another device."> - Received a tab + Tab received. </message> <message name="IDS_SEND_TAB_TO_SELF_INFOBAR_MESSAGE_URL" desc="Clickable text displayed as part of a URL in the inforbar displayed when a user receives a shared tab from another device."> Open