diff --git a/BUILD.gn b/BUILD.gn index 39aace08..7f12f0a 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -690,8 +690,8 @@ } } - if ((is_linux && !is_chromeos && !is_chromecast) || (is_win && use_drfuzz) || - (use_libfuzzer && is_mac)) { + if ((is_linux && !is_chromeos && !is_chromecast) || + (is_win && (use_drfuzz || use_libfuzzer)) || (use_libfuzzer && is_mac)) { deps += [ "//testing/libfuzzer/fuzzers", "//testing/libfuzzer/tests:libfuzzer_tests",
diff --git a/DEPS b/DEPS index 3ccafb47..ac340a7 100644 --- a/DEPS +++ b/DEPS
@@ -105,11 +105,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '5767fc042834283154dbbf1724fed3fcff41bd5e', + 'skia_revision': '5ea41fc89b264f2cab7058bf48429f87761f65e9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '2012676a17faccdb4468dc490a52b5293a08af80', + 'v8_revision': 'd4c562dc691178f3bf0b278beff8696feadea48c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -117,7 +117,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'af8b73c9e6320524ac7bc0aa43dc8d1b47257bc1', + 'angle_revision': '115e8a2625f5d81bb4e6fa4b687c0c5e5b56ca73', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -177,7 +177,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. - 'libprotobuf-mutator': '3fc43a01d721ef1bacfefed170bc22abf1b8b051', + 'libprotobuf-mutator': 'c148984c5af61e628252ebdc5f141fe89d83106c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -213,7 +213,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. - 'spv_tools_revision': 'bfcdc913c4184430e4fca6923683c62723bf5956', + 'spv_tools_revision': '80564a56ec85b0aa083111a3e153d84a680bec02', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -595,7 +595,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '74419b36e4b268effeb7feadd51359bedf9a2058', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '10f3ee914d209c26f4f0e38c96b44853eb13ebd1', 'condition': 'checkout_linux', }, @@ -620,7 +620,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'c4a7356a469b3b6267965d7bcc318cf35cdd3b62', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'f221bac5302a86731c3a9b81a795587a7a429a48', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -954,7 +954,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '620aaef23380249735cea1d0a5d6342ae8403feb', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '59d6ace5cb9969923533796844612d65b6db2cce', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1106,7 +1106,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '6d2f3f4cb8bac1f7c4a945c73d07a33df74f22f9', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '1c718f91de164290a2504ab6e9ba7a36aec0882e', + Var('webrtc_git') + '/src.git' + '@' + 'd50fdd75341647b6d662a76a3af60e21ac742e03', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1137,7 +1137,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@1b71de973c63fbbb4efe06cb2699efcace76b018', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@3a31ac84a0bbd96d538d662219127741d4728053', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/browser/aw_pdf_exporter.cc b/android_webview/browser/aw_pdf_exporter.cc index ee2cea5..da885b36 100644 --- a/android_webview/browser/aw_pdf_exporter.cc +++ b/android_webview/browser/aw_pdf_exporter.cc
@@ -68,7 +68,7 @@ base::Bind(&AwPdfExporter::DidExportPdf, base::Unretained(this))); if (!print_manager->PrintNow()) - DidExportPdf(fd, 0); + DidExportPdf(0); } namespace { @@ -113,7 +113,7 @@ settings.set_should_print_backgrounds(true); } -void AwPdfExporter::DidExportPdf(int fd, int page_count) { +void AwPdfExporter::DidExportPdf(int page_count) { JNIEnv* env = base::android::AttachCurrentThread(); ScopedJavaLocalRef<jobject> obj = java_ref_.get(env); if (obj.is_null())
diff --git a/android_webview/browser/aw_pdf_exporter.h b/android_webview/browser/aw_pdf_exporter.h index 598881a..8c1be91 100644 --- a/android_webview/browser/aw_pdf_exporter.h +++ b/android_webview/browser/aw_pdf_exporter.h
@@ -40,7 +40,7 @@ const base::android::JavaRef<jobject>& obj, const printing::PageRanges& page_ranges, printing::PrintSettings& settings); - void DidExportPdf(int fd, int page_count); + void DidExportPdf(int page_count); JavaObjectWeakGlobalRef java_ref_; content::WebContents* web_contents_;
diff --git a/android_webview/browser/aw_variations_service_client.cc b/android_webview/browser/aw_variations_service_client.cc index 7781ad84..e096879 100644 --- a/android_webview/browser/aw_variations_service_client.cc +++ b/android_webview/browser/aw_variations_service_client.cc
@@ -54,10 +54,6 @@ return android_webview::GetChannelOrStable(); } -bool AwVariationsServiceClient::GetSupportsPermanentConsistency() { - return false; -} - bool AwVariationsServiceClient::OverridesRestrictParameter( std::string* parameter) { return false;
diff --git a/android_webview/browser/aw_variations_service_client.h b/android_webview/browser/aw_variations_service_client.h index 0caf0fd..afcac6b 100644 --- a/android_webview/browser/aw_variations_service_client.h +++ b/android_webview/browser/aw_variations_service_client.h
@@ -31,7 +31,6 @@ scoped_refptr<network::SharedURLLoaderFactory> GetURLLoaderFactory() override; network_time::NetworkTimeTracker* GetNetworkTimeTracker() override; version_info::Channel GetChannel() override; - bool GetSupportsPermanentConsistency() override; bool OverridesRestrictParameter(std::string* parameter) override; DISALLOW_COPY_AND_ASSIGN(AwVariationsServiceClient);
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 243a270..ff8698f 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -391,6 +391,7 @@ "keyboard/virtual_keyboard_container_layout_manager.h", "keyboard/virtual_keyboard_controller.cc", "keyboard/virtual_keyboard_controller.h", + "keyboard/virtual_keyboard_controller_observer.h", "laser/laser_pointer_controller.cc", "laser/laser_pointer_controller.h", "laser/laser_pointer_view.cc", @@ -503,8 +504,12 @@ "message_center/message_center_view.h", "message_center/message_list_view.cc", "message_center/message_list_view.h", + "message_center/notification_swipe_control_view.cc", + "message_center/notification_swipe_control_view.h", "message_center/notifier_settings_view.cc", "message_center/notifier_settings_view.h", + "message_center/slidable_message_view.cc", + "message_center/slidable_message_view.h", "metrics/demo_session_metrics_recorder.cc", "metrics/demo_session_metrics_recorder.h", "metrics/desktop_task_switch_metric_recorder.cc",
diff --git a/ash/assistant/ui/assistant_web_view.cc b/ash/assistant/ui/assistant_web_view.cc index d571554..82af33ca 100644 --- a/ash/assistant/ui/assistant_web_view.cc +++ b/ash/assistant/ui/assistant_web_view.cc
@@ -5,8 +5,6 @@ #include "ash/assistant/ui/assistant_web_view.h" #include <algorithm> -#include <map> -#include <string> #include <utility> #include "ash/assistant/assistant_controller.h" @@ -21,12 +19,48 @@ #include "ui/compositor/layer.h" #include "ui/display/display.h" #include "ui/display/screen.h" +#include "ui/gfx/canvas.h" #include "ui/views/layout/box_layout.h" #include "ui/views/painter.h" #include "ui/views/widget/widget.h" namespace ash { +namespace { + +// ContentViewMaskPainter ------------------------------------------------- + +class ContentViewMaskPainter : public views::Painter { + public: + ContentViewMaskPainter() = default; + ~ContentViewMaskPainter() override = default; + + // views::Painter: + gfx::Size GetMinimumSize() const override { return gfx::Size(); } + + void Paint(gfx::Canvas* canvas, const gfx::Size& size) override { + cc::PaintFlags flags; + flags.setAntiAlias(true); + flags.setColor(SK_ColorBLACK); + + SkRRect rect; + rect.setRectRadii( + SkRect::MakeWH(size.width(), size.height()), + (const SkVector[]){ + /*upper_left=*/SkVector::Make(0, 0), + /*upper_right=*/SkVector::Make(0, 0), + /*lower_right=*/SkVector::Make(kCornerRadiusDip, kCornerRadiusDip), + /*lower_left=*/SkVector::Make(kCornerRadiusDip, kCornerRadiusDip)}); + + canvas->sk_canvas()->drawRRect(rect, flags); + } + + private: + DISALLOW_COPY_AND_ASSIGN(ContentViewMaskPainter); +}; + +} // namespace + // AssistantWebView ------------------------------------------------------------ AssistantWebView::AssistantWebView(AssistantController* assistant_controller) @@ -93,8 +127,7 @@ // Content mask. // This is used to enforce corner radius on the contents' layer. content_view_mask_ = views::Painter::CreatePaintedLayer( - views::Painter::CreateSolidRoundRectPainter(SK_ColorBLACK, - kCornerRadiusDip)); + std::make_unique<ContentViewMaskPainter>()); content_view_mask_->layer()->SetFillsBoundsOpaquely(false); }
diff --git a/ash/keyboard/virtual_keyboard_controller.cc b/ash/keyboard/virtual_keyboard_controller.cc index a57a0b7..a56fc332 100644 --- a/ash/keyboard/virtual_keyboard_controller.cc +++ b/ash/keyboard/virtual_keyboard_controller.cc
@@ -257,6 +257,8 @@ } else { Shell::Get()->DisableKeyboard(); } + for (VirtualKeyboardControllerObserver& observer : observers_) + observer.OnVirtualKeyboardStateChanged(is_enabled); } void VirtualKeyboardController::ForceShowKeyboard() { @@ -300,6 +302,16 @@ Shell::Get()->EnableKeyboard(); } +void VirtualKeyboardController::AddObserver( + VirtualKeyboardControllerObserver* observer) { + observers_.AddObserver(observer); +} + +void VirtualKeyboardController::RemoveObserver( + VirtualKeyboardControllerObserver* observer) { + observers_.RemoveObserver(observer); +} + void VirtualKeyboardController::UpdateBluetoothDevice( device::BluetoothDevice* device) { // We only care about keyboard type bluetooth device change.
diff --git a/ash/keyboard/virtual_keyboard_controller.h b/ash/keyboard/virtual_keyboard_controller.h index 49bb8e5..ec7552b 100644 --- a/ash/keyboard/virtual_keyboard_controller.h +++ b/ash/keyboard/virtual_keyboard_controller.h
@@ -9,9 +9,11 @@ #include "ash/ash_export.h" #include "ash/bluetooth_devices_observer.h" +#include "ash/keyboard/virtual_keyboard_controller_observer.h" #include "ash/session/session_observer.h" #include "ash/wm/tablet_mode/tablet_mode_observer.h" #include "base/macros.h" +#include "base/observer_list.h" #include "ui/base/ime/chromeos/public/interfaces/ime_keyset.mojom.h" #include "ui/events/devices/input_device_event_observer.h" #include "ui/keyboard/keyboard_controller_observer.h" @@ -60,6 +62,10 @@ // SessionObserver: void OnActiveUserSessionChanged(const AccountId& account_id) override; + // Management of the observer list. + void AddObserver(VirtualKeyboardControllerObserver* observer); + void RemoveObserver(VirtualKeyboardControllerObserver* observer); + private: // Updates the list of active input devices. void UpdateDevices(); @@ -89,6 +95,8 @@ // Observer to observe the bluetooth devices. std::unique_ptr<BluetoothDevicesObserver> bluetooth_devices_observer_; + base::ObserverList<VirtualKeyboardControllerObserver> observers_; + DISALLOW_COPY_AND_ASSIGN(VirtualKeyboardController); };
diff --git a/ash/keyboard/virtual_keyboard_controller_observer.h b/ash/keyboard/virtual_keyboard_controller_observer.h new file mode 100644 index 0000000..5a69f06 --- /dev/null +++ b/ash/keyboard/virtual_keyboard_controller_observer.h
@@ -0,0 +1,22 @@ +// 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 ASH_KEYBOARD_VIRTUAL_KEYBOARD_CONTROLLER_OBSERVER_H_ +#define ASH_KEYBOARD_VIRTUAL_KEYBOARD_CONTROLLER_OBSERVER_H_ + +#include "base/observer_list.h" + +namespace ash { + +class VirtualKeyboardControllerObserver : public base::CheckedObserver { + public: + virtual void OnVirtualKeyboardStateChanged(bool enabled) = 0; + + protected: + ~VirtualKeyboardControllerObserver() override = default; +}; + +} // namespace ash + +#endif // ASH_KEYBOARD_VIRTUAL_KEYBOARD_CONTROLLER_OBSERVER_H_
diff --git a/ash/lock_screen_action/lock_screen_note_display_state_handler_unittest.cc b/ash/lock_screen_action/lock_screen_note_display_state_handler_unittest.cc index 14203718..3ed89ef 100644 --- a/ash/lock_screen_action/lock_screen_note_display_state_handler_unittest.cc +++ b/ash/lock_screen_action/lock_screen_note_display_state_handler_unittest.cc
@@ -91,8 +91,11 @@ auto power_manager_client = std::make_unique<chromeos::FakePowerManagerClient>(); power_manager_client_ = power_manager_client.get(); - power_manager_client_->SetScreenBrightnessPercent(kVisibleBrightnessPercent, - false /*gradual*/); + + power_manager::SetBacklightBrightnessRequest request; + request.set_percent(kVisibleBrightnessPercent); + power_manager_client_->SetScreenBrightness(request); + power_manager_observer_ = std::make_unique<TestPowerManagerObserver>(power_manager_client_); chromeos::DBusThreadManager::GetSetterForTesting()->SetPowerManagerClient(
diff --git a/ash/login/ui/lock_contents_view.cc b/ash/login/ui/lock_contents_view.cc index 8f54738..ce0e7390 100644 --- a/ash/login/ui/lock_contents_view.cc +++ b/ash/login/ui/lock_contents_view.cc
@@ -1294,7 +1294,9 @@ if (state->enable_tap_auth) to_update_auth |= LoginAuthUserView::AUTH_TAP; if (state->fingerprint_state != - mojom::FingerprintUnlockState::UNAVAILABLE) { + mojom::FingerprintUnlockState::UNAVAILABLE && + state->fingerprint_state != + mojom::FingerprintUnlockState::AUTH_DISABLED_FROM_TIMEOUT) { to_update_auth |= LoginAuthUserView::AUTH_FINGERPRINT; }
diff --git a/ash/login/ui/lock_debug_view.cc b/ash/login/ui/lock_debug_view.cc index 4e71fcf..ad280e7 100644 --- a/ash/login/ui/lock_debug_view.cc +++ b/ash/login/ui/lock_debug_view.cc
@@ -335,6 +335,8 @@ case mojom::FingerprintUnlockState::AUTH_FAILED: return mojom::FingerprintUnlockState::AUTH_DISABLED; case mojom::FingerprintUnlockState::AUTH_DISABLED: + return mojom::FingerprintUnlockState::AUTH_DISABLED_FROM_TIMEOUT; + case mojom::FingerprintUnlockState::AUTH_DISABLED_FROM_TIMEOUT: return mojom::FingerprintUnlockState::UNAVAILABLE; } };
diff --git a/ash/login/ui/login_auth_user_view.cc b/ash/login/ui/login_auth_user_view.cc index b2461cf..261f9a5 100644 --- a/ash/login/ui/login_auth_user_view.cc +++ b/ash/login/ui/login_auth_user_view.cc
@@ -96,8 +96,8 @@ constexpr int kNonEmptyWidthDp = 1; // Returns an observer that will hide |view| when it fires. The observer will -// delete itself after firing. Make sure to call |observer->SetReady()| after -// attaching it. +// delete itself after firing (by returning true). Make sure to call +// |observer->SetActive()| after attaching it. ui::CallbackLayerAnimationObserver* BuildObserverToHideView(views::View* view) { return new ui::CallbackLayerAnimationObserver(base::Bind( [](views::View* view, @@ -187,6 +187,7 @@ case mojom::FingerprintUnlockState::UNAVAILABLE: case mojom::FingerprintUnlockState::AVAILABLE: case mojom::FingerprintUnlockState::AUTH_SUCCESS: + case mojom::FingerprintUnlockState::AUTH_DISABLED_FROM_TIMEOUT: icon_->SetImage(gfx::CreateVectorIcon( kLockScreenFingerprintIcon, kFingerprintIconSizeDp, SK_ColorWHITE)); return; @@ -210,6 +211,7 @@ case mojom::FingerprintUnlockState::UNAVAILABLE: case mojom::FingerprintUnlockState::AVAILABLE: case mojom::FingerprintUnlockState::AUTH_SUCCESS: + case mojom::FingerprintUnlockState::AUTH_DISABLED_FROM_TIMEOUT: return IDS_ASH_LOGIN_FINGERPRINT_UNLOCK_MESSAGE; case mojom::FingerprintUnlockState::AUTH_FAILED: return IDS_ASH_LOGIN_FINGERPRINT_UNLOCK_FAILED_MESSAGE; @@ -226,7 +228,9 @@ return; state_ = state; - SetVisible(state != mojom::FingerprintUnlockState::UNAVAILABLE); + SetVisible(state != mojom::FingerprintUnlockState::UNAVAILABLE && + state != + mojom::FingerprintUnlockState::AUTH_DISABLED_FROM_TIMEOUT); SetIcon(state); SetText(state); @@ -590,6 +594,17 @@ } void LoginAuthUserView::CaptureStateForAnimationPreLayout() { + auto stop_animation = [](views::View* view) { + if (view->layer()->GetAnimator()->is_animating()) + view->layer()->GetAnimator()->StopAnimating(); + }; + + // Stop any running animation scheduled in ApplyAnimationPostLayout. + stop_animation(this); + stop_animation(password_view_); + stop_animation(pin_view_); + stop_animation(fingerprint_view_); + DCHECK(!cached_animation_state_); cached_animation_state_ = std::make_unique<AnimationState>(this); } @@ -597,11 +612,6 @@ void LoginAuthUserView::ApplyAnimationPostLayout() { DCHECK(cached_animation_state_); - // Cancel any running animations. - pin_view_->layer()->GetAnimator()->AbortAllAnimations(); - password_view_->layer()->GetAnimator()->AbortAllAnimations(); - layer()->GetAnimator()->AbortAllAnimations(); - bool has_password = (auth_methods() & AUTH_PASSWORD) != 0; bool has_pin = (auth_methods() & AUTH_PIN) != 0; bool has_fingerprint = (auth_methods() & AUTH_FINGERPRINT) != 0; @@ -700,7 +710,7 @@ { ui::ScopedLayerAnimationSettings settings( - password_view_->layer()->GetAnimator()); + fingerprint_view_->layer()->GetAnimator()); settings.SetTransitionDuration(base::TimeDelta::FromMilliseconds( login_constants::kChangeUserAnimationDurationMs)); settings.SetTweenType(gfx::Tween::Type::FAST_OUT_SLOW_IN);
diff --git a/ash/message_center/message_list_view.cc b/ash/message_center/message_list_view.cc index 87eb19f..be732c99 100644 --- a/ash/message_center/message_list_view.cc +++ b/ash/message_center/message_list_view.cc
@@ -6,6 +6,7 @@ #include "ash/message_center/message_center_style.h" #include "ash/message_center/message_center_view.h" +#include "ash/message_center/slidable_message_view.h" #include "base/command_line.h" #include "base/location.h" #include "base/single_thread_task_runner.h" @@ -16,7 +17,6 @@ #include "ui/message_center/public/cpp/message_center_constants.h" #include "ui/message_center/public/cpp/notification.h" #include "ui/message_center/views/message_view.h" -#include "ui/message_center/views/slidable_message_view.h" #include "ui/views/background.h" #include "ui/views/border.h" #include "ui/views/layout/box_layout.h"
diff --git a/ash/message_center/message_list_view.h b/ash/message_center/message_list_view.h index 5ec8763d..99c2914 100644 --- a/ash/message_center/message_list_view.h +++ b/ash/message_center/message_list_view.h
@@ -10,11 +10,11 @@ #include <vector> #include "ash/ash_export.h" +#include "ash/message_center/slidable_message_view.h" #include "base/macros.h" #include "ui/compositor/paint_context.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" -#include "ui/message_center/views/slidable_message_view.h" #include "ui/views/animation/bounds_animator.h" #include "ui/views/animation/bounds_animator_observer.h" #include "ui/views/controls/scroll_view.h"
diff --git a/ash/message_center/message_list_view_unittest.cc b/ash/message_center/message_list_view_unittest.cc index b580a45..91803ff 100644 --- a/ash/message_center/message_list_view_unittest.cc +++ b/ash/message_center/message_list_view_unittest.cc
@@ -7,6 +7,7 @@ #include <utility> #include "ash/message_center/message_list_view.h" +#include "ash/message_center/slidable_message_view.h" #include "ash/test/ash_test_base.h" #include "base/macros.h" #include "base/run_loop.h" @@ -17,7 +18,6 @@ #include "ui/message_center/notification_list.h" #include "ui/message_center/public/cpp/notification.h" #include "ui/message_center/views/notification_view_md.h" -#include "ui/message_center/views/slidable_message_view.h" #include "ui/views/test/views_test_base.h" using ::testing::ElementsAre;
diff --git a/ui/message_center/views/notification_swipe_control_view.cc b/ash/message_center/notification_swipe_control_view.cc similarity index 72% rename from ui/message_center/views/notification_swipe_control_view.cc rename to ash/message_center/notification_swipe_control_view.cc index 4cba6ed..228cf928 100644 --- a/ui/message_center/views/notification_swipe_control_view.cc +++ b/ash/message_center/notification_swipe_control_view.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/message_center/views/notification_swipe_control_view.h" +#include "ash/message_center/notification_swipe_control_view.h" #include "ui/base/l10n/l10n_util.h" #include "ui/events/event.h" @@ -14,21 +14,20 @@ #include "ui/views/background.h" #include "ui/views/layout/box_layout.h" -namespace message_center { +namespace ash { const char NotificationSwipeControlView::kViewClassName[] = "NotificationSwipeControlView"; NotificationSwipeControlView::NotificationSwipeControlView() { - auto layout = std::make_unique<views::BoxLayout>( + auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::kHorizontal, - gfx::Insets(kSwipeControlButtonVerticalMargin, - kSwipeControlButtonHorizontalMargin), - kSwipeControlButtonHorizontalMargin); + gfx::Insets(message_center::kSwipeControlButtonVerticalMargin, + message_center::kSwipeControlButtonHorizontalMargin), + message_center::kSwipeControlButtonHorizontalMargin)); layout->set_cross_axis_alignment( views::BoxLayout::CROSS_AXIS_ALIGNMENT_START); layout->set_main_axis_alignment(views::BoxLayout::MAIN_AXIS_ALIGNMENT_END); - SetLayoutManager(std::move(layout)); // Draw on its own layer to round corners SetPaintToLayer(); @@ -60,17 +59,17 @@ void NotificationSwipeControlView::ShowSettingsButton(bool show) { if (show && !settings_button_) { - settings_button_ = std::make_unique<views::ImageButton>(this); - settings_button_->set_owned_by_client(); + settings_button_ = new views::ImageButton(this); settings_button_->SetImage( views::Button::STATE_NORMAL, - gfx::CreateVectorIcon(kNotificationSettingsButtonIcon, - kSwipeControlButtonImageSize, + gfx::CreateVectorIcon(message_center::kNotificationSettingsButtonIcon, + message_center::kSwipeControlButtonImageSize, gfx::kChromeIconGrey)); settings_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER, views::ImageButton::ALIGN_MIDDLE); settings_button_->SetPreferredSize( - gfx::Size(kSwipeControlButtonSize, kSwipeControlButtonSize)); + gfx::Size(message_center::kSwipeControlButtonSize, + message_center::kSwipeControlButtonSize)); settings_button_->SetAccessibleName(l10n_util::GetStringUTF16( IDS_MESSAGE_NOTIFICATION_SETTINGS_BUTTON_ACCESSIBLE_NAME)); @@ -79,28 +78,28 @@ settings_button_->SetBackground( views::CreateSolidBackground(SK_ColorTRANSPARENT)); - int position = snooze_button_ ? 1 : 0; - AddChildViewAt(settings_button_.get(), position); + AddChildViewAt(settings_button_, child_count()); Layout(); } else if (!show && settings_button_) { - DCHECK(Contains(settings_button_.get())); - settings_button_.reset(); + DCHECK(Contains(settings_button_)); + delete settings_button_; + settings_button_ = nullptr; } } void NotificationSwipeControlView::ShowSnoozeButton(bool show) { if (show && !snooze_button_) { - snooze_button_ = std::make_unique<views::ImageButton>(this); - snooze_button_->set_owned_by_client(); + snooze_button_ = new views::ImageButton(this); snooze_button_->SetImage( views::Button::STATE_NORMAL, - gfx::CreateVectorIcon(kNotificationSnoozeButtonIcon, - kSwipeControlButtonImageSize, + gfx::CreateVectorIcon(message_center::kNotificationSnoozeButtonIcon, + message_center::kSwipeControlButtonImageSize, gfx::kChromeIconGrey)); snooze_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER, views::ImageButton::ALIGN_MIDDLE); snooze_button_->SetPreferredSize( - gfx::Size(kSwipeControlButtonSize, kSwipeControlButtonSize)); + gfx::Size(message_center::kSwipeControlButtonSize, + message_center::kSwipeControlButtonSize)); snooze_button_->SetAccessibleName(l10n_util::GetStringUTF16( IDS_MESSAGE_NOTIFICATION_SETTINGS_BUTTON_ACCESSIBLE_NAME)); @@ -109,11 +108,12 @@ snooze_button_->SetBackground( views::CreateSolidBackground(SK_ColorTRANSPARENT)); - AddChildViewAt(snooze_button_.get(), 0); + AddChildViewAt(snooze_button_, 0); Layout(); } else if (!show && snooze_button_) { - DCHECK(Contains(snooze_button_.get())); - snooze_button_.reset(); + DCHECK(Contains(snooze_button_)); + delete snooze_button_; + snooze_button_ = nullptr; } } @@ -123,14 +123,13 @@ void NotificationSwipeControlView::ButtonPressed(views::Button* sender, const ui::Event& event) { - if (settings_button_ && sender == settings_button_.get()) { - for (Observer& observer : button_observers_) { + DCHECK(sender); + if (sender == settings_button_) { + for (Observer& observer : button_observers_) observer.OnSettingsButtonPressed(event); - } - } else if (snooze_button_ && sender == snooze_button_.get()) { - for (Observer& observer : button_observers_) { + } else if (sender == snooze_button_) { + for (Observer& observer : button_observers_) observer.OnSnoozeButtonPressed(event); - } } } @@ -140,4 +139,4 @@ button_observers_.AddObserver(observer); } -} // namespace message_center +} // namespace ash
diff --git a/ui/message_center/views/notification_swipe_control_view.h b/ash/message_center/notification_swipe_control_view.h similarity index 79% rename from ui/message_center/views/notification_swipe_control_view.h rename to ash/message_center/notification_swipe_control_view.h index e97e10d..d938f49e 100644 --- a/ui/message_center/views/notification_swipe_control_view.h +++ b/ash/message_center/notification_swipe_control_view.h
@@ -2,25 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef UI_MESSAGE_CENTER_VIEWS_NOTIFICATION_SWIPE_CONTROL_VIEW_H_ -#define UI_MESSAGE_CENTER_VIEWS_NOTIFICATION_SWIPE_CONTROL_VIEW_H_ +#ifndef ASH_MESSAGE_CENTER_NOTIFICATION_SWIPE_CONTROL_VIEW_H_ +#define ASH_MESSAGE_CENTER_NOTIFICATION_SWIPE_CONTROL_VIEW_H_ +#include "ash/ash_export.h" #include "base/macros.h" #include "base/observer_list.h" #include "base/observer_list_types.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/animation/animation_delegate.h" -#include "ui/message_center/message_center_export.h" #include "ui/views/controls/button/button.h" #include "ui/views/controls/button/image_button.h" #include "ui/views/view.h" -namespace message_center { +namespace ash { // View containing 2 buttons that appears behind notification by swiping. -class MESSAGE_CENTER_EXPORT NotificationSwipeControlView - : public views::View, - public views::ButtonListener { +class ASH_EXPORT NotificationSwipeControlView : public views::View, + public views::ButtonListener { public: class Observer : public base::CheckedObserver { public: @@ -59,8 +58,10 @@ // Change the visibility of the snooze button. True to show, false to hide. void ShowSnoozeButton(bool show); - std::unique_ptr<views::ImageButton> settings_button_; - std::unique_ptr<views::ImageButton> snooze_button_; + // Owned by views hierarchy. + views::ImageButton* settings_button_ = nullptr; + views::ImageButton* snooze_button_ = nullptr; + base::ObserverList<Observer, false /* check_empty */, false /* allow_reentrancy */> @@ -69,6 +70,6 @@ DISALLOW_COPY_AND_ASSIGN(NotificationSwipeControlView); }; -} // namespace message_center +} // namespace ash -#endif // UI_MESSAGE_CENTER_VIEWS_NOTIFICATION_SWIPE_CONTROL_VIEW_H_ +#endif // ASH_MESSAGE_CENTER_NOTIFICATION_SWIPE_CONTROL_VIEW_H_
diff --git a/ui/message_center/views/slidable_message_view.cc b/ash/message_center/slidable_message_view.cc similarity index 79% rename from ui/message_center/views/slidable_message_view.cc rename to ash/message_center/slidable_message_view.cc index 89ae2c1..022f913 100644 --- a/ui/message_center/views/slidable_message_view.cc +++ b/ash/message_center/slidable_message_view.cc
@@ -2,33 +2,35 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "ui/message_center/views/slidable_message_view.h" +#include "ash/message_center/slidable_message_view.h" +#include "ash/message_center/notification_swipe_control_view.h" #include "ui/message_center/public/cpp/features.h" #include "ui/message_center/public/cpp/message_center_constants.h" #include "ui/message_center/views/message_view.h" #include "ui/message_center/views/notification_background_painter.h" #include "ui/message_center/views/notification_control_buttons_view.h" -#include "ui/message_center/views/notification_swipe_control_view.h" #include "ui/views/background.h" #include "ui/views/layout/fill_layout.h" #include "ui/views/view.h" -namespace message_center { +namespace ash { -SlidableMessageView::SlidableMessageView(MessageView* message_view) - : message_view_(message_view) { +SlidableMessageView::SlidableMessageView( + message_center::MessageView* message_view) + : message_view_(message_view), + control_view_(new NotificationSwipeControlView()) { SetFocusBehavior(views::View::FocusBehavior::NEVER); // Draw on its own layer to allow bound animation. SetPaintToLayer(); layer()->SetFillsBoundsOpaquely(false); - SetBackground(views::CreateSolidBackground(kSwipeControlBackgroundColor)); + SetBackground(views::CreateSolidBackground( + message_center::kSwipeControlBackgroundColor)); SetLayoutManager(std::make_unique<views::FillLayout>()); - control_view_ = std::make_unique<NotificationSwipeControlView>(); - AddChildView(control_view_.get()); + AddChildView(control_view_); control_view_->AddObserver(this); message_view_->AddSlideObserver(this); @@ -45,7 +47,7 @@ NotificationSwipeControlView::ButtonPosition button_position = gesture_amount < 0 ? NotificationSwipeControlView::ButtonPosition::RIGHT : NotificationSwipeControlView::ButtonPosition::LEFT; - NotificationControlButtonsView* buttons = + message_center::NotificationControlButtonsView* buttons = message_view_->GetControlButtonsView(); bool has_settings_button = buttons->settings_button(); bool has_snooze_button = buttons->snooze_button(); @@ -80,7 +82,7 @@ } void SlidableMessageView::UpdateWithNotification( - const Notification& notification) { + const message_center::Notification& notification) { message_view_->UpdateWithNotification(notification); } @@ -95,14 +97,15 @@ void SlidableMessageView::UpdateCornerRadius(int top_radius, int bottom_radius) { SetBackground(views::CreateBackgroundFromPainter( - std::make_unique<NotificationBackgroundPainter>( - top_radius, bottom_radius, kSwipeControlBackgroundColor))); + std::make_unique<message_center::NotificationBackgroundPainter>( + top_radius, bottom_radius, + message_center::kSwipeControlBackgroundColor))); SchedulePaint(); } // static SlidableMessageView* SlidableMessageView::GetFromMessageView( - MessageView* message_view) { + message_center::MessageView* message_view) { DCHECK(message_view); DCHECK(message_view->parent()); DCHECK_EQ(std::string(SlidableMessageView::kViewClassName), @@ -110,4 +113,4 @@ return static_cast<SlidableMessageView*>(message_view->parent()); } -} // namespace message_center +} // namespace ash
diff --git a/ash/message_center/slidable_message_view.h b/ash/message_center/slidable_message_view.h new file mode 100644 index 0000000..81a8d7e --- /dev/null +++ b/ash/message_center/slidable_message_view.h
@@ -0,0 +1,71 @@ +// Copyright (c) 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 ASH_MESSAGE_CENTER_SLIDABLE_MESSAGE_VIEW_H_ +#define ASH_MESSAGE_CENTER_SLIDABLE_MESSAGE_VIEW_H_ + +#include "ash/ash_export.h" +#include "ash/message_center/notification_swipe_control_view.h" +#include "ui/message_center/views/message_view.h" +#include "ui/views/view.h" + +namespace ash { + +class ASH_EXPORT SlidableMessageView + : public views::View, + public message_center::MessageView::SlideObserver, + public NotificationSwipeControlView::Observer { + public: + explicit SlidableMessageView(message_center::MessageView* message_view); + ~SlidableMessageView() override; + + message_center::MessageView* GetMessageView() const { return message_view_; } + static SlidableMessageView* GetFromMessageView( + message_center::MessageView* message_view); + + // MessageView::SlideObserver + void OnSlideChanged(const std::string& notification_id) override; + + // NotificationSwipeControlView::Observer + void OnSettingsButtonPressed(const ui::Event& event) override; + void OnSnoozeButtonPressed(const ui::Event& event) override; + + void SetExpanded(bool expanded) { + return message_view_->SetExpanded(expanded); + } + + bool IsManuallyExpandedOrCollapsed() const { + return message_view_->IsManuallyExpandedOrCollapsed(); + } + + // Updates this view with the new data contained in the notification. + void UpdateWithNotification(const message_center::Notification& notification); + + std::string notification_id() const { + return message_view_->notification_id(); + } + + message_center::MessageView::Mode GetMode() const { + return message_view_->GetMode(); + } + + void CloseSwipeControl(); + + // views::View + void ChildPreferredSizeChanged(views::View* child) override; + void ChildVisibilityChanged(views::View* child) override; + gfx::Size CalculatePreferredSize() const override; + int GetHeightForWidth(int width) const override; + + void UpdateCornerRadius(int top_radius, int bottom_radius); + + private: + // Owned by views hierarchy. + message_center::MessageView* const message_view_; + NotificationSwipeControlView* const control_view_; +}; + +} // namespace ash + +#endif // ASH_MESSAGE_CENTER_SLIDABLE_MESSAGE_VIEW_H_
diff --git a/ash/public/interfaces/login_user_info.mojom b/ash/public/interfaces/login_user_info.mojom index 240c968..7fcf4da 100644 --- a/ash/public/interfaces/login_user_info.mojom +++ b/ash/public/interfaces/login_user_info.mojom
@@ -54,6 +54,10 @@ // recognized. There have been too many unlock attempts and fingerprint // is now disabled. AUTH_DISABLED, + // Fingerprint unlock is disabled because user is forced to use an + // authentication method that authenticates via cryptohome. + // I.e., password, cryptohome-based PIN, easy unlock. + AUTH_DISABLED_FROM_TIMEOUT, }; // Information about the custom icon in the user pod.
diff --git a/ash/shelf/shelf_background_animator_unittest.cc b/ash/shelf/shelf_background_animator_unittest.cc index 62318a5b..f3b64dac 100644 --- a/ash/shelf/shelf_background_animator_unittest.cc +++ b/ash/shelf/shelf_background_animator_unittest.cc
@@ -358,28 +358,19 @@ DISALLOW_COPY_AND_ASSIGN(ShelfBackgroundTargetColorTest); }; -// Verify the target colors of the shelf and item backgrounds are updated after -// session state changes. Only compare the base color, because different alpha -// values may be applied based on |ShelfBackgroundType|, which is verifed by +// The tests only compare the base color, because different alpha values may be +// applied based on |ShelfBackgroundType|, which is verifed by // |ShelfBackgroundAnimatorTest|. +// +// Verify the target colors of the shelf and item backgrounds are updated based +// on session state, starting from LOGIN_PRIMARY. TEST_F(ShelfBackgroundTargetColorTest, - ShelfAndItemBackgroundColorUpdatedWithSessionState) { - // Use the real ShelfBackgroundAnimator instance because it needs to update - // for session state changes. + ShelfAndItemBackgroundColorUpdatedFromLogin) { ShelfBackgroundAnimatorTestApi test_api( Shelf::ForWindow(Shell::Get()->GetPrimaryRootWindow()) ->shelf_widget() ->background_animator_for_testing()); - // The shelf is not initialized until session state becomes active, so the - // following two cases don't have visible effects until we support views-based - // shelf for all session states, but it's still good to check them here. - NotifySessionStateChanged(session_manager::SessionState::OOBE); - EXPECT_EQ(GetBaseColor(test_api.shelf_background_target_color()), - GetBaseColor(SK_ColorTRANSPARENT)); - EXPECT_EQ(GetBaseColor(test_api.item_background_target_color()), - GetBaseColor(gfx::kGoogleGrey100)); - NotifySessionStateChanged(session_manager::SessionState::LOGIN_PRIMARY); EXPECT_EQ(GetBaseColor(test_api.shelf_background_target_color()), GetBaseColor(SK_ColorTRANSPARENT)); @@ -431,4 +422,39 @@ GetBaseColor(kShelfDefaultBaseColor)); } +// Verify the target colors of the shelf and item backgrounds are updated based +// on session state, starting from OOBE. +// Note: the shelf is not supported for OOBE yet but it's good to check it here. +// TODO(wzang|798869): The item backgrounds still keep the OOBE color if +// directly transitioned from OOBE to LOGIN_PRIMARY. Revisit this when OOBE +// shelf is supported. +TEST_F(ShelfBackgroundTargetColorTest, + ShelfAndItemBackgroundColorUpdatedFromOOBE) { + ShelfBackgroundAnimatorTestApi test_api( + Shelf::ForWindow(Shell::Get()->GetPrimaryRootWindow()) + ->shelf_widget() + ->background_animator_for_testing()); + + NotifySessionStateChanged(session_manager::SessionState::OOBE); + EXPECT_EQ(GetBaseColor(test_api.shelf_background_target_color()), + GetBaseColor(SK_ColorTRANSPARENT)); + EXPECT_EQ(GetBaseColor(test_api.item_background_target_color()), + GetBaseColor(gfx::kGoogleGrey100)); + + SimulateUserLogin("user1@test.com"); + + NotifySessionStateChanged( + session_manager::SessionState::LOGGED_IN_NOT_ACTIVE); + EXPECT_EQ(GetBaseColor(test_api.shelf_background_target_color()), + GetBaseColor(SK_ColorTRANSPARENT)); + EXPECT_EQ(GetBaseColor(test_api.item_background_target_color()), + GetBaseColor(SK_ColorTRANSPARENT)); + + NotifySessionStateChanged(session_manager::SessionState::ACTIVE); + EXPECT_EQ(GetBaseColor(test_api.shelf_background_target_color()), + GetBaseColor(kShelfDefaultBaseColor)); + EXPECT_EQ(GetBaseColor(test_api.item_background_target_color()), + GetBaseColor(kShelfDefaultBaseColor)); +} + } // namespace ash
diff --git a/ash/shelf/shelf_layout_manager.cc b/ash/shelf/shelf_layout_manager.cc index b75522e..a79f4ef0 100644 --- a/ash/shelf/shelf_layout_manager.cc +++ b/ash/shelf/shelf_layout_manager.cc
@@ -541,8 +541,10 @@ if (state_.session_state == session_manager::SessionState::OOBE) return SHELF_BACKGROUND_OOBE; if (state_.session_state != session_manager::SessionState::ACTIVE) { - if (!Shell::Get()->wallpaper_controller()->IsWallpaperBlurred()) + if (Shell::Get()->wallpaper_controller()->HasShownAnyWallpaper() && + !Shell::Get()->wallpaper_controller()->IsWallpaperBlurred()) { return SHELF_BACKGROUND_LOGIN_NONBLURRED_WALLPAPER; + } return SHELF_BACKGROUND_LOGIN; } @@ -1143,6 +1145,10 @@ MaybeUpdateShelfBackground(AnimationChangeType::ANIMATE); } +void ShelfLayoutManager::OnFirstWallpaperShown() { + MaybeUpdateShelfBackground(AnimationChangeType::ANIMATE); +} + void ShelfLayoutManager::OnLoginStatusChanged(LoginStatus loing_status) { UpdateVisibilityState(); }
diff --git a/ash/shelf/shelf_layout_manager.h b/ash/shelf/shelf_layout_manager.h index f5f4940..10b7de5 100644 --- a/ash/shelf/shelf_layout_manager.h +++ b/ash/shelf/shelf_layout_manager.h
@@ -187,6 +187,7 @@ // Overridden from WallpaperControllerObserver: void OnWallpaperBlurChanged() override; + void OnFirstWallpaperShown() override; // TODO(harrym|oshima): These templates will be moved to a new Shelf class. // A helper function for choosing values specific to a shelf alignment.
diff --git a/ash/shelf/shelf_layout_manager_unittest.cc b/ash/shelf/shelf_layout_manager_unittest.cc index 7636ded8..f73821ac 100644 --- a/ash/shelf/shelf_layout_manager_unittest.cc +++ b/ash/shelf/shelf_layout_manager_unittest.cc
@@ -253,6 +253,29 @@ DISALLOW_COPY_AND_ASSIGN(ShelfLayoutObserverTest); }; +class WallpaperShownWaiter : public WallpaperControllerObserver { + public: + WallpaperShownWaiter() { + Shell::Get()->wallpaper_controller()->AddObserver(this); + } + + ~WallpaperShownWaiter() override { + Shell::Get()->wallpaper_controller()->RemoveObserver(this); + } + + // Note this could only be called once because RunLoop would not run after + // Quit is called. Create a new instance if there's need to wait again. + void Wait() { run_loop_.Run(); } + + private: + // WallpaperControllerObserver: + void OnFirstWallpaperShown() override { run_loop_.Quit(); } + + base::RunLoop run_loop_; + + DISALLOW_COPY_AND_ASSIGN(WallpaperShownWaiter); +}; + } // namespace class ShelfLayoutManagerTest : public AshTestBase { @@ -986,22 +1009,32 @@ // Assertions around the login screen. TEST_F(ShelfLayoutManagerTest, VisibleWhenLoginScreenShowing) { Shelf* shelf = GetPrimaryShelf(); + WallpaperController* wallpaper_controller = + Shell::Get()->wallpaper_controller(); + WallpaperShownWaiter waiter; mojom::SessionInfoPtr info = mojom::SessionInfo::New(); info->state = session_manager::SessionState::LOGIN_PRIMARY; - ash::Shell::Get()->session_controller()->SetSessionInfo(std::move(info)); + Shell::Get()->session_controller()->SetSessionInfo(std::move(info)); EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState()); - // Blurred wallpaper. - ash::Shell::Get()->wallpaper_controller()->UpdateWallpaperBlur(/*blur=*/true); + // No wallpaper. + ASSERT_FALSE(wallpaper_controller->HasShownAnyWallpaper()); EXPECT_EQ(SHELF_BACKGROUND_LOGIN, GetShelfWidget()->GetBackgroundType()); + // Showing wallpaper is asynchronous. + wallpaper_controller->ShowDefaultWallpaperForTesting(); + waiter.Wait(); + ASSERT_TRUE(wallpaper_controller->HasShownAnyWallpaper()); + // Non-blurred wallpaper. - base::CommandLine::ForCurrentProcess()->AppendSwitch( - ash::switches::kAshDisableLoginDimAndBlur); - ash::Shell::Get()->wallpaper_controller()->UpdateWallpaperBlur(/*blur=*/true); + wallpaper_controller->UpdateWallpaperBlur(/*blur=*/false); EXPECT_EQ(SHELF_BACKGROUND_LOGIN_NONBLURRED_WALLPAPER, GetShelfWidget()->GetBackgroundType()); + + // Blurred wallpaper. + wallpaper_controller->UpdateWallpaperBlur(/*blur=*/true); + EXPECT_EQ(SHELF_BACKGROUND_LOGIN, GetShelfWidget()->GetBackgroundType()); } // Assertions around the lock screen showing.
diff --git a/ash/system/brightness/brightness_controller_chromeos.cc b/ash/system/brightness/brightness_controller_chromeos.cc index b75a90d..6bddde31 100644 --- a/ash/system/brightness/brightness_controller_chromeos.cc +++ b/ash/system/brightness/brightness_controller_chromeos.cc
@@ -8,6 +8,7 @@ #include "base/metrics/user_metrics.h" #include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/power_manager/backlight.pb.h" #include "chromeos/dbus/power_manager_client.h" #include "ui/base/accelerators/accelerator.h" @@ -36,9 +37,17 @@ void BrightnessControllerChromeos::SetBrightnessPercent(double percent, bool gradual) { + power_manager::SetBacklightBrightnessRequest request; + request.set_percent(percent); + request.set_transition( + gradual + ? power_manager::SetBacklightBrightnessRequest_Transition_GRADUAL + : power_manager::SetBacklightBrightnessRequest_Transition_INSTANT); + request.set_cause( + power_manager::SetBacklightBrightnessRequest_Cause_USER_REQUEST); chromeos::DBusThreadManager::Get() ->GetPowerManagerClient() - ->SetScreenBrightnessPercent(percent, gradual); + ->SetScreenBrightness(request); } void BrightnessControllerChromeos::GetBrightnessPercent(
diff --git a/ash/wallpaper/wallpaper_controller.cc b/ash/wallpaper/wallpaper_controller.cc index e60389b..46ab7d8 100644 --- a/ash/wallpaper/wallpaper_controller.cc +++ b/ash/wallpaper/wallpaper_controller.cc
@@ -645,6 +645,10 @@ !IsActiveUserWallpaperControlledByPolicyImpl(); } +bool WallpaperController::HasShownAnyWallpaper() const { + return !!current_wallpaper_; +} + void WallpaperController::ShowWallpaperImage(const gfx::ImageSkia& image, WallpaperInfo info, bool preview_mode) { @@ -686,6 +690,10 @@ current_wallpaper_->AddObserver(this); current_wallpaper_->StartResize(); + if (is_first_wallpaper_) { + for (auto& observer : observers_) + observer.OnFirstWallpaperShown(); + } mojo_observers_.ForAllPtrs([this](mojom::WallpaperObserver* observer) { observer->OnWallpaperChanged(current_wallpaper_->original_image_id()); }); @@ -733,6 +741,10 @@ switches::kAshDisableLoginDimAndBlur); } +bool WallpaperController::IsWallpaperBlurred() const { + return is_wallpaper_blurred_; +} + bool WallpaperController::SetUserWallpaperInfo(const AccountId& account_id, const WallpaperInfo& info, bool is_ephemeral) {
diff --git a/ash/wallpaper/wallpaper_controller.h b/ash/wallpaper/wallpaper_controller.h index c4340c6..ceb79e0 100644 --- a/ash/wallpaper/wallpaper_controller.h +++ b/ash/wallpaper/wallpaper_controller.h
@@ -148,6 +148,11 @@ // Returns true if the active user is allowed to open the wallpaper picker. bool CanOpenWallpaperPicker(); + // Returns whether any wallpaper has been shown. It returns false before the + // first wallpaper is set (which happens momentarily after startup), and will + // always return true thereafter. + bool HasShownAnyWallpaper() const; + // Shows the wallpaper and alerts observers of changes. Does not show the // image if |preview_mode| is false and the current wallpaper is still being // previewed. See comments for |confirm_preview_wallpaper_callback_|. @@ -172,7 +177,9 @@ bool IsBlurAllowed() const; // Returns whether the current wallpaper is blurred. - bool IsWallpaperBlurred() const { return is_wallpaper_blurred_; } + // Note: this returns false when there's no wallpaper yet. Check + // |HasShownAnyWallpaper| if there's need to distinguish. + bool IsWallpaperBlurred() const; // Sets wallpaper info for |account_id| and saves it to local state if // |is_ephemeral| is false. Returns false if it fails (which happens if local
diff --git a/ash/wallpaper/wallpaper_controller_observer.h b/ash/wallpaper/wallpaper_controller_observer.h index cfbdf72f..c8c1199 100644 --- a/ash/wallpaper/wallpaper_controller_observer.h +++ b/ash/wallpaper/wallpaper_controller_observer.h
@@ -23,6 +23,10 @@ // Invoked when the wallpaper preview mode ends. virtual void OnWallpaperPreviewEnded() {} + // Invoked when the first wallpaper is set. The first wallpaper is the one + // shown right after boot splash screen or after a session restart. + virtual void OnFirstWallpaperShown() {} + protected: virtual ~WallpaperControllerObserver() {} };
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc index b7b9f859..162edda 100644 --- a/ash/wallpaper/wallpaper_controller_unittest.cc +++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -268,10 +268,15 @@ TestWallpaperControllerObserver() = default; void OnWallpaperBlurChanged() override { ++wallpaper_blur_changed_count_; } + void OnFirstWallpaperShown() override { ++first_wallpaper_shown_count_; } void Reset() { wallpaper_blur_changed_count_ = 0; } int wallpaper_blur_changed_count_ = 0; + int first_wallpaper_shown_count_ = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(TestWallpaperControllerObserver); }; } // namespace @@ -2358,6 +2363,30 @@ EXPECT_EQ(WallpaperType::CUSTOMIZED, controller_->GetWallpaperType()); } +TEST_F(WallpaperControllerTest, OnFirstWallpaperShown) { + TestWallpaperControllerObserver observer; + controller_->AddObserver(&observer); + EXPECT_EQ(0, GetWallpaperCount()); + EXPECT_EQ(0, observer.first_wallpaper_shown_count_); + // Show the first wallpaper, verify the observer is notified. + controller_->ShowWallpaperImage(CreateImage(640, 480, SK_ColorBLUE), + CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH), + false /*preview_mode=*/); + RunAllTasksUntilIdle(); + EXPECT_EQ(SK_ColorBLUE, GetWallpaperColor()); + EXPECT_EQ(1, GetWallpaperCount()); + EXPECT_EQ(1, observer.first_wallpaper_shown_count_); + // Show the second wallpaper, verify the observer is not notified. + controller_->ShowWallpaperImage(CreateImage(640, 480, SK_ColorCYAN), + CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH), + false /*preview_mode=*/); + RunAllTasksUntilIdle(); + EXPECT_EQ(SK_ColorCYAN, GetWallpaperColor()); + EXPECT_EQ(2, GetWallpaperCount()); + EXPECT_EQ(1, observer.first_wallpaper_shown_count_); + controller_->RemoveObserver(&observer); +} + // A test wallpaper controller client class. class TestWallpaperControllerClient : public mojom::WallpaperControllerClient { public:
diff --git a/ash/wm/tablet_mode/tablet_mode_controller.cc b/ash/wm/tablet_mode/tablet_mode_controller.cc index 55a37f9f..5309029 100644 --- a/ash/wm/tablet_mode/tablet_mode_controller.cc +++ b/ash/wm/tablet_mode/tablet_mode_controller.cc
@@ -254,6 +254,9 @@ Shell::Get()->window_tree_host_manager()->AddObserver(this); chromeos::AccelerometerReader::GetInstance()->AddObserver(this); ui::InputDeviceManager::GetInstance()->AddObserver(this); + bluetooth_devices_observer_ = std::make_unique<BluetoothDevicesObserver>( + base::BindRepeating(&TabletModeController::UpdateBluetoothDevice, + base::Unretained(this))); chromeos::PowerManagerClient* power_manager_client = chromeos::DBusThreadManager::Get()->GetPowerManagerClient();
diff --git a/build/config/sanitizers/BUILD.gn b/build/config/sanitizers/BUILD.gn index 2ad0304..92e6fcb 100644 --- a/build/config/sanitizers/BUILD.gn +++ b/build/config/sanitizers/BUILD.gn
@@ -227,29 +227,38 @@ } } } - } else if (is_win && is_asan) { + } else if (is_win) { # Windows directly calls link.exe instead of the compiler driver when - # linking. Hence, pass the runtime libraries instead of -fsanitize=address. - # In the static-library build, libraries are different for executables - # and dlls, see link_executable and link_shared_library below. - # This here handles only the component build. - if (target_cpu == "x64") { - # Windows 64-bit. - if (is_component_build) { + # linking. Hence, pass the runtime libraries instead of -fsanitize=address + # or -fsanitize=fuzzer. + if (is_asan && is_component_build) { + # In the static-library build, ASan libraries are different for + # executables and dlls, see link_executable and link_shared_library below. + # This here handles only the component build. + if (target_cpu == "x64") { + # Windows 64-bit. libs = [ "clang_rt.asan_dynamic-x86_64.lib", "clang_rt.asan_dynamic_runtime_thunk-x86_64.lib", ] - } - } else { - assert(target_cpu == "x86", "WinASan unsupported architecture") - if (is_component_build) { + } else { + assert(target_cpu == "x86", "WinASan unsupported architecture") libs = [ "clang_rt.asan_dynamic-i386.lib", "clang_rt.asan_dynamic_runtime_thunk-i386.lib", ] } } + if (use_libfuzzer) { + assert(target_cpu == "x64", "LibFuzzer unsupported architecture") + assert(!is_component_build, + "LibFuzzer only supports non-component builds on Windows") + + # Incremental linking causes padding that messes up SanitizerCoverage. + # Don't do it. + ldflags = [ "/INCREMENTAL:NO" ] + libs = [ "clang_rt.fuzzer_no_main-x86_64.lib" ] + } } }
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc index 9b7809e3..a9cda9e8 100644 --- a/cc/layers/picture_layer_impl.cc +++ b/cc/layers/picture_layer_impl.cc
@@ -718,26 +718,29 @@ } viewport_rect_for_tile_priority_in_content_space_ = visible_rect_in_content_space; -#if defined(OS_ANDROID) - // On android, if we're in a scrolling gesture, the pending tree does not - // reflect the fact that we may be hiding the top or bottom controls. Thus, - // it would believe that the viewport is smaller than it actually is which - // can cause activation flickering issues. So, if we're in this situation - // adjust the visible rect by the top/bottom controls height. This isn't - // ideal since we're not always in this case, but since we should be - // prioritizing the active tree anyway, it doesn't cause any serious issues. - // https://crbug.com/794456. - if (layer_tree_impl()->IsPendingTree() && - layer_tree_impl()->IsActivelyScrolling()) { - float total_controls_height = layer_tree_impl()->top_controls_height() + - layer_tree_impl()->bottom_controls_height(); - viewport_rect_for_tile_priority_in_content_space_.Inset( - 0, // left - 0, // top, - 0, // right, - -total_controls_height); // bottom + + float total_controls_height = layer_tree_impl()->top_controls_height() + + layer_tree_impl()->bottom_controls_height(); + if (total_controls_height) { + // If sliding top controls are being used, the pending tree does not + // reflect the fact that we may be hiding the top or bottom controls. Thus, + // it would believe that the viewport is smaller than it actually is which + // can cause activation flickering issues. So, if we're in this situation + // adjust the visible rect by the amount the controls are expanded beyond + // the current viewport size (this is also called the "bounds delta" in + // LayerImpl and LTHI::UpdateViewportContainerBounds(). + if (layer_tree_impl()->IsPendingTree() && + layer_tree_impl()->browser_controls_shrink_blink_size()) { + float hidden_ratio = + 1.f - layer_tree_impl()->CurrentBrowserControlsShownRatio(); + + viewport_rect_for_tile_priority_in_content_space_.Inset( + 0, // left + 0, // top, + 0, // right, + std::ceilf(-total_controls_height * hidden_ratio)); // bottom + } } -#endif } PictureLayerImpl* PictureLayerImpl::GetPendingOrActiveTwinLayer() const {
diff --git a/cc/trees/layer_tree_host.cc b/cc/trees/layer_tree_host.cc index a18aa62..e3bd5b6d 100644 --- a/cc/trees/layer_tree_host.cc +++ b/cc/trees/layer_tree_host.cc
@@ -1165,9 +1165,13 @@ if (changed) { SetPropertyTreesNeedRebuild(); SetNeedsCommit(); +#if defined(OS_MACOSX) + // TODO(ccameron): This check is not valid on Aura or Mus yet, but should + // be. CHECK(!has_pushed_local_surface_id_from_parent_ || new_local_surface_id_request_ || !local_surface_id_from_parent_.is_valid()); +#endif } }
diff --git a/chrome/android/java/res/layout/explore_sites_category_card_view.xml b/chrome/android/java/res/layout/explore_sites_category_card_view.xml index 03d70bbb..210452c2 100644 --- a/chrome/android/java/res/layout/explore_sites_category_card_view.xml +++ b/chrome/android/java/res/layout/explore_sites_category_card_view.xml
@@ -7,20 +7,22 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" - android:layout_height="wrap_content" > + android:layout_height="wrap_content" + android:orientation="vertical" + android:gravity="center_horizontal" > <TextView android:id="@+id/category_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_horizontal" - android:lines="1" android:textAppearance="@style/BlackTitle1" /> <GridLayout android:id="@+id/category_sites" android:layout_width="match_parent" android:layout_height="wrap_content" + android:orientation="horizontal" android:columnCount="4" android:rowCount="2" />
diff --git a/chrome/android/java/res/layout/explore_sites_page_layout.xml b/chrome/android/java/res/layout/explore_sites_page_layout.xml index 2c8df9b7..0847921 100644 --- a/chrome/android/java/res/layout/explore_sites_page_layout.xml +++ b/chrome/android/java/res/layout/explore_sites_page_layout.xml
@@ -3,15 +3,11 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<org.chromium.chrome.browser.explore_sites.ExploreSitesPageLayout +<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/explore_sites_category_recycler" + android:scrollbars="vertical" + android:gravity="center_horizontal" android:layout_width="match_parent" - android:layout_height="match_parent" > - - <android.support.v7.widget.RecyclerView - android:id="@+id/explore_sites_category_recycler" - android:scrollbars="vertical" - android:layout_width="match_parent" - android:layout_height="match_parent" /> -</org.chromium.chrome.browser.explore_sites.ExploreSitesPageLayout> + android:layout_height="match_parent" />
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelper.java index 2ed6704..238d17f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelper.java
@@ -172,6 +172,18 @@ } @Override + public void onUrlUpdated(Tab tab) { + assert !tab.isIncognito(); + // This address cases, where pages are implemented as a single page app and + // switching between articles updates URL, but does not cause a page reload. + if (tab == mCurrentTab + && !getTabFetchReadinessState(tab).isContextTheSame(tab.getUrl())) { + clearState(); + getTabFetchReadinessState(tab).updateUrl(tab.getUrl()); + } + } + + @Override public void didFirstVisuallyNonEmptyPaint(Tab tab) { setTimeBaselineAndMaybeFetch(tab); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardAdapter.java b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/CategoryCardAdapter.java similarity index 72% rename from chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardAdapter.java rename to chrome/android/java/src/org/chromium/chrome/browser/explore_sites/CategoryCardAdapter.java index 2417655..127a75f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardAdapter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/CategoryCardAdapter.java
@@ -10,11 +10,13 @@ import android.widget.TextView; import org.chromium.chrome.R; -import org.chromium.chrome.browser.modelutil.ListObservableImpl; +import org.chromium.chrome.browser.modelutil.ForwardingListObservable; import org.chromium.chrome.browser.modelutil.PropertyKey; import org.chromium.chrome.browser.modelutil.PropertyModel; import org.chromium.chrome.browser.modelutil.PropertyObservable; import org.chromium.chrome.browser.modelutil.RecyclerViewAdapter; +import org.chromium.chrome.browser.native_page.ContextMenuManager; +import org.chromium.chrome.browser.native_page.NativePageNavigationDelegate; import org.chromium.chrome.browser.widget.RoundedIconGenerator; import java.lang.annotation.Retention; @@ -23,10 +25,9 @@ /** * Recycler view adapter delegate for a model containing a list of category cards and an error code. */ -public class ExploreSitesCategoryCardAdapter extends ListObservableImpl<ExploreSitesCategory> - implements RecyclerViewAdapter.Delegate< - ExploreSitesCategoryCardViewHolderFactory.CategoryCardViewHolder, - ExploreSitesCategory>, +class CategoryCardAdapter extends ForwardingListObservable<Void> + implements RecyclerViewAdapter + .Delegate<CategoryCardViewHolderFactory.CategoryCardViewHolder, Void>, PropertyObservable.PropertyObserver<PropertyKey> { @IntDef({ViewType.HEADER, ViewType.CATEGORY, ViewType.LOADING, ViewType.ERROR}) @Retention(RetentionPolicy.SOURCE) @@ -37,15 +38,24 @@ int ERROR = 3; } + private final RoundedIconGenerator mIconGenerator; + private final ContextMenuManager mContextMenuManager; + private final NativePageNavigationDelegate mNavDelegate; + private RecyclerView.LayoutManager mLayoutManager; private PropertyModel mCategoryModel; - private RoundedIconGenerator mIconGenerator; - public ExploreSitesCategoryCardAdapter(PropertyModel model, - RecyclerView.LayoutManager layoutManager, RoundedIconGenerator iconGenerator) { - model.addObserver(this); + public CategoryCardAdapter(PropertyModel model, RecyclerView.LayoutManager layoutManager, + RoundedIconGenerator iconGenerator, ContextMenuManager contextMenuManager, + NativePageNavigationDelegate navDelegate) { mCategoryModel = model; + mCategoryModel.addObserver(this); + mCategoryModel.get(ExploreSitesPage.CATEGORY_LIST_KEY).addObserver(this); + + mLayoutManager = layoutManager; mIconGenerator = iconGenerator; + mContextMenuManager = contextMenuManager; + mNavDelegate = navDelegate; } @Override @@ -75,9 +85,8 @@ } @Override - public void onBindViewHolder( - ExploreSitesCategoryCardViewHolderFactory.CategoryCardViewHolder holder, int position, - @Nullable ExploreSitesCategory payload) { + public void onBindViewHolder(CategoryCardViewHolderFactory.CategoryCardViewHolder holder, + int position, @Nullable Void payload) { if (holder.getItemViewType() == ViewType.HEADER) { TextView view = (TextView) holder.itemView; view.setText(R.string.explore_sites_title); @@ -87,10 +96,10 @@ // Populate loading view } else { ExploreSitesCategoryCardView view = (ExploreSitesCategoryCardView) holder.itemView; - view.setIconGenerator(mIconGenerator); // Position - 1 because there is always title. - view.initialize( - mCategoryModel.get(ExploreSitesPage.CATEGORY_LIST_KEY).get(position - 1)); + view.setCategory( + mCategoryModel.get(ExploreSitesPage.CATEGORY_LIST_KEY).get(position - 1), + mIconGenerator, mContextMenuManager, mNavDelegate); } } @@ -106,7 +115,7 @@ } if (key == ExploreSitesPage.SCROLL_TO_CATEGORY_KEY) { int pos = mCategoryModel.get(ExploreSitesPage.SCROLL_TO_CATEGORY_KEY); - mLayoutManager.scrollToPosition(pos + 1); + mLayoutManager.scrollToPosition(pos); } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardViewHolderFactory.java b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/CategoryCardViewHolderFactory.java similarity index 66% rename from chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardViewHolderFactory.java rename to chrome/android/java/src/org/chromium/chrome/browser/explore_sites/CategoryCardViewHolderFactory.java index 8671465..b62b3b7b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardViewHolderFactory.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/CategoryCardViewHolderFactory.java
@@ -14,9 +14,8 @@ import org.chromium.chrome.browser.modelutil.RecyclerViewAdapter; /** Factory to create CategoryCardViewHolder objects. */ -public class ExploreSitesCategoryCardViewHolderFactory - implements RecyclerViewAdapter.ViewHolderFactory< - ExploreSitesCategoryCardViewHolderFactory.CategoryCardViewHolder> { +class CategoryCardViewHolderFactory implements RecyclerViewAdapter.ViewHolderFactory< + CategoryCardViewHolderFactory.CategoryCardViewHolder> { /** View holder for the recycler view. */ public static class CategoryCardViewHolder extends RecyclerView.ViewHolder { public CategoryCardViewHolder(View view) { @@ -26,19 +25,20 @@ @Override public CategoryCardViewHolder createViewHolder( - ViewGroup parent, @ExploreSitesCategoryCardAdapter.ViewType int viewType) { + ViewGroup parent, @CategoryCardAdapter.ViewType int viewType) { View view; switch (viewType) { - case ExploreSitesCategoryCardAdapter.ViewType.HEADER: + case CategoryCardAdapter.ViewType.HEADER: + TextView titleView = new TextView(parent.getContext()); view = new TextView(parent.getContext()); break; - case ExploreSitesCategoryCardAdapter.ViewType.CATEGORY: + case CategoryCardAdapter.ViewType.CATEGORY: view = (ExploreSitesCategoryCardView) LayoutInflater.from(parent.getContext()) - .inflate(R.layout.explore_sites_category_card_view, parent); + .inflate(R.layout.explore_sites_category_card_view, null); break; - case ExploreSitesCategoryCardAdapter.ViewType.LOADING: // inflate loading spinny - case ExploreSitesCategoryCardAdapter.ViewType.ERROR: // inflate error - view = null; + case CategoryCardAdapter.ViewType.LOADING: // inflate loading spinny + case CategoryCardAdapter.ViewType.ERROR: // inflate error + view = new TextView(parent.getContext()); // dummy view. break; default: assert false;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardView.java b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardView.java index cd19914..ec7e27a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardView.java
@@ -6,13 +6,22 @@ import android.content.Context; import android.util.AttributeSet; +import android.view.ContextMenu; import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.View.OnCreateContextMenuListener; import android.widget.GridLayout; import android.widget.LinearLayout; import android.widget.TextView; import org.chromium.chrome.R; +import org.chromium.chrome.browser.native_page.ContextMenuManager; +import org.chromium.chrome.browser.native_page.NativePageNavigationDelegate; import org.chromium.chrome.browser.widget.RoundedIconGenerator; +import org.chromium.content_public.browser.LoadUrlParams; +import org.chromium.ui.base.PageTransition; +import org.chromium.ui.mojom.WindowOpenDisposition; import java.util.List; @@ -23,6 +32,53 @@ private TextView mTitleView; private GridLayout mTileView; private RoundedIconGenerator mIconGenerator; + private ContextMenuManager mContextMenuManager; + private NativePageNavigationDelegate mNavigationDelegate; + + private class CategoryCardInteractionDelegate + implements ContextMenuManager.Delegate, OnClickListener, OnCreateContextMenuListener { + private ExploreSitesSite mSite; + public CategoryCardInteractionDelegate(ExploreSitesSite site) { + mSite = site; + } + + @Override + public void onClick(View view) { + mNavigationDelegate.openUrl(WindowOpenDisposition.CURRENT_TAB, + new LoadUrlParams(getUrl(), PageTransition.AUTO_BOOKMARK)); + } + + @Override + public void onCreateContextMenu( + ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { + mContextMenuManager.createContextMenu(menu, v, this); + } + + @Override + public void openItem(int windowDisposition) { + mNavigationDelegate.openUrl( + windowDisposition, new LoadUrlParams(getUrl(), PageTransition.AUTO_BOOKMARK)); + } + + @Override + public void removeItem() {} // TODO(chili): Add removal method. + + @Override + public String getUrl() { + return mSite.getUrl(); + } + + @Override + public boolean isItemSupported(@ContextMenuManager.ContextMenuItemId int menuItemId) { + if (menuItemId == ContextMenuManager.ContextMenuItemId.LEARN_MORE) { + return false; + } + return true; + } + + @Override + public void onContextMenuCreated(){}; + } public ExploreSitesCategoryCardView(Context context, AttributeSet attrs) { super(context, attrs); @@ -35,11 +91,13 @@ mTileView = findViewById(R.id.category_sites); } - public void setIconGenerator(RoundedIconGenerator iconGenerator) { + public void setCategory(ExploreSitesCategory category, RoundedIconGenerator iconGenerator, + ContextMenuManager contextMenuManager, + NativePageNavigationDelegate navigationDelegate) { mIconGenerator = iconGenerator; - } + mContextMenuManager = contextMenuManager; + mNavigationDelegate = navigationDelegate; - public void initialize(ExploreSitesCategory category) { updateTitle(category.getTitle()); updateTileViews(category.getSites()); } @@ -57,14 +115,19 @@ if (mTileView.getChildCount() < sites.size()) { for (int i = mTileView.getChildCount(); i < sites.size(); i++) { mTileView.addView(LayoutInflater.from(getContext()) - .inflate(R.layout.explore_sites_tile_view, mTileView)); + .inflate(R.layout.explore_sites_tile_view, null)); } } // Initialize all the tiles again to update. for (int i = 0; i < sites.size(); i++) { ExploreSitesTileView tileView = (ExploreSitesTileView) mTileView.getChildAt(i); - tileView.setIconGenerator(mIconGenerator); - tileView.initialize(sites.get(i)); + final ExploreSitesSite site = sites.get(i); + tileView.initialize(site, mIconGenerator); + + CategoryCardInteractionDelegate interactionDelegate = + new CategoryCardInteractionDelegate(site); + tileView.setOnClickListener(interactionDelegate); + tileView.setOnCreateContextMenuListener(interactionDelegate); } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesPage.java b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesPage.java index efb7436..ef60bb6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesPage.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesPage.java
@@ -4,11 +4,11 @@ package org.chromium.chrome.browser.explore_sites; -import android.app.Activity; import android.content.Context; import android.support.annotation.IntDef; import android.support.annotation.Nullable; import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; @@ -18,19 +18,26 @@ import org.chromium.chrome.browser.UrlConstants; import org.chromium.chrome.browser.modelutil.ListModel; import org.chromium.chrome.browser.modelutil.PropertyModel; +import org.chromium.chrome.browser.modelutil.RecyclerViewAdapter; import org.chromium.chrome.browser.native_page.BasicNativePage; +import org.chromium.chrome.browser.native_page.ContextMenuManager; import org.chromium.chrome.browser.native_page.NativePageHost; +import org.chromium.chrome.browser.native_page.NativePageNavigationDelegateImpl; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.widget.RoundedIconGenerator; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.net.URI; +import java.net.URISyntaxException; import java.util.List; /** * Provides functionality when the user interacts with the explore sites page. */ public class ExploreSitesPage extends BasicNativePage { + private static final String CONTEXT_MENU_USER_ACTION_PREFIX = "ExploreSites"; static final PropertyModel.WritableIntPropertyKey STATUS_KEY = new PropertyModel.WritableIntPropertyKey(); static final PropertyModel.WritableIntPropertyKey SCROLL_TO_CATEGORY_KEY = @@ -47,30 +54,36 @@ int ERROR = 3; } + private final TabModelSelector mTabModelSelector; + private NativePageHost mHost; private ViewGroup mView; private String mTitle; - private Activity mActivity; - private ExploreSitesPageLayout mLayout; private PropertyModel mModel; + private CategoryCardAdapter mAdapter; + private ContextMenuManager mContextMenuManager; + private String mNavFragment; /** * Create a new instance of the explore sites page. */ public ExploreSitesPage(ChromeActivity activity, NativePageHost host) { super(activity, host); + mTabModelSelector = activity.getTabModelSelector(); } @Override - protected void initialize(ChromeActivity activity, NativePageHost host) { - mActivity = activity; - mTitle = mActivity.getString(R.string.explore_sites_title); - mView = (ViewGroup) mActivity.getLayoutInflater().inflate( + protected void initialize(ChromeActivity activity, final NativePageHost host) { + mHost = host; + mTitle = activity.getString(R.string.explore_sites_title); + mView = (ViewGroup) activity.getLayoutInflater().inflate( R.layout.explore_sites_page_layout, null); mModel = new PropertyModel.Builder(STATUS_KEY, SCROLL_TO_CATEGORY_KEY, CATEGORY_LIST_KEY) .with(CATEGORY_LIST_KEY, new ListModel<ExploreSitesCategory>()) .with(SCROLL_TO_CATEGORY_KEY, 0) + .with(STATUS_KEY, CatalogLoadingState.LOADING) .build(); + Context context = mView.getContext(); LinearLayoutManager layoutManager = new LinearLayoutManager(context); int iconSizePx = context.getResources().getDimensionPixelSize(R.dimen.tile_view_icon_size); @@ -80,18 +93,43 @@ context.getResources(), R.color.default_favicon_background_color), context.getResources().getDimensionPixelSize(R.dimen.headline_size_medium)); - ExploreSitesCategoryCardAdapter adapterDelegate = - new ExploreSitesCategoryCardAdapter(mModel, layoutManager, iconGenerator); - Profile profile = host.getActiveTab().getProfile(); + NativePageNavigationDelegateImpl navDelegate = + new NativePageNavigationDelegateImpl(activity, profile, host, mTabModelSelector); + // Don't direct reference activity because it might change if tab is reparented. + Runnable closeContextMenuCallback = + () -> host.getActiveTab().getActivity().closeContextMenu(); + mContextMenuManager = new ContextMenuManager(navDelegate, this ::setTouchEnabled, + closeContextMenuCallback, CONTEXT_MENU_USER_ACTION_PREFIX); + host.getActiveTab().getWindowAndroid().addContextMenuCloseListener(mContextMenuManager); + + CategoryCardAdapter adapterDelegate = new CategoryCardAdapter( + mModel, layoutManager, iconGenerator, mContextMenuManager, navDelegate); + + RecyclerView recyclerView = + (RecyclerView) mView.findViewById(R.id.explore_sites_category_recycler); + RecyclerViewAdapter<CategoryCardViewHolderFactory.CategoryCardViewHolder, Void> adapter = + new RecyclerViewAdapter<>(adapterDelegate, new CategoryCardViewHolderFactory()); + + recyclerView.setLayoutManager(layoutManager); + recyclerView.setAdapter(adapter); + ExploreSitesBridge.getEspCatalog(profile, this::translateToModel); - mModel.set(STATUS_KEY, CatalogLoadingState.LOADING); + // TODO(chili): Set layout to be an observer of list model } private void translateToModel(@Nullable List<ExploreSitesCategory> categoryList) { + if (categoryList == null) { + mModel.set(STATUS_KEY, CatalogLoadingState.ERROR); + return; + } + mModel.set(STATUS_KEY, CatalogLoadingState.SUCCESS); ListModel<ExploreSitesCategory> categoryListModel = mModel.get(CATEGORY_LIST_KEY); categoryListModel.set(categoryList); + if (mNavFragment != null) { + lookupCategoryAndScroll(mNavFragment); + } } @Override @@ -108,4 +146,45 @@ public String getTitle() { return mTitle; } + + @Override + public void updateForUrl(String url) { + super.updateForUrl(url); + String fragment; + try { + fragment = new URI(url).getFragment(); + } catch (URISyntaxException e) { + fragment = ""; + } + if (mModel.get(STATUS_KEY) == CatalogLoadingState.LOADING) { + mNavFragment = fragment; + } else { + lookupCategoryAndScroll(fragment); + } + } + + @Override + public void destroy() { + mHost.getActiveTab().getWindowAndroid().removeContextMenuCloseListener(mContextMenuManager); + super.destroy(); + } + + private void setTouchEnabled(boolean enabled) {} // Does nothing. + + private void lookupCategoryAndScroll(String categoryId) { + int position = 0; + try { + int id = Integer.parseInt(categoryId); + ListModel<ExploreSitesCategory> categoryList = mModel.get(CATEGORY_LIST_KEY); + for (int i = 0; i < categoryList.size(); i++) { + if (categoryList.get(i).getId() == id) { + position = i; + break; + } + } + } catch (NumberFormatException e) { + } // do nothing + mModel.set(SCROLL_TO_CATEGORY_KEY, position); + mNavFragment = null; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesTileView.java b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesTileView.java index f277d6a..20c097e7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesTileView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesTileView.java
@@ -29,7 +29,8 @@ mIconSizePx = getResources().getDimensionPixelSize(R.dimen.tile_view_icon_size); } - public void initialize(ExploreSitesSite site) { + public void initialize(ExploreSitesSite site, RoundedIconGenerator generator) { + mIconGenerator = generator; super.initialize(site.getTitle(), /* showOfflineBadge = */ false, getDrawableForBitmap(site.getIcon(), site.getTitle()), TITLE_LINES); } @@ -44,12 +45,4 @@ } return ViewUtils.createRoundedBitmapDrawable(image, mIconSizePx / 2); } - - /** - * Sets icon generator. This is to help prevent an instance of icon generator - * being created for each tile. - */ - void setIconGenerator(RoundedIconGenerator generator) { - mIconGenerator = generator; - } }
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 45794f3..4ba5685 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -563,15 +563,15 @@ "java/src/org/chromium/chrome/browser/download/ui/OfflineGroupHeaderView.java", "java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java", "java/src/org/chromium/chrome/browser/engagement/SiteEngagementService.java", + "java/src/org/chromium/chrome/browser/explore_sites/CategoryCardAdapter.java", + "java/src/org/chromium/chrome/browser/explore_sites/CategoryCardViewHolderFactory.java", "java/src/org/chromium/chrome/browser/explore_sites/ExperimentalExploreSitesCategoryTileView.java", "java/src/org/chromium/chrome/browser/explore_sites/ExperimentalExploreSitesSection.java", "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBackgroundTask.java", "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBridge.java", "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBridgeExperimental.java", "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategory.java", - "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardAdapter.java", "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardView.java", - "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardViewHolderFactory.java", "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryTile.java", "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryTileView.java", "java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesPage.java",
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelperTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelperTest.java index 1e03c5b..5821906 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelperTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/contextual_suggestions/FetchHelperTest.java
@@ -149,6 +149,27 @@ } @Test + public void tabObserver_onUrlUpdated() { + FetchHelper helper = createFetchHelper(); + doReturn(DIFFERENT_URL).when(mTab).getUrl(); + getTabObserver().onUrlUpdated(mTab); + verify(mDelegate, times(1)).clearState(); + // Normally we would change the suffix here, but ShadowUrlUtilities don't support that now. + doReturn(STARTING_URL).when(mTab).getUrl(); + getTabObserver().onUrlUpdated(mTab); + verify(mDelegate, times(2)).clearState(); + + // Should be ignored, because URL is the same. + getTabObserver().onUrlUpdated(mTab); + verify(mDelegate, times(2)).clearState(); + + // Should be ignored, because tab is different. + doReturn(STARTING_URL).when(mTab2).getUrl(); + getTabObserver().onUrlUpdated(mTab2); + verify(mDelegate, times(2)).clearState(); + } + + @Test public void tabObserver_didFirstVisuallyNonEmptyPaint() { delayFetchExecutionTest((tabObserver) -> tabObserver.didFirstVisuallyNonEmptyPaint(mTab)); }
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 338a1c8..296c62f 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -135,9 +135,6 @@ </message> <!-- MultiDevice setup dialog. --> - <message name="IDS_MULTIDEVICE_SETUP_DIALOG_TITLE" desc="Title for the MultiDevice setup dialog, which allows users to enable features which involve communication between multiple devices (e.g., a Chromebook and a phone)." translateable="false"> - MultiDevice Setup - </message> <message name="IDS_MULTIDEVICE_SETUP_ACCEPT_LABEL" desc="Label for button to accept conditions and begin MultiDevice setup workflow."> Accept & continue </message>
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 2a7994f..20395d4 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -6640,7 +6640,7 @@ You've signed in and turned on Sync </message> <message name="IDS_SYNC_CONFIRMATION_DICE_TITLE" desc="Title of the sync confirmation dialog in the tab modal signin flow when Dice is enabled"> - You've turned on Sync + Turn on sync? </message> <message name="IDS_SYNC_CONFIRMATION_UNITY_TITLE" desc="Title of the sync confirmation dialog in the tab modal signin flow when Unity is enabled"> Get Google smarts in Chrome @@ -6710,15 +6710,9 @@ <message name="IDS_SYNC_CONFIRMATION_DICE_SYNC_SETTINGS_DESCRIPTION" desc="Body of the personalize services section of the sync confirmation dialog in the tab modal signin flow for child accounts"> Google may use content on sites you visit, plus browser activity and interactions, to personalize Chrome and other Google services like Translate, Search, and ads. You can customize this in Settings. </message> - <message name="IDS_SYNC_CONFIRMATION_CONFIRM_BUTTON_LABEL" desc="Label of the confirmation button in the sync confirmation dialog of the tab modal signin flow"> - Ok, got it - </message> <message name="IDS_SYNC_CONFIRMATION_DICE_CONFIRM_BUTTON_LABEL" desc="Label of the confirmation button in the sync confirmation dialog of the tab modal signin flow"> Yes, I'm in </message> - <message name="IDS_SYNC_CONFIRMATION_UNDO_BUTTON_LABEL" desc="Label of the undo button in the sync confirmation dialog of the tab modal signin flow"> - Undo - </message> <message name="IDS_SYNC_CONFIRMATION_DICE_SETTINGS_BUTTON_LABEL" desc="Label of the button in the sync confirmation dialog of the tab modal signin flow to open settings"> Settings </message>
diff --git a/chrome/app/settings_chromium_strings.grdp b/chrome/app/settings_chromium_strings.grdp index cba4d6e..7b263c0 100644 --- a/chrome/app/settings_chromium_strings.grdp +++ b/chrome/app/settings_chromium_strings.grdp
@@ -62,6 +62,15 @@ <message name="IDS_SETTINGS_NON_PERSONALIZED_SERVICES_SECTION_DESC" desc="Brief explanation of the capability of Google services."> Communicates with Google to improve browsing and Chromium </message> + <message name="IDS_SETTINGS_RESTART_TO_APPLY_CHANGES" desc="Description in the snackbar to restart Chrome and apply changes."> + To apply your changes, relaunch Chromium + </message> + <message name="IDS_SETTINGS_SIGNIN_ALLOWED" desc="The title of the preference to allow to sign-in to Chrome"> + Allow Chromium sign-in + </message> + <message name="IDS_SETTINGS_SIGNIN_ALLOWED_DESC" desc="The description of the preference to allow to sign-in to Chrome"> + By turning this off, you can sign in to Google sites like Gmail without signing in to Chromium + </message> <!-- People Page --> <message name="IDS_SETTINGS_SYNC_DISABLED_BY_ADMINISTRATOR" desc="The text to display when sync is disabled by administrator policy."> @@ -80,9 +89,6 @@ <message name="IDS_SETTINGS_PROFILE_NAME_AND_PICTURE" desc="Label of the link that takes you to the page to edit your name and picture for your chrome profile."> Chromium name and picture </message> - <message name="IDS_SETTINGS_PEOPLE_SIGN_IN_PROMPT_SECONDARY_WITH_NO_ACCOUNT" desc="The secondary text displayed to prompt users to sign in to Chromium."> - Sign in to sync and personalize Chromium across your devices - </message> <message name="IDS_SETTINGS_PEOPLE_SIGN_IN_PROMPT_SECONDARY_WITH_ACCOUNT" desc="The secondary text displayed to prompt users to enable sync for an account that is alredy present in Chromium."> Sync and personalize Chromium across your devices </message>
diff --git a/chrome/app/settings_google_chrome_strings.grdp b/chrome/app/settings_google_chrome_strings.grdp index 8830a6d1..16563301 100644 --- a/chrome/app/settings_google_chrome_strings.grdp +++ b/chrome/app/settings_google_chrome_strings.grdp
@@ -62,6 +62,15 @@ <message name="IDS_SETTINGS_NON_PERSONALIZED_SERVICES_SECTION_DESC" desc="Brief explanation of the capability of Google services."> Communicates with Google to improve browsing and Chrome </message> + <message name="IDS_SETTINGS_RESTART_TO_APPLY_CHANGES" desc="Description in the snackbar to restart Chrome and apply changes."> + To apply your changes, relaunch Chrome + </message> + <message name="IDS_SETTINGS_SIGNIN_ALLOWED" desc="The title of the preference to allow to sign-in to Chrome"> + Allow Chrome sign-in + </message> + <message name="IDS_SETTINGS_SIGNIN_ALLOWED_DESC" desc="The description of the preference to allow to sign-in to Chrome"> + By turning this off, you can sign in to Google sites like Gmail without signing in to Chrome + </message> <!-- People Page --> <message name="IDS_SETTINGS_SYNC_DISABLED_BY_ADMINISTRATOR" desc="The text to display when sync is disabled by administrator policy."> @@ -80,9 +89,6 @@ <message name="IDS_SETTINGS_PROFILE_NAME_AND_PICTURE" desc="Label of the link that takes you to the page to edit your name and picture for your chrome profile."> Chrome name and picture </message> - <message name="IDS_SETTINGS_PEOPLE_SIGN_IN_PROMPT_SECONDARY_WITH_NO_ACCOUNT" desc="The secondary text displayed to prompt users to sign in to Chrome."> - Sign in to sync and personalize Chrome across your devices - </message> <message name="IDS_SETTINGS_PEOPLE_SIGN_IN_PROMPT_SECONDARY_WITH_ACCOUNT" desc="The secondary text displayed to prompt users to enable sync for an account that is alredy present in Chrome."> Sync and personalize Chrome across your devices </message>
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index 4c3f1eeb..54d47fc 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -3455,9 +3455,6 @@ <message name="IDS_SETTINGS_PEOPLE_SYNC_ANOTHER_ACCOUNT" desc="The label for the button that lets the user choose another account to sync with."> Use another account </message> - <message name="IDS_SETTINGS_PEOPLE_SYNC_AS_NAME" desc="The label for the button that lets the user start syncing with the selected account."> - Sync as <ph name="FULL_NAME">$1<ex>Bob Smith</ex></ph> - </message> <message name="IDS_SETTINGS_PEOPLE_SYNCING_TO_ACCOUNT" desc="The text displayed to the user that the profile is currently syncing to a specific account."> Syncing to <ph name="EMAIL">$1<ex>abcd@google.com</ex></ph> </message>
diff --git a/chrome/app/theme/default_100_percent/legacy/avatar_menu_auth_error.png b/chrome/app/theme/default_100_percent/legacy/avatar_menu_auth_error.png deleted file mode 100644 index 5464700f8..0000000 --- a/chrome/app/theme/default_100_percent/legacy/avatar_menu_auth_error.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_100_percent/legacy/info_small.png b/chrome/app/theme/default_100_percent/legacy/info_small.png deleted file mode 100644 index 3e20491..0000000 --- a/chrome/app/theme/default_100_percent/legacy/info_small.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_100_percent/legacy/safebrowsing_warning.png b/chrome/app/theme/default_100_percent/legacy/safebrowsing_warning.png deleted file mode 100644 index ecd036f7..0000000 --- a/chrome/app/theme/default_100_percent/legacy/safebrowsing_warning.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_100_percent/legacy/translate.png b/chrome/app/theme/default_100_percent/legacy/translate.png deleted file mode 100644 index 1509e2e..0000000 --- a/chrome/app/theme/default_100_percent/legacy/translate.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_100_percent/mac/omnibox_keyword_hint_tab.png b/chrome/app/theme/default_100_percent/mac/omnibox_keyword_hint_tab.png deleted file mode 100644 index cdff3c0..0000000 --- a/chrome/app/theme/default_100_percent/mac/omnibox_keyword_hint_tab.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_100_percent/mac/overlay_drop_shadow.png b/chrome/app/theme/default_100_percent/mac/overlay_drop_shadow.png deleted file mode 100644 index 5192fa2c..0000000 --- a/chrome/app/theme/default_100_percent/mac/overlay_drop_shadow.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_100_percent/mac/tab_active_center.png b/chrome/app/theme/default_100_percent/mac/tab_active_center.png deleted file mode 100644 index 0b16854e..0000000 --- a/chrome/app/theme/default_100_percent/mac/tab_active_center.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_100_percent/mac/tab_active_left.png b/chrome/app/theme/default_100_percent/mac/tab_active_left.png deleted file mode 100644 index d0b8cd7b..0000000 --- a/chrome/app/theme/default_100_percent/mac/tab_active_left.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_100_percent/mac/tab_active_right.png b/chrome/app/theme/default_100_percent/mac/tab_active_right.png deleted file mode 100644 index 0f467fde..0000000 --- a/chrome/app/theme/default_100_percent/mac/tab_active_right.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_100_percent/mac/tab_alpha_left.png b/chrome/app/theme/default_100_percent/mac/tab_alpha_left.png deleted file mode 100644 index cd4913c..0000000 --- a/chrome/app/theme/default_100_percent/mac/tab_alpha_left.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_100_percent/mac/tab_alpha_right.png b/chrome/app/theme/default_100_percent/mac/tab_alpha_right.png deleted file mode 100644 index 510c396..0000000 --- a/chrome/app/theme/default_100_percent/mac/tab_alpha_right.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_100_percent/mac/toolbar_shade_top.png b/chrome/app/theme/default_100_percent/mac/toolbar_shade_top.png deleted file mode 100644 index 5673ead..0000000 --- a/chrome/app/theme/default_100_percent/mac/toolbar_shade_top.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/legacy/avatar_menu_auth_error.png b/chrome/app/theme/default_200_percent/legacy/avatar_menu_auth_error.png deleted file mode 100644 index 4d4d03d..0000000 --- a/chrome/app/theme/default_200_percent/legacy/avatar_menu_auth_error.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/legacy/info_small.png b/chrome/app/theme/default_200_percent/legacy/info_small.png deleted file mode 100644 index d7852d9..0000000 --- a/chrome/app/theme/default_200_percent/legacy/info_small.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/legacy/safebrowsing_warning.png b/chrome/app/theme/default_200_percent/legacy/safebrowsing_warning.png deleted file mode 100644 index 0fdc86d..0000000 --- a/chrome/app/theme/default_200_percent/legacy/safebrowsing_warning.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/legacy/translate.png b/chrome/app/theme/default_200_percent/legacy/translate.png deleted file mode 100644 index 03428f13..0000000 --- a/chrome/app/theme/default_200_percent/legacy/translate.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/mac/omnibox_keyword_hint_tab.png b/chrome/app/theme/default_200_percent/mac/omnibox_keyword_hint_tab.png deleted file mode 100644 index 966d546..0000000 --- a/chrome/app/theme/default_200_percent/mac/omnibox_keyword_hint_tab.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/mac/overlay_drop_shadow.png b/chrome/app/theme/default_200_percent/mac/overlay_drop_shadow.png deleted file mode 100644 index c82089d0..0000000 --- a/chrome/app/theme/default_200_percent/mac/overlay_drop_shadow.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/mac/tab_active_center.png b/chrome/app/theme/default_200_percent/mac/tab_active_center.png deleted file mode 100644 index d888b04..0000000 --- a/chrome/app/theme/default_200_percent/mac/tab_active_center.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/mac/tab_active_left.png b/chrome/app/theme/default_200_percent/mac/tab_active_left.png deleted file mode 100644 index 7ef21e96..0000000 --- a/chrome/app/theme/default_200_percent/mac/tab_active_left.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/mac/tab_active_right.png b/chrome/app/theme/default_200_percent/mac/tab_active_right.png deleted file mode 100644 index f77638d..0000000 --- a/chrome/app/theme/default_200_percent/mac/tab_active_right.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/mac/tab_alpha_left.png b/chrome/app/theme/default_200_percent/mac/tab_alpha_left.png deleted file mode 100644 index 33710b59..0000000 --- a/chrome/app/theme/default_200_percent/mac/tab_alpha_left.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/mac/tab_alpha_right.png b/chrome/app/theme/default_200_percent/mac/tab_alpha_right.png deleted file mode 100644 index c92327c..0000000 --- a/chrome/app/theme/default_200_percent/mac/tab_alpha_right.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/default_200_percent/mac/toolbar_shade_top.png b/chrome/app/theme/default_200_percent/mac/toolbar_shade_top.png deleted file mode 100644 index 26f434e..0000000 --- a/chrome/app/theme/default_200_percent/mac/toolbar_shade_top.png +++ /dev/null Binary files differ
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index 826ec91..6c3c1012 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd
@@ -154,9 +154,6 @@ <structure type="chrome_scaled_image" name="IDR_HIDE_PASSWORD" file="cros/hide_password.png" /> </if> <structure type="chrome_scaled_image" name="IDR_HIDE_PASSWORD_HOVER" file="common/hide_password_hover.png" /> - <if expr="is_macosx"> - <structure type="chrome_scaled_image" name="IDR_ICON_PROFILES_ACCOUNT_BUTTON_ERROR" file="legacy/avatar_menu_auth_error.png" /> - </if> <if expr="not is_android and not chromeos"> <!-- User Manager tutorial --> <structure type="chrome_scaled_image" name="IDR_ICON_USER_MANAGER_TUTORIAL_YOUR_CHROME" file="common/user_manager_tutorial/your_chrome.png" /> @@ -164,9 +161,6 @@ <structure type="chrome_scaled_image" name="IDR_ICON_USER_MANAGER_TUTORIAL_FRIENDS" file="common/user_manager_tutorial/family_and_friends.png" /> <structure type="chrome_scaled_image" name="IDR_ICON_USER_MANAGER_TUTORIAL_COMPLETE" file="common/user_manager_tutorial/complete.png" /> </if> - <if expr="is_macosx"> - <structure type="chrome_scaled_image" name="IDR_INFO" file="legacy/info_small.png" /> - </if> <structure type="chrome_scaled_image" name="IDR_INFOBAR_3D_BLOCKED" file="common/infobar_3d_blocked.png" /> <structure type="chrome_scaled_image" name="IDR_INPUT_ALERT" file="common/input_alert.png" /> <structure type="chrome_scaled_image" name="IDR_INPUT_ALERT_MENU" file="common/input_alert_menu.png" /> @@ -204,10 +198,6 @@ <structure type="chrome_scaled_image" name="IDR_OMNIBOX_CALCULATOR_ROUND" file="chromium/calculator_round_24.png" /> <structure type="chrome_scaled_image" name="IDR_OMNIBOX_TRANSLATION_ROUND" file="chromium/translate_round_32.png" /> </if> - <if expr="is_macosx"> - <structure type="chrome_scaled_image" name="IDR_OVERLAY_DROP_SHADOW" file="mac/overlay_drop_shadow.png" /> - <structure type="chrome_scaled_image" name="IDR_OMNIBOX_KEYWORD_HINT_TAB" file="mac/omnibox_keyword_hint_tab.png" /> - </if> <structure type="chrome_scaled_image" name="IDR_PLUGINS_FAVICON" file="common/favicon_extensions.png" /> <structure type="chrome_scaled_image" name="IDR_PRERENDER" file="common/prerender_succeed_icon.png" /> <if expr="chromeos"> @@ -357,9 +347,6 @@ <structure type="chrome_scaled_image" name="IDR_RESET_WARNING" file="cros/reset_warning.png" /> </if> <structure type="chrome_scaled_image" name="IDR_RESTORE_BUTTON_MASK" file="common/restore_button_mask.png" /> - <if expr="is_macosx"> - <structure type="chrome_scaled_image" name="IDR_SAFEBROWSING_WARNING" file="legacy/safebrowsing_warning.png" /> - </if> <structure type="chrome_scaled_image" name="IDR_SCREEN_CAPTURE_NOTIFICATION_GRIP" file="screen_capture_notification_grip.png" /> <structure type="chrome_scaled_image" name="IDR_SCREENSHOT_NOTIFICATION_ICON" file="common/notification_screenshot_icon.png" /> <if expr="chromeos"> @@ -379,11 +366,6 @@ </if> <structure type="chrome_scaled_image" name="IDR_SUPERVISED_USER_PLACEHOLDER" file="common/supervised_user_placeholder.png" /> <if expr="is_macosx"> - <structure type="chrome_scaled_image" name="IDR_TAB_ACTIVE_CENTER" file="mac/tab_active_center.png" /> - <structure type="chrome_scaled_image" name="IDR_TAB_ACTIVE_LEFT" file="mac/tab_active_left.png" /> - <structure type="chrome_scaled_image" name="IDR_TAB_ACTIVE_RIGHT" file="mac/tab_active_right.png" /> - <structure type="chrome_scaled_image" name="IDR_TAB_ALPHA_LEFT" file="mac/tab_alpha_left.png" /> - <structure type="chrome_scaled_image" name="IDR_TAB_ALPHA_RIGHT" file="mac/tab_alpha_right.png" /> <structure type="chrome_scaled_image" name="IDR_SWIPE_BACK" file="mac/back_large.png" /> <structure type="chrome_scaled_image" name="IDR_SWIPE_FORWARD" file="mac/forward_large.png" /> </if> @@ -393,9 +375,11 @@ <structure type="chrome_scaled_image" name="IDR_CLOSE_1" file="common/close_1.png" /> <structure type="chrome_scaled_image" name="IDR_CLOSE_1_H" file="common/close_1_hover.png" /> <structure type="chrome_scaled_image" name="IDR_CLOSE_1_P" file="common/close_1_pressed.png" /> - <!-- Used by Mac OSX, and Chrome OS login pages. --> - <structure type="chrome_scaled_image" name="IDR_TAB_RECORDING_INDICATOR" file="legacy/tab_recording_indicator.png" /> + <!-- Used by Chrome OS login page. --> + <if expr="chromeos"> + <structure type="chrome_scaled_image" name="IDR_TAB_RECORDING_INDICATOR" file="legacy/tab_recording_indicator.png" /> + </if> <structure type="chrome_scaled_image" name="IDR_TAB_DROP_DOWN" file="tab_drop_down.png" /> <structure type="chrome_scaled_image" name="IDR_TAB_DROP_UP" file="tab_drop_up.png" /> <if expr="chromeos"> @@ -436,12 +420,6 @@ </if> <!-- Instant Extended API toolbar background is common for all platforms. --> <structure type="chrome_scaled_image" name="IDR_THEME_WINDOW_CONTROL_BACKGROUND" file="notused.png" /> - <if expr="is_macosx"> - <structure type="chrome_scaled_image" name="IDR_TOOLBAR_SHADE_TOP" file="mac/toolbar_shade_top.png" /> - </if> - <if expr="is_macosx"> - <structure type="chrome_scaled_image" name="IDR_TRANSLATE" file="legacy/translate.png" /> - </if> <structure type="chrome_scaled_image" name="IDR_TRANSLATE_BUBBLE_ICON" file="common/translate_bubble_icon.png" /> <if expr="chromeos"> <structure type="chrome_scaled_image" name="IDR_USER_IMAGE_CAPTURE" file="cros/snapshot_wide.png" />
diff --git a/chrome/browser/android/explore_sites/explore_sites_fetcher.cc b/chrome/browser/android/explore_sites/explore_sites_fetcher.cc index bd85aec..1897421 100644 --- a/chrome/browser/android/explore_sites/explore_sites_fetcher.cc +++ b/chrome/browser/android/explore_sites/explore_sites_fetcher.cc
@@ -41,7 +41,7 @@ // Content type needed in order to communicate with the server in binary // proto format. const char kRequestContentType[] = "application/x-protobuf"; -const char kRequestMethod[] = "POST"; +const char kRequestMethod[] = "GET"; constexpr net::NetworkTrafficAnnotationTag traffic_annotation = net::DefineNetworkTrafficAnnotation("explore_sites", R"( @@ -102,26 +102,26 @@ version.components()[2], // Build version.components()[3], // Patch channel_name.c_str()); + GURL final_url = + net::AppendOrReplaceQueryParameter(url, "country_code", country_code); + final_url = net::AppendOrReplaceQueryParameter(final_url, "version_token", + catalog_version); + auto resource_request = std::make_unique<network::ResourceRequest>(); + resource_request->url = final_url; resource_request->method = kRequestMethod; bool is_stable_channel = chrome::GetChannel() == version_info::Channel::STABLE; std::string api_key = is_stable_channel ? google_apis::GetAPIKey() : google_apis::GetNonStableAPIKey(); - resource_request->headers.SetHeader("x-google-api-key", api_key); + resource_request->headers.SetHeader("x-goog-api-key", api_key); resource_request->headers.SetHeader("X-Client-Version", client_version); + resource_request->headers.SetHeader("Content-Type", kRequestContentType); // TODO(freedjm): Implement Accept-Language support. url_loader_ = network::SimpleURLLoader::Create(std::move(resource_request), traffic_annotation); - GetCatalogRequest request; - request.set_version_token(catalog_version); - request.set_country_code(country_code); - std::string request_message; - request.SerializeToString(&request_message); - url_loader_->AttachStringForUpload(request_message, kRequestContentType); - url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie( url_loader_factory_.get(), base::BindOnce(&ExploreSitesFetcher::OnSimpleLoaderComplete,
diff --git a/chrome/browser/android/explore_sites/explore_sites_fetcher_unittest.cc b/chrome/browser/android/explore_sites/explore_sites_fetcher_unittest.cc index a799c93..414e466 100644 --- a/chrome/browser/android/explore_sites/explore_sites_fetcher_unittest.cc +++ b/chrome/browser/android/explore_sites/explore_sites_fetcher_unittest.cc
@@ -38,6 +38,8 @@ ExploreSitesRequestStatus RunFetcherWithData(const std::string& response_data, std::string* data_received); + network::ResourceRequest last_resource_request; + private: ExploreSitesFetcher::Callback StoreResult(); network::TestURLLoaderFactory::PendingRequest* GetPendingRequest( @@ -52,7 +54,6 @@ network::TestURLLoaderFactory test_url_loader_factory_; scoped_refptr<network::SharedURLLoaderFactory> test_shared_url_loader_factory_; - network::ResourceRequest last_resource_request_; ExploreSitesRequestStatus last_status_; std::unique_ptr<std::string> last_data_; @@ -79,7 +80,8 @@ void ExploreSitesFetcherTest::SetUp() { test_url_loader_factory_.SetInterceptor( base::BindLambdaForTesting([&](const network::ResourceRequest& request) { - last_resource_request_ = request; + EXPECT_TRUE(request.url.is_valid() && !request.url.is_empty()); + last_resource_request = request; })); } @@ -153,7 +155,7 @@ base::OnceCallback<void(void)> respond_callback, std::string* data_received) { std::unique_ptr<ExploreSitesFetcher> fetcher = - ExploreSitesFetcher::CreateForGetCatalog(StoreResult(), "", "KE", + ExploreSitesFetcher::CreateForGetCatalog(StoreResult(), "123", "KE", test_shared_url_loader_factory_); std::move(respond_callback).Run(); @@ -215,6 +217,10 @@ RunFetcherWithData("Any data.", &data)); EXPECT_FALSE(data.empty()); EXPECT_EQ(data, "Any data."); + + EXPECT_EQ(last_resource_request.url.spec(), + "https://exploresites-pa.googleapis.com/v1/" + "getcatalog?country_code=KE&version_token=123"); } } // namespace explore_sites
diff --git a/chrome/browser/android/explore_sites/url_util.cc b/chrome/browser/android/explore_sites/url_util.cc index 8fa815bb..fc2947c 100644 --- a/chrome/browser/android/explore_sites/url_util.cc +++ b/chrome/browser/android/explore_sites/url_util.cc
@@ -14,7 +14,7 @@ GURL GetBaseURL() { const char kBaseURLOption[] = "base_url"; - const char kDefaultBaseUrl[] = "https://exploresites-pa.googleapis.com/v1"; + const char kDefaultBaseUrl[] = "https://exploresites-pa.googleapis.com"; std::string field_trial_param = base::GetFieldTrialParamValueByFeature( chrome::android::kExploreSites, kBaseURLOption); if (field_trial_param.empty()) @@ -23,7 +23,7 @@ } GURL GetCatalogURL() { - const char kGetCatalogPath[] = "/getcatalog"; + const char kGetCatalogPath[] = "/v1/getcatalog"; std::string path(kGetCatalogPath); GURL base_url(GetBaseURL()); @@ -33,7 +33,7 @@ } GURL GetCategoriesURL() { - const char kNtpJsonPath[] = "/getcategories"; + const char kNtpJsonPath[] = "/v1/getcategories"; std::string path(kNtpJsonPath); GURL base_url(GetBaseURL());
diff --git a/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.cc b/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.cc index be09fde..c6601c79 100644 --- a/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.cc +++ b/chrome/browser/android/oom_intervention/oom_intervention_tab_helper.cc
@@ -81,6 +81,14 @@ config->is_navigate_ads_enabled()) { NearOomReductionInfoBar::Show(web_contents(), this); intervention_state_ = InterventionState::UI_SHOWN; + if (!last_navigation_timestamp_.is_null()) { + base::TimeDelta time_since_last_navigation = + base::TimeTicks::Now() - last_navigation_timestamp_; + UMA_HISTOGRAM_COUNTS_1M( + "Memory.Experimental.OomIntervention." + "RendererTimeSinceLastNavigationAtIntervention", + time_since_last_navigation.InSeconds()); + } } near_oom_detected_time_ = base::TimeTicks::Now(); renderer_detection_timer_.AbandonAndStop(); @@ -292,6 +300,8 @@ } } + if (!renderer_pause_enabled && !navigate_ads_enabled) + return; content::RenderFrameHost* main_frame = web_contents()->GetMainFrame(); DCHECK(main_frame); content::RenderProcessHost* render_process_host = main_frame->GetProcess();
diff --git a/chrome/browser/bookmarks/managed_bookmark_service_unittest.cc b/chrome/browser/bookmarks/managed_bookmark_service_unittest.cc index 701d2d2..f27e228 100644 --- a/chrome/browser/bookmarks/managed_bookmark_service_unittest.cc +++ b/chrome/browser/bookmarks/managed_bookmark_service_unittest.cc
@@ -35,6 +35,28 @@ using testing::Mock; using testing::_; +TEST(ManagedBookmarkServiceNoPolicyTest, EmptyManagedNode) { + // Verifies that the managed node is empty and invisible when the policy is + // not set. + content::TestBrowserThreadBundle thread_bundle; + TestingProfile profile; + + // Make sure the policy isn't set. + ASSERT_EQ(nullptr, profile.GetTestingPrefService()->GetManagedPref( + bookmarks::prefs::kManagedBookmarks)); + + profile.CreateBookmarkModel(false); + BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(&profile); + bookmarks::test::WaitForBookmarkModelToLoad(model); + ManagedBookmarkService* managed = + ManagedBookmarkServiceFactory::GetForProfile(&profile); + DCHECK(managed); + + ASSERT_TRUE(managed->managed_node()); + EXPECT_TRUE(managed->managed_node()->empty()); + EXPECT_FALSE(managed->managed_node()->IsVisible()); +} + class ManagedBookmarkServiceTest : public testing::Test { public: ManagedBookmarkServiceTest() : managed_(NULL), model_(NULL) {} @@ -47,7 +69,14 @@ // TODO(crbug.com/697817): Convert SetManagedPrefs to take a unique_ptr. prefs_->SetManagedPref(bookmarks::prefs::kManagedBookmarks, CreateTestTree()); - ResetModel(); + + // Create and load the bookmark model. + profile_.CreateBookmarkModel(false); + model_ = BookmarkModelFactory::GetForBrowserContext(&profile_); + bookmarks::test::WaitForBookmarkModelToLoad(model_); + model_->AddObserver(&observer_); + managed_ = ManagedBookmarkServiceFactory::GetForProfile(&profile_); + DCHECK(managed_); // The managed node always exists. ASSERT_TRUE(managed_->managed_node()); @@ -57,15 +86,6 @@ void TearDown() override { model_->RemoveObserver(&observer_); } - void ResetModel() { - profile_.CreateBookmarkModel(false); - model_ = BookmarkModelFactory::GetForBrowserContext(&profile_); - bookmarks::test::WaitForBookmarkModelToLoad(model_); - model_->AddObserver(&observer_); - managed_ = ManagedBookmarkServiceFactory::GetForProfile(&profile_); - DCHECK(managed_); - } - static std::unique_ptr<base::DictionaryValue> CreateBookmark( const std::string& title, const std::string& url) { @@ -145,18 +165,6 @@ DISALLOW_COPY_AND_ASSIGN(ManagedBookmarkServiceTest); }; -TEST_F(ManagedBookmarkServiceTest, EmptyManagedNode) { - // Verifies that the managed node is empty and invisible when the policy is - // not set. - model_->RemoveObserver(&observer_); - prefs_->RemoveManagedPref(bookmarks::prefs::kManagedBookmarks); - ResetModel(); - - ASSERT_TRUE(managed_->managed_node()); - EXPECT_TRUE(managed_->managed_node()->empty()); - EXPECT_FALSE(managed_->managed_node()->IsVisible()); -} - TEST_F(ManagedBookmarkServiceTest, LoadInitial) { // Verifies that the initial load picks up the initial policy too. EXPECT_TRUE(model_->bookmark_bar_node()->empty());
diff --git a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc index 3f2f90f..690b3334 100644 --- a/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc +++ b/chrome/browser/chromeos/extensions/file_manager/private_api_drive.cc
@@ -623,12 +623,11 @@ } drivefs_interface->GetMetadata( - path, /* want_thumbnail = */ false, - mojo::WrapCallbackWithDefaultInvokeIfNotRun( - base::BindOnce( - &SingleEntryPropertiesGetterForDriveFs::OnGetFileInfo, - weak_ptr_factory_.GetWeakPtr()), - drive::FILE_ERROR_SERVICE_UNAVAILABLE, nullptr)); + path, mojo::WrapCallbackWithDefaultInvokeIfNotRun( + base::BindOnce( + &SingleEntryPropertiesGetterForDriveFs::OnGetFileInfo, + weak_ptr_factory_.GetWeakPtr()), + drive::FILE_ERROR_SERVICE_UNAVAILABLE, nullptr)); } void OnGetFileInfo(drive::FileError error, @@ -1621,7 +1620,7 @@ return false; drivefs_interface->GetMetadata( - path, false, + path, mojo::WrapCallbackWithDefaultInvokeIfNotRun( base::BindOnce( &FileManagerPrivateInternalGetDownloadUrlFunction::OnGotMetadata,
diff --git a/chrome/browser/chromeos/file_manager/open_with_browser.cc b/chrome/browser/chromeos/file_manager/open_with_browser.cc index 254572f..6a85f71d 100644 --- a/chrome/browser/chromeos/file_manager/open_with_browser.cc +++ b/chrome/browser/chromeos/file_manager/open_with_browser.cc
@@ -193,8 +193,7 @@ integration_service->GetDriveFsInterface() && integration_service->GetRelativeDrivePath(file_path, &path)) { integration_service->GetDriveFsInterface()->GetMetadata( - path, false, - base::BindOnce(&OpenHostedDriveFsFile, file_path, profile)); + path, base::BindOnce(&OpenHostedDriveFsFile, file_path, profile)); return true; } OpenGDocUrlFromFile(file_path, profile);
diff --git a/chrome/browser/chromeos/file_system_provider/operations/get_metadata.cc b/chrome/browser/chromeos/file_system_provider/operations/get_metadata.cc index 73acae8..011f126 100644 --- a/chrome/browser/chromeos/file_system_provider/operations/get_metadata.cc +++ b/chrome/browser/chromeos/file_system_provider/operations/get_metadata.cc
@@ -142,7 +142,9 @@ : Operation(event_router, file_system_info), entry_path_(entry_path), fields_(fields), - callback_(std::move(callback)) {} + callback_(std::move(callback)) { + DCHECK_NE(0, fields_); +} GetMetadata::~GetMetadata() { }
diff --git a/chrome/browser/chromeos/login/lock/screen_locker.cc b/chrome/browser/chromeos/login/lock/screen_locker.cc index e6da0b7..e7fc1e2 100644 --- a/chrome/browser/chromeos/login/lock/screen_locker.cc +++ b/chrome/browser/chromeos/login/lock/screen_locker.cc
@@ -395,6 +395,15 @@ void ScreenLocker::OnPinAttemptDone(const UserContext& user_context, bool success) { if (success) { + // Mark strong auth if this is cryptohome based pin. + if (quick_unlock::PinBackend::GetInstance()->ShouldUseCryptohome( + user_context.GetAccountId())) { + quick_unlock::QuickUnlockStorage* quick_unlock_storage = + quick_unlock::QuickUnlockFactory::GetForAccountId( + user_context.GetAccountId()); + if (quick_unlock_storage) + quick_unlock_storage->MarkStrongAuth(); + } OnAuthSuccess(user_context); } else { // PIN authentication has failed; try submitting as a normal password. @@ -672,6 +681,10 @@ } else { VLOG(1) << "Fingerprint is not available on lock screen"; } + + UpdateFingerprintState( + "ScreenLockReady", + user_manager::UserManager::Get()->GetPrimaryUser()->GetAccountId()); } bool ScreenLocker::IsUserLoggedIn(const AccountId& account_id) const { @@ -756,4 +769,46 @@ } } +void ScreenLocker::UpdateFingerprintState(const std::string& source, + const AccountId& account_id) { + VLOG(1) << "Updating fingerprint state (source=" << source << ")"; + update_fingerprint_state_timer_.Stop(); + quick_unlock::QuickUnlockStorage* quick_unlock_storage = + quick_unlock::QuickUnlockFactory::GetForAccountId(account_id); + + // If strong auth is required, disable fingerprint. + if (quick_unlock_storage && !quick_unlock_storage->HasStrongAuth() && + quick_unlock_storage->fingerprint_storage()->IsFingerprintAvailable()) { + VLOG(1) << "Require strong auth to make fingerprint unlock available."; + delegate_->SetFingerprintState(account_id, FingerprintState::kTimeout); + + // Prefs based pin will be unavailable when strong auth is required. + quick_unlock::PinBackend::GetInstance()->CanAuthenticate( + account_id, base::BindOnce(&ScreenLocker::OnPinCanAuthenticate, + weak_factory_.GetWeakPtr(), account_id)); + return; + } + + // If fingerprint is available, call this function again when strong auth + // will expire. + if (quick_unlock_storage && + quick_unlock_storage->IsFingerprintAuthenticationAvailable()) { + const base::TimeDelta next_strong_auth = + quick_unlock_storage->TimeUntilNextStrongAuth(); + VLOG(1) << "Scheduling next fingerprint state update in " + << next_strong_auth; + update_fingerprint_state_timer_.Start( + FROM_HERE, next_strong_auth, + base::BindOnce(&ScreenLocker::UpdateFingerprintState, + base::Unretained(this), + "update_fingerprint_state_timer_", account_id)); + } +} + +void ScreenLocker::OnPinCanAuthenticate(const AccountId& account_id, + bool can_authenticate) { + LoginScreenClient::Get()->login_screen()->SetPinEnabledForUser( + account_id, can_authenticate); +} + } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/lock/screen_locker.h b/chrome/browser/chromeos/login/lock/screen_locker.h index 8bc125f..a366a2cd 100644 --- a/chrome/browser/chromeos/login/lock/screen_locker.h +++ b/chrome/browser/chromeos/login/lock/screen_locker.h
@@ -55,6 +55,7 @@ kSignin, kFailed, kRemoved, + kTimeout, }; // Delegate used to send internal state changes back to the UI. @@ -242,6 +243,11 @@ // check has completed. void ContinueAuthenticate(const UserContext& user_context); + void UpdateFingerprintState(const std::string& source, + const AccountId& account_id); + + void OnPinCanAuthenticate(const AccountId& account_id, bool can_authenticate); + // WebUIScreenLocker instance in use. std::unique_ptr<WebUIScreenLocker> web_ui_; @@ -300,6 +306,10 @@ // ViewsScreenLocker instance in use. std::unique_ptr<ViewsScreenLocker> views_screen_locker_; + // Password is required every 24 hours in order to use fingerprint unlock. + // This is used to update fingerprint state when password is required. + base::OneShotTimer update_fingerprint_state_timer_; + base::WeakPtrFactory<ScreenLocker> weak_factory_; DISALLOW_COPY_AND_ASSIGN(ScreenLocker);
diff --git a/chrome/browser/chromeos/login/lock/views_screen_locker.cc b/chrome/browser/chromeos/login/lock/views_screen_locker.cc index 12ba587..6d7f143 100644 --- a/chrome/browser/chromeos/login/lock/views_screen_locker.cc +++ b/chrome/browser/chromeos/login/lock/views_screen_locker.cc
@@ -52,6 +52,8 @@ return ash::mojom::FingerprintUnlockState::AUTH_FAILED; case ScreenLocker::FingerprintState::kRemoved: return ash::mojom::FingerprintUnlockState::AUTH_DISABLED; + case ScreenLocker::FingerprintState::kTimeout: + return ash::mojom::FingerprintUnlockState::AUTH_DISABLED_FROM_TIMEOUT; } }
diff --git a/chrome/browser/chromeos/login/quick_unlock/fingerprint_storage.cc b/chrome/browser/chromeos/login/quick_unlock/fingerprint_storage.cc index 1f0294f9..5ae52e9 100644 --- a/chrome/browser/chromeos/login/quick_unlock/fingerprint_storage.cc +++ b/chrome/browser/chromeos/login/quick_unlock/fingerprint_storage.cc
@@ -22,7 +22,7 @@ FingerprintStorage::~FingerprintStorage() {} -bool FingerprintStorage::IsFingerprintAuthenticationAvailable() const { +bool FingerprintStorage::IsFingerprintAvailable() const { return !ExceededUnlockAttempts() && IsFingerprintEnabled() && HasRecord(); }
diff --git a/chrome/browser/chromeos/login/quick_unlock/fingerprint_storage.h b/chrome/browser/chromeos/login/quick_unlock/fingerprint_storage.h index 9f70550..6a4c447 100644 --- a/chrome/browser/chromeos/login/quick_unlock/fingerprint_storage.h +++ b/chrome/browser/chromeos/login/quick_unlock/fingerprint_storage.h
@@ -28,6 +28,10 @@ explicit FingerprintStorage(PrefService* pref_service); ~FingerprintStorage(); + // Returns true if fingerprint unlock is currently available. + // This does not check if strong auth is available. + bool IsFingerprintAvailable() const; + // Returns true if the user has fingerprint record registered. bool HasRecord() const; @@ -46,9 +50,6 @@ friend class chromeos::FingerprintStorageTestApi; friend class QuickUnlockStorage; - // Returns true if fingerprint unlock is currently available. - bool IsFingerprintAuthenticationAvailable() const; - PrefService* pref_service_; // Number of fingerprint unlock attempt. int unlock_attempt_count_ = 0;
diff --git a/chrome/browser/chromeos/login/quick_unlock/fingerprint_storage_unittest.cc b/chrome/browser/chromeos/login/quick_unlock/fingerprint_storage_unittest.cc index 7306435..9023448 100644 --- a/chrome/browser/chromeos/login/quick_unlock/fingerprint_storage_unittest.cc +++ b/chrome/browser/chromeos/login/quick_unlock/fingerprint_storage_unittest.cc
@@ -46,8 +46,8 @@ quick_unlock::FingerprintStorage* fingerprint_storage) : fingerprint_storage_(fingerprint_storage) {} - bool IsFingerprintAuthenticationAvailable() const { - return fingerprint_storage_->IsFingerprintAuthenticationAvailable(); + bool IsFingerprintAvailable() const { + return fingerprint_storage_->IsFingerprintAvailable(); } private: @@ -90,14 +90,14 @@ EXPECT_TRUE(fingerprint_storage->HasRecord()); EXPECT_EQ(0, fingerprint_storage->unlock_attempt_count()); - EXPECT_TRUE(test_api.IsFingerprintAuthenticationAvailable()); + EXPECT_TRUE(test_api.IsFingerprintAvailable()); // No fingerprint records registered makes fingerprint authentication // unavailable. SetRecords(0); - EXPECT_FALSE(test_api.IsFingerprintAuthenticationAvailable()); + EXPECT_FALSE(test_api.IsFingerprintAvailable()); SetRecords(1); - EXPECT_TRUE(test_api.IsFingerprintAuthenticationAvailable()); + EXPECT_TRUE(test_api.IsFingerprintAvailable()); // Too many authentication attempts make fingerprint authentication // unavailable. @@ -105,9 +105,9 @@ ++i) { fingerprint_storage->AddUnlockAttempt(); } - EXPECT_FALSE(test_api.IsFingerprintAuthenticationAvailable()); + EXPECT_FALSE(test_api.IsFingerprintAvailable()); fingerprint_storage->ResetUnlockAttemptCount(); - EXPECT_TRUE(test_api.IsFingerprintAuthenticationAvailable()); + EXPECT_TRUE(test_api.IsFingerprintAvailable()); } } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/quick_unlock/pin_backend.cc b/chrome/browser/chromeos/login/quick_unlock/pin_backend.cc index e093c451..eb5476b 100644 --- a/chrome/browser/chromeos/login/quick_unlock/pin_backend.cc +++ b/chrome/browser/chromeos/login/quick_unlock/pin_backend.cc
@@ -258,6 +258,17 @@ } } +bool PinBackend::ShouldUseCryptohome(const AccountId& account_id) { + if (!cryptohome_backend_) + return false; + + // Even if cryptohome is supported, the user may have registered a PIN with + // the prefs backend from a previous version. If that's the case, we should + // talk to the prefs backend instead of the cryptohome backend. + QuickUnlockStorage* storage = GetPrefsBackend(account_id); + return !storage || !storage->pin_storage_prefs()->IsPinSet(); +} + void PinBackend::OnIsCryptohomeBackendSupported(bool is_supported) { if (is_supported) cryptohome_backend_ = std::make_unique<PinStorageCryptohome>(); @@ -276,16 +287,5 @@ scoped_keep_alive_.reset(); } -bool PinBackend::ShouldUseCryptohome(const AccountId& account_id) { - if (!cryptohome_backend_) - return false; - - // Even if cryptohome is supported, the user may have registered a PIN with - // the prefs backend from a previous version. If that's the case, we should - // talk to the prefs backend instead of the cryptohome backend. - QuickUnlockStorage* storage = GetPrefsBackend(account_id); - return !storage || !storage->pin_storage_prefs()->IsPinSet(); -} - } // namespace quick_unlock } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/quick_unlock/pin_backend.h b/chrome/browser/chromeos/login/quick_unlock/pin_backend.h index 64152d8..a8209652 100644 --- a/chrome/browser/chromeos/login/quick_unlock/pin_backend.h +++ b/chrome/browser/chromeos/login/quick_unlock/pin_backend.h
@@ -72,6 +72,11 @@ const Key& key, BoolCallback result); + // Returns true if the cryptohome backend should be used. Sometimes the prefs + // backend should be used even when cryptohome is available, ie, when there is + // an non-migrated PIN key. + bool ShouldUseCryptohome(const AccountId& account_id); + // Resets any cached state for testing purposes. static void ResetForTesting(); @@ -83,11 +88,6 @@ // should be cleared from prefs. void OnPinMigrationAttemptComplete(Profile* profile, bool success); - // Returns true if the cryptohome backend should be used. Sometimes the prefs - // backend should be used even when cryptohome is available, ie, when there is - // an non-migrated PIN key. - bool ShouldUseCryptohome(const AccountId& account_id); - // True if still trying to determine which backend should be used. bool resolving_backend_ = true; // Determining if the device supports cryptohome-based keys requires an async
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 31eda8d..0fccbc4d 100644 --- a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_storage.cc +++ b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_storage.cc
@@ -14,6 +14,17 @@ namespace chromeos { namespace quick_unlock { +namespace { + +base::TimeDelta GetStrongAuthTimeout(PrefService* pref_service) { + PasswordConfirmationFrequency strong_auth_interval = + static_cast<PasswordConfirmationFrequency>( + pref_service->GetInteger(prefs::kQuickUnlockTimeout)); + return PasswordConfirmationFrequencyToTimeDelta(strong_auth_interval); +} + +} // namespace + QuickUnlockStorage::QuickUnlockStorage(PrefService* pref_service) : pref_service_(pref_service) { fingerprint_storage_ = std::make_unique<FingerprintStorage>(pref_service); @@ -31,15 +42,7 @@ bool QuickUnlockStorage::HasStrongAuth() const { if (last_strong_auth_.is_null()) return false; - - // PIN and fingerprint share the same timeout policy. - PasswordConfirmationFrequency strong_auth_interval = - static_cast<PasswordConfirmationFrequency>( - pref_service_->GetInteger(prefs::kQuickUnlockTimeout)); - base::TimeDelta strong_auth_timeout = - PasswordConfirmationFrequencyToTimeDelta(strong_auth_interval); - - return TimeSinceLastStrongAuth() < strong_auth_timeout; + return TimeSinceLastStrongAuth() < GetStrongAuthTimeout(pref_service_); } base::TimeDelta QuickUnlockStorage::TimeSinceLastStrongAuth() const { @@ -47,9 +50,13 @@ return base::TimeTicks::Now() - last_strong_auth_; } +base::TimeDelta QuickUnlockStorage::TimeUntilNextStrongAuth() const { + DCHECK(!last_strong_auth_.is_null()); + return GetStrongAuthTimeout(pref_service_) - TimeSinceLastStrongAuth(); +} + bool QuickUnlockStorage::IsFingerprintAuthenticationAvailable() const { - return HasStrongAuth() && - fingerprint_storage_->IsFingerprintAuthenticationAvailable(); + return HasStrongAuth() && fingerprint_storage_->IsFingerprintAvailable(); } bool QuickUnlockStorage::IsPinAuthenticationAvailable() 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 89327fc3..bb4cdfe0 100644 --- a/chrome/browser/chromeos/login/quick_unlock/quick_unlock_storage.h +++ b/chrome/browser/chromeos/login/quick_unlock/quick_unlock_storage.h
@@ -44,7 +44,12 @@ // called if HasStrongAuth returns false. base::TimeDelta TimeSinceLastStrongAuth() const; + // Returns the time until next strong authentication required. This should + // not be called if HasStrongAuth returns false. + base::TimeDelta TimeUntilNextStrongAuth() const; + // Returns true if fingerprint unlock is currently available. + // This checks whether there's fingerprint setup, as well as HasStrongAuth. bool IsFingerprintAuthenticationAvailable() const; // Returns true if PIN unlock is currently available.
diff --git a/chrome/browser/chromeos/power/auto_screen_brightness/brightness_monitor_impl_unittest.cc b/chrome/browser/chromeos/power/auto_screen_brightness/brightness_monitor_impl_unittest.cc index b9011a4..e0d600537 100644 --- a/chrome/browser/chromeos/power/auto_screen_brightness/brightness_monitor_impl_unittest.cc +++ b/chrome/browser/chromeos/power/auto_screen_brightness/brightness_monitor_impl_unittest.cc
@@ -10,6 +10,7 @@ #include "base/threading/sequenced_task_runner_handle.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/fake_power_manager_client.h" +#include "chromeos/dbus/power_manager/backlight.pb.h" #include "testing/gtest/include/gtest/gtest.h" namespace chromeos { @@ -81,9 +82,11 @@ // on fake power manager client. void SetUpBrightnessMonitor(double init_brightness) { if (init_brightness >= 0) { + power_manager::SetBacklightBrightnessRequest request; + request.set_percent(init_brightness); chromeos::DBusThreadManager::Get() ->GetPowerManagerClient() - ->SetScreenBrightnessPercent(init_brightness, true); + ->SetScreenBrightness(request); } monitor_ = BrightnessMonitorImpl::CreateForTesting(
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc index 9cb89ff..cda1e33 100644 --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -199,6 +199,10 @@ (*s_whitelist)[password_manager::prefs::kCredentialsEnableAutosignin] = settings_api::PrefType::PREF_TYPE_BOOLEAN; + // Privacy page + (*s_whitelist)[::prefs::kSigninAllowedOnNextStartup] = + settings_api::PrefType::PREF_TYPE_BOOLEAN; + // Sync and personalization page. (*s_whitelist)[::prefs::kSafeBrowsingEnabled] = settings_api::PrefType::PREF_TYPE_BOOLEAN;
diff --git a/chrome/browser/resources/chromeos/login/discover/discover_module_behavior.js b/chrome/browser/resources/chromeos/login/discover/discover_module_behavior.js index 340fa99..f527b09 100644 --- a/chrome/browser/resources/chromeos/login/discover/discover_module_behavior.js +++ b/chrome/browser/resources/chromeos/login/discover/discover_module_behavior.js
@@ -31,6 +31,11 @@ }, show: function() {}, + + updateLocalizedContent: function() { + // Pass to I18nBehavior. + this.i18nUpdateLocale(); + }, }; var DiscoverModuleBehavior =
diff --git a/chrome/browser/resources/chromeos/login/oobe.js b/chrome/browser/resources/chromeos/login/oobe.js index 93ebe419..fdb6bfa 100644 --- a/chrome/browser/resources/chromeos/login/oobe.js +++ b/chrome/browser/resources/chromeos/login/oobe.js
@@ -256,10 +256,8 @@ $('virtual-keyboard').checked = data.virtualKeyboardEnabled; // TODO(katie): Remove this when launching features in OOBE screen. - if (!data.enableExperimentalA11yFeatures) { - $('select-to-speak-row').setAttribute('hidden', true); + if (!data.enableExperimentalA11yFeatures) $('docked-magnifier-row').setAttribute('hidden', true); - } $('oobe-welcome-md').a11yStatus = data; },
diff --git a/chrome/browser/resources/chromeos/login/oobe_dialog.css b/chrome/browser/resources/chromeos/login/oobe_dialog.css index 0f68c186..7a24de2 100644 --- a/chrome/browser/resources/chromeos/login/oobe_dialog.css +++ b/chrome/browser/resources/chromeos/login/oobe_dialog.css
@@ -9,6 +9,7 @@ --subtitle-font-distance-to-baseline: 3px; --subtitle-line-height: 18px; --offline-gaia-dialog-width: 768px; + font-family: var(--oobe-default-font-family); } #header-container { @@ -36,7 +37,7 @@ } #oobe-subtitle ::slotted(*) { - color: var(--google-grey-900); + color: var(--google-grey-700); font-size: var(--subtitle-font-size); line-height: var(--subtitle-line-height); /* margin 12px = 32 - line-height
diff --git a/chrome/browser/resources/chromeos/login/oobe_dialog_host_behavior.js b/chrome/browser/resources/chromeos/login/oobe_dialog_host_behavior.js index 0a44337..643b702 100644 --- a/chrome/browser/resources/chromeos/login/oobe_dialog_host_behavior.js +++ b/chrome/browser/resources/chromeos/login/oobe_dialog_host_behavior.js
@@ -51,21 +51,15 @@ /** * Triggers updateLocalizedContent() for elements matched by |selector|. - * @param {string=} selector CSS selector (optional). + * @param {string} selector CSS selector (optional). */ propagateUpdateLocalizedContent: function(selector) { - if (!selector) - selector = 'oobe-dialog'; - var screens = Polymer.dom(this.root).querySelectorAll(selector); for (var i = 0; i < screens.length; ++i) { - screens[i].updateLocalizedContent(); + /** @type {{updateLocalizedContent: function()}}}*/ (screens[i]) + .updateLocalizedContent(); } }, - - updateLocalizedContent: function() { - this.propagateUpdateLocalizedContent(); - }, }; /**
diff --git a/chrome/browser/resources/chromeos/login/oobe_fonts.css b/chrome/browser/resources/chromeos/login/oobe_fonts.css index 1b59396..c4c7ce9 100644 --- a/chrome/browser/resources/chromeos/login/oobe_fonts.css +++ b/chrome/browser/resources/chromeos/login/oobe_fonts.css
@@ -4,5 +4,6 @@ :root { --oobe-button-font-family: "Google Sans", Roboto, sans-serif; + --oobe-default-font-family: Roboto, sans-serif; --oobe-title-font-family: "Google Sans", Roboto, sans-serif; }
diff --git a/chrome/browser/resources/chromeos/login/oobe_screen_eula.js b/chrome/browser/resources/chromeos/login/oobe_screen_eula.js index 93d6baa..ab7dca4 100644 --- a/chrome/browser/resources/chromeos/login/oobe_screen_eula.js +++ b/chrome/browser/resources/chromeos/login/oobe_screen_eula.js
@@ -191,7 +191,8 @@ var TERMS_URL = 'chrome://terms'; var loadBundledEula = function() { - WebViewHelper.loadUrlToWebview(webview, TERMS_URL); + WebViewHelper.loadUrlContentToWebView( + webview, TERMS_URL, WebViewHelper.ContentType.HTML); }; webview.addContentScripts([{
diff --git a/chrome/browser/resources/chromeos/login/oobe_welcome.html b/chrome/browser/resources/chromeos/login/oobe_welcome.html index fa9821b..ffca41e1 100644 --- a/chrome/browser/resources/chromeos/login/oobe_welcome.html +++ b/chrome/browser/resources/chromeos/login/oobe_welcome.html
@@ -180,8 +180,7 @@ on-change="onA11yOptionChanged_" chrome-message="enableSelectToSpeak" label-for-aria="[[i18nDynamic(locale, 'selectToSpeakOption')]]" - id="selectToSpeakOobeOption" - hidden="[[!a11yStatus.enableExperimentalA11yFeatures]]"> + id="selectToSpeakOobeOption"> <span slot="title"> [[i18nDynamic(locale, 'selectToSpeakOption')]] </span>
diff --git a/chrome/browser/resources/chromeos/login/screen_arc_terms_of_service.js b/chrome/browser/resources/chromeos/login/screen_arc_terms_of_service.js index 065eb57..f49daa12 100644 --- a/chrome/browser/resources/chromeos/login/screen_arc_terms_of_service.js +++ b/chrome/browser/resources/chromeos/login/screen_arc_terms_of_service.js
@@ -390,7 +390,14 @@ * @param {string} targetUrl URL to open. */ showUrlOverlay: function(targetUrl) { - $('arc-tos-overlay-webview').src = targetUrl; + var webView = $('arc-tos-overlay-webview'); + if (this.usingOfflineTerms_) { + const TERMS_URL = 'chrome://terms/arc/privacy_policy'; + WebViewHelper.loadUrlContentToWebView( + webView, TERMS_URL, WebViewHelper.ContentType.PDF); + } else { + webView.src = targetUrl; + } $('arc-tos-overlay-webview-container').classList.add('overlay-loading'); this.showOverlay('arc-overlay-url'); }, @@ -555,9 +562,10 @@ // If in demo mode fallback to offline Terms of Service copy. if (this.isDemoModeSetup_()) { this.usingOfflineTerms_ = true; - const TERMS_URL = 'chrome://terms/arc'; + const TERMS_URL = 'chrome://terms/arc/terms'; var webView = this.getElement_('arc-tos-view'); - WebViewHelper.loadUrlToWebview(webView, TERMS_URL); + WebViewHelper.loadUrlContentToWebView( + webView, TERMS_URL, WebViewHelper.ContentType.HTML); return; } this.showError_();
diff --git a/chrome/browser/resources/chromeos/login/web_view_helper.js b/chrome/browser/resources/chromeos/login/web_view_helper.js index 846eff7..47336de 100644 --- a/chrome/browser/resources/chromeos/login/web_view_helper.js +++ b/chrome/browser/resources/chromeos/login/web_view_helper.js
@@ -9,28 +9,43 @@ /** Web view helper shared between OOBE screens. */ class WebViewHelper { /** - * Loads text/html contents from the given url into the given webview. The - * content is loaded via XHR and is sent to webview via data url so that it - * is properly sandboxed. + * Loads content of the given url into the given web view. + * The content is loaded via XHR and is sent to web view via data url so that + * it is properly sandboxed. * - * @param {!WebView} webView web view element to host the text/html content. - * @param {string} url URL to load text/html from. + * @param {!WebView} webView web view element to host the content. + * @param {string} url URL to load the content from. + * @param {!ContentType} contentType type of the content to load. */ - static loadUrlToWebview(webView, url) { + static loadUrlContentToWebView(webView, url, contentType) { assert(webView.tagName === 'WEBVIEW'); const onError = function() { webView.src = 'about:blank'; }; - const setContents = function(contents) { - webView.src = - 'data:text/html;charset=utf-8,' + encodeURIComponent(contents); + /** + * Sets contents to web view. + * Prefixes data with appropriate scheme, MIME type and token. + * @param {string} data data string to set. + */ + const setContents = function(data) { + switch (contentType) { + case WebViewHelper.ContentType.HTML: + webView.src = + 'data:text/html;charset=utf-8,' + encodeURIComponent(data); + break; + case WebViewHelper.ContentType.PDF: + webView.src = 'data:application/pdf;base64,' + data; + break; + default: + assertNotReached('Unknown content type to load.'); + } }; var xhr = new XMLHttpRequest(); xhr.open('GET', url); - xhr.setRequestHeader('Accept', 'text/html'); + xhr.setRequestHeader('Accept', contentType); xhr.onreadystatechange = function() { if (xhr.readyState != XMLHttpRequest.DONE) return; @@ -39,12 +54,11 @@ return; } - var contentType = xhr.getResponseHeader('Content-Type'); - if (contentType && !contentType.includes('text/html')) { + var responseContentType = xhr.getResponseHeader('Content-Type'); + if (responseContentType && !responseContentType.includes(contentType)) { onError(); return; } - setContents(xhr.response); }; @@ -54,4 +68,15 @@ onError(); } } -} \ No newline at end of file +} + +/** + * Type of content to load into web view. + * @enum {string} + */ +WebViewHelper.ContentType = { + /** UTF-8 encoded text/html content type. */ + HTML: 'text/html', + /** Base64 encoded application/pdf content type. */ + PDF: 'application/pdf', +}; \ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup_dialog.html b/chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup_dialog.html index a1306f2b5..3ba9f86 100644 --- a/chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup_dialog.html +++ b/chrome/browser/resources/chromeos/multidevice_setup/multidevice_setup_dialog.html
@@ -2,12 +2,13 @@ <html dir="$i18n{textdirection}" lang="$i18n{language}"> <head> <meta charset="utf8"> - <title>$i18n{title}</title> <base href="chrome://multidevice-setup"> <style> html, body { + display: flex; height: 100%; + justify-content: center; margin: 0; overflow: hidden; width: 100%;
diff --git a/chrome/browser/resources/settings/downloads_page/add_smb_share_dialog.html b/chrome/browser/resources/settings/downloads_page/add_smb_share_dialog.html index 6c8c82a..5dab706 100644 --- a/chrome/browser/resources/settings/downloads_page/add_smb_share_dialog.html +++ b/chrome/browser/resources/settings/downloads_page/add_smb_share_dialog.html
@@ -19,11 +19,11 @@ cr-input { --cr-input-error-display: none; - width: var(--settings-input-max-width); } cr-searchable-drop-down { display: block; + --cr-searchable-drop-down-width: 472px; } cr-input:not(:last-child),
diff --git a/chrome/browser/resources/settings/people_page/people_page.html b/chrome/browser/resources/settings/people_page/people_page.html index 3e957d7..460ca31 100644 --- a/chrome/browser/resources/settings/people_page/people_page.html +++ b/chrome/browser/resources/settings/people_page/people_page.html
@@ -232,9 +232,6 @@ <if expr="not chromeos"> </template> <!-- if="[[!diceEnabled_]]" --> </if> - <div class="settings-box" hidden="[[syncStatus.signinAllowed]]"> - $i18n{syncDisabledByAdministrator} - </div> </template> <if expr="not chromeos">
diff --git a/chrome/browser/resources/settings/people_page/sync_account_control.html b/chrome/browser/resources/settings/people_page/sync_account_control.html index 4536883d..7726f002 100644 --- a/chrome/browser/resources/settings/people_page/sync_account_control.html +++ b/chrome/browser/resources/settings/people_page/sync_account_control.html
@@ -193,8 +193,7 @@ <paper-button id="sync-button" class="action-button" hidden="[[syncStatus.signedIn]]" on-click="onSyncButtonTap_" disabled="[[syncStatus.setupInProgress]]"> - [[getSubstituteLabel_( - '$i18nPolymer{syncAsName}', shownAccount_.givenName)]] + $i18n{peopleSignIn} </paper-button> <paper-button id="turn-off" class="secondary-button" hidden="[[!shouldShowTurnOffButton_(syncStatus.signedIn)]]"
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html index 6308bdf..d120aec94 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page.html +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -29,6 +29,9 @@ <link rel="import" href="../site_settings/zoom_levels.html"> <link rel="import" href="../site_settings_page/site_settings_page.html"> +<if expr="not chromeos"> +<link rel="import" href="chrome://resources/cr_elements/cr_toast/cr_toast.html"> +</if> <if expr="use_nss_certs"> <link rel="import" href="chrome://resources/cr_components/certificate_manager/certificate_manager.html"> </if> @@ -38,6 +41,18 @@ <dom-module id="settings-privacy-page"> <template> <style include="settings-shared"> +<if expr="not chromeos"> + #toast { + color: white; + left: 0; + z-index: 1; + } + + :host-context([dir='rtl']) #toast { + left: auto; + right: 0; + } +</if> </style> <template is="dom-if" if="[[showClearBrowsingDataDialog_]]" restamp> <settings-clear-browsing-data-dialog prefs="{{prefs}}" @@ -78,6 +93,14 @@ unified-consent-enabled="[[unifiedConsentEnabled_]]"> </settings-personalization-options> </template> +<if expr="not chromeos"> + <settings-toggle-button id="signinAllowedToggle" + pref="{{prefs.signin.allowed_on_next_startup}}" + label="$i18n{signinAllowedTitle}" + sub-label="$i18n{signinAllowedDescription}" + on-settings-boolean-control-change="onSigninAllowedChange_"> + </settings-toggle-button> +</if><!-- not chromeos --> <settings-toggle-button id="doNotTrack" pref="{{prefs.enable_do_not_track}}" label="$i18n{doNotTrack}" on-settings-boolean-control-change="onDoNotTrackChange_" @@ -557,6 +580,14 @@ </template> </template> </settings-animated-pages> +<if expr="not chromeos"> + <cr-toast id="toast" open="[[showRestart_]]"> + <div>$i18n{restartToApplyChanges}</div> + <paper-button on-click="onRestartTap_"> + $i18n{restart} + </paper-button> + </cr-toast> +</if> </template> <script src="privacy_page.js"></script> </dom-module>
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.js b/chrome/browser/resources/settings/privacy_page/privacy_page.js index 11f3265..e01cce4 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page.js +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.js
@@ -163,6 +163,11 @@ return loadTimeData.getBoolean('enableEphemeralFlashPermission'); }, }, + + // <if expr="not chromeos"> + /** @private */ + showRestart_: Boolean, + // </if> }, /** @override */ @@ -348,5 +353,19 @@ return value ? this.i18n('siteSettingsProtectedContentEnableIdentifiers') : this.i18n('siteSettingsBlocked'); }, + + /** @private */ + onSigninAllowedChange_: function() { + this.showRestart_ = true; + }, + + /** + * @param {!Event} e + * @private + */ + onRestartTap_: function(e) { + e.stopPropagation(); + settings.LifetimeBrowserProxyImpl.getInstance().restart(); + }, }); })();
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/landing_view.js b/chrome/browser/resources/welcome/onboarding_welcome/landing_view.js index f4eccbf..925b6fd 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/landing_view.js +++ b/chrome/browser/resources/welcome/onboarding_welcome/landing_view.js
@@ -9,7 +9,8 @@ /** @private */ onExistingUserClick_: function() { - welcome.WelcomeBrowserProxyImpl.getInstance().handleActivateSignIn(); + welcome.WelcomeBrowserProxyImpl.getInstance().handleActivateSignIn( + 'chrome://welcome/returning-user'); }, /** @private */
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/welcome_browser_proxy.js b/chrome/browser/resources/welcome/onboarding_welcome/welcome_browser_proxy.js index c8c64603..679fe655 100644 --- a/chrome/browser/resources/welcome/onboarding_welcome/welcome_browser_proxy.js +++ b/chrome/browser/resources/welcome/onboarding_welcome/welcome_browser_proxy.js
@@ -11,17 +11,16 @@ /** @interface */ class WelcomeBrowserProxy { - handleActivateSignIn() {} + /** @param {string} redirectUrl the URL to redirect to, after signing in. */ + handleActivateSignIn(redirectUrl) {} goToNewTabPage() {} } /** @implements {welcome.WelcomeBrowserProxy} */ class WelcomeBrowserProxyImpl { /** @override */ - handleActivateSignIn() { - // TODO(scottchen): add code to direct back to /welcome/returning-user - // after user finishes signing in. - chrome.send('handleActivateSignIn'); + handleActivateSignIn(redirectUrl) { + chrome.send('handleActivateSignIn', redirectUrl ? [redirectUrl] : []); } /** @override */
diff --git a/chrome/browser/signin/account_consistency_mode_manager.cc b/chrome/browser/signin/account_consistency_mode_manager.cc index d5e83452..91d136f 100644 --- a/chrome/browser/signin/account_consistency_mode_manager.cc +++ b/chrome/browser/signin/account_consistency_mode_manager.cc
@@ -12,6 +12,7 @@ #include "base/metrics/histogram_macros.h" #include "build/build_config.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/common/pref_names.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" #include "components/pref_registry/pref_registry_syncable.h" @@ -121,6 +122,21 @@ account_consistency_initialized_(false) { DCHECK(profile_); DCHECK(!profile_->IsOffTheRecord()); + + PrefService* prefs = profile->GetPrefs(); + bool signin_allowed = prefs->GetBoolean(prefs::kSigninAllowed); + if (prefs->IsUserModifiablePreference(prefs::kSigninAllowed)) { + // Propagate settings changes from the previous launch to the signin-allowed + // pref. + signin_allowed = prefs->GetBoolean(prefs::kSigninAllowedOnNextStartup); + prefs->SetBoolean(prefs::kSigninAllowed, signin_allowed); + } else { + // When the signin-allowed pref is not user-modifiable(e.g. managed), reset + // signin-allowed-on-next-startup. + prefs->SetBoolean(prefs::kSigninAllowedOnNextStartup, signin_allowed); + } + UMA_HISTOGRAM_BOOLEAN("Signin.SigninAllowed", signin_allowed); + account_consistency_ = ComputeAccountConsistencyMethod(profile_); #if BUILDFLAG(ENABLE_DICE_SUPPORT) @@ -160,6 +176,7 @@ registry->RegisterBooleanPref(prefs::kAccountConsistencyMirrorRequired, false); #endif + registry->RegisterBooleanPref(prefs::kSigninAllowedOnNextStartup, true); } // static @@ -285,6 +302,12 @@ return AccountConsistencyMethod::kDiceFixAuthErrors; } + if (!profile->GetPrefs()->GetBoolean(prefs::kSigninAllowed)) { + VLOG(1) << "Desktop Identity Consistency disabled as sign-in to Chrome" + "is not allowed"; + return AccountConsistencyMethod::kDiceFixAuthErrors; + } + if (method == AccountConsistencyMethod::kDiceMigration && profile->GetPrefs()->GetBoolean(kDiceMigrationCompletePref)) { return AccountConsistencyMethod::kDice;
diff --git a/chrome/browser/signin/account_consistency_mode_manager.h b/chrome/browser/signin/account_consistency_mode_manager.h index 6b2d67fb6..aeaa184 100644 --- a/chrome/browser/signin/account_consistency_mode_manager.h +++ b/chrome/browser/signin/account_consistency_mode_manager.h
@@ -73,6 +73,8 @@ private: FRIEND_TEST_ALL_PREFIXES(AccountConsistencyModeManagerTest, MigrateAtCreation); + FRIEND_TEST_ALL_PREFIXES(AccountConsistencyModeManagerTest, + SigninAllowedChangesDiceState); #if BUILDFLAG(ENABLE_DICE_SUPPORT) // Schedules migration to happen at next startup. Exposed as a static function
diff --git a/chrome/browser/signin/account_consistency_mode_manager_unittest.cc b/chrome/browser/signin/account_consistency_mode_manager_unittest.cc index 3a895e8..8cee2f64 100644 --- a/chrome/browser/signin/account_consistency_mode_manager_unittest.cc +++ b/chrome/browser/signin/account_consistency_mode_manager_unittest.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/prefs/browser_prefs.h" #include "chrome/browser/signin/scoped_account_consistency.h" #include "chrome/browser/supervised_user/supervised_user_constants.h" +#include "chrome/common/pref_names.h" #include "chrome/test/base/testing_profile.h" #include "components/prefs/pref_notifier_impl.h" #include "components/prefs/testing_pref_store.h" @@ -80,6 +81,43 @@ } #if BUILDFLAG(ENABLE_DICE_SUPPORT) +// Checks that changing the signin-allowed pref changes the Dice state on next +// startup. +TEST(AccountConsistencyModeManagerTest, SigninAllowedChangesDiceState) { + ScopedAccountConsistencyDice scoped_dice; + content::TestBrowserThreadBundle test_thread_bundle; + TestingProfile profile; + ASSERT_FALSE(profile.IsNewProfile()); + + { + // First startup. + AccountConsistencyModeManager manager(&profile); + EXPECT_TRUE(profile.GetPrefs()->GetBoolean(prefs::kSigninAllowed)); + EXPECT_TRUE( + profile.GetPrefs()->GetBoolean(prefs::kSigninAllowedOnNextStartup)); + EXPECT_EQ(signin::AccountConsistencyMethod::kDice, + manager.GetAccountConsistencyMethod()); + + // User changes their settings. + profile.GetPrefs()->SetBoolean(prefs::kSigninAllowedOnNextStartup, false); + // Dice should remain in the same state until restart. + EXPECT_EQ(signin::AccountConsistencyMethod::kDice, + manager.GetAccountConsistencyMethod()); + } + + { + // Second startup. + AccountConsistencyModeManager manager(&profile); + // The signin-allowed pref should be disabled. + EXPECT_FALSE(profile.GetPrefs()->GetBoolean(prefs::kSigninAllowed)); + EXPECT_FALSE( + profile.GetPrefs()->GetBoolean(prefs::kSigninAllowedOnNextStartup)); + // Dice should be disabled. + EXPECT_EQ(signin::AccountConsistencyMethod::kDiceFixAuthErrors, + manager.GetAccountConsistencyMethod()); + } +} + // Checks that Dice migration happens when the reconcilor is created. TEST(AccountConsistencyModeManagerTest, MigrateAtCreation) { content::TestBrowserThreadBundle test_thread_bundle;
diff --git a/chrome/browser/signin/chrome_signin_helper.cc b/chrome/browser/signin/chrome_signin_helper.cc index 34d93417..84a4ce7e 100644 --- a/chrome/browser/signin/chrome_signin_helper.cc +++ b/chrome/browser/signin/chrome_signin_helper.cc
@@ -306,6 +306,9 @@ signin_metrics::PromoAction promo_action = signin_metrics::PromoAction::PROMO_ACTION_NO_SIGNIN_PROMO; signin_metrics::Reason reason = signin_metrics::Reason::REASON_UNKNOWN_REASON; + // This is the URL that the browser specified to redirect to after the user + // signs in. Not to be confused with the redirect header from GAIA response. + GURL redirect_after_signin_url = GURL::EmptyGURL(); bool is_sync_signin_tab = false; DiceTabHelper* tab_helper = DiceTabHelper::FromWebContents(web_contents); @@ -314,6 +317,7 @@ access_point = tab_helper->signin_access_point(); promo_action = tab_helper->signin_promo_action(); reason = tab_helper->signin_reason(); + redirect_after_signin_url = tab_helper->redirect_url(); } DiceResponseHandler* dice_response_handler = @@ -325,7 +329,8 @@ SigninManagerFactory::GetForProfile(profile), is_sync_signin_tab, base::BindOnce(&CreateDiceTurnOnSyncHelper, base::Unretained(profile), access_point, promo_action, reason), - base::BindOnce(&ShowDiceSigninError, base::Unretained(profile)))); + base::BindOnce(&ShowDiceSigninError, base::Unretained(profile)), + redirect_after_signin_url)); } #endif // BUILDFLAG(ENABLE_DICE_SUPPORT)
diff --git a/chrome/browser/signin/dice_tab_helper.cc b/chrome/browser/signin/dice_tab_helper.cc index c80f616..b25794f7 100644 --- a/chrome/browser/signin/dice_tab_helper.cc +++ b/chrome/browser/signin/dice_tab_helper.cc
@@ -24,7 +24,8 @@ const GURL& signin_url, signin_metrics::AccessPoint access_point, signin_metrics::Reason reason, - signin_metrics::PromoAction promo_action) { + signin_metrics::PromoAction promo_action, + const GURL& redirect_url) { DCHECK(signin_url.is_valid()); DCHECK(signin_url_.is_empty() || signin_url_ == signin_url); @@ -39,6 +40,7 @@ signin_promo_action_ = promo_action; is_chrome_signin_page_ = true; signin_page_load_recorded_ = false; + redirect_url_ = redirect_url; if (reason == signin_metrics::Reason::REASON_SIGNIN_PRIMARY_ACCOUNT) { signin_metrics::LogSigninAccessPointStarted(access_point, promo_action);
diff --git a/chrome/browser/signin/dice_tab_helper.h b/chrome/browser/signin/dice_tab_helper.h index 3e39d1d7..72e75db5 100644 --- a/chrome/browser/signin/dice_tab_helper.h +++ b/chrome/browser/signin/dice_tab_helper.h
@@ -31,12 +31,15 @@ signin_metrics::Reason signin_reason() { return signin_reason_; } + GURL redirect_url() { return redirect_url_; } + // Initializes the DiceTabHelper for a new signin flow. Must be called once // per signin flow happening in the tab, when the signin URL is being loaded. void InitializeSigninFlow(const GURL& signin_url, signin_metrics::AccessPoint access_point, signin_metrics::Reason reason, - signin_metrics::PromoAction promo_action); + signin_metrics::PromoAction promo_action, + const GURL& redirect_url); // Returns true if this the tab is a re-usable chrome sign-in page (the signin // page is loading or loaded in the tab). @@ -57,6 +60,7 @@ bool IsSigninPageNavigation( content::NavigationHandle* navigation_handle) const; + GURL redirect_url_; GURL signin_url_; signin_metrics::AccessPoint signin_access_point_ = signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN;
diff --git a/chrome/browser/signin/dice_tab_helper_unittest.cc b/chrome/browser/signin/dice_tab_helper_unittest.cc index 172ed2d..b7060c9 100644 --- a/chrome/browser/signin/dice_tab_helper_unittest.cc +++ b/chrome/browser/signin/dice_tab_helper_unittest.cc
@@ -31,7 +31,8 @@ simulator->Start(); helper->InitializeSigninFlow( signin_url_, access_point, reason, - signin_metrics::PromoAction::PROMO_ACTION_NO_SIGNIN_PROMO); + signin_metrics::PromoAction::PROMO_ACTION_NO_SIGNIN_PROMO, + GURL::EmptyGURL()); EXPECT_TRUE(helper->IsChromeSigninPage()); simulator->Commit(); } @@ -127,8 +128,8 @@ dice_tab_helper->InitializeSigninFlow( signin_url_, signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS, signin_metrics::Reason::REASON_SIGNIN_PRIMARY_ACCOUNT, - signin_metrics::PromoAction:: - PROMO_ACTION_NEW_ACCOUNT_NO_EXISTING_ACCOUNT); + signin_metrics::PromoAction::PROMO_ACTION_NEW_ACCOUNT_NO_EXISTING_ACCOUNT, + GURL::EmptyGURL()); EXPECT_EQ(1, ua_tester.GetActionCount("Signin_Signin_FromSettings")); EXPECT_EQ(1, ua_tester.GetActionCount("Signin_SigninPage_Loading")); EXPECT_EQ(0, ua_tester.GetActionCount("Signin_SigninPage_Shown")); @@ -157,7 +158,8 @@ dice_tab_helper->InitializeSigninFlow( signin_url_, signin_metrics::AccessPoint::ACCESS_POINT_SETTINGS, signin_metrics::Reason::REASON_SIGNIN_PRIMARY_ACCOUNT, - signin_metrics::PromoAction::PROMO_ACTION_WITH_DEFAULT); + signin_metrics::PromoAction::PROMO_ACTION_WITH_DEFAULT, + GURL::EmptyGURL()); EXPECT_EQ(2, ua_tester.GetActionCount("Signin_Signin_FromSettings")); EXPECT_EQ(2, ua_tester.GetActionCount("Signin_SigninPage_Loading")); h_tester.ExpectUniqueSample(
diff --git a/chrome/browser/signin/process_dice_header_delegate_impl.cc b/chrome/browser/signin/process_dice_header_delegate_impl.cc index 9b4afaa..ab1f7b5 100644 --- a/chrome/browser/signin/process_dice_header_delegate_impl.cc +++ b/chrome/browser/signin/process_dice_header_delegate_impl.cc
@@ -31,13 +31,15 @@ SigninManager* signin_manager, bool is_sync_signin_tab, EnableSyncCallback enable_sync_callback, - ShowSigninErrorCallback show_signin_error_callback) + ShowSigninErrorCallback show_signin_error_callback, + const GURL& redirect_url) : content::WebContentsObserver(web_contents), account_consistency_(account_consistency), signin_manager_(signin_manager), enable_sync_callback_(std::move(enable_sync_callback)), show_signin_error_callback_(std::move(show_signin_error_callback)), - is_sync_signin_tab_(is_sync_signin_tab) { + is_sync_signin_tab_(is_sync_signin_tab), + redirect_url_(redirect_url) { DCHECK(web_contents); DCHECK(signin_manager_); } @@ -81,8 +83,17 @@ if (!web_contents) return; - // After signing in to Chrome, the user should be redirected to the NTP. - RedirectToNtp(web_contents); + // After signing in to Chrome, the user should be redirected to the NTP, + // unless specified otherwise. + if (redirect_url_.is_empty()) { + RedirectToNtp(web_contents); + return; + } + + DCHECK(redirect_url_.is_valid()); + web_contents->GetController().LoadURL(redirect_url_, content::Referrer(), + ui::PAGE_TRANSITION_AUTO_TOPLEVEL, + std::string()); } void ProcessDiceHeaderDelegateImpl::HandleTokenExchangeFailure(
diff --git a/chrome/browser/signin/process_dice_header_delegate_impl.h b/chrome/browser/signin/process_dice_header_delegate_impl.h index 56f9ba8..9ff2b1f 100644 --- a/chrome/browser/signin/process_dice_header_delegate_impl.h +++ b/chrome/browser/signin/process_dice_header_delegate_impl.h
@@ -43,7 +43,8 @@ SigninManager* signin_manager, bool is_sync_signin_tab, EnableSyncCallback enable_sync_callback, - ShowSigninErrorCallback show_signin_error_callback); + ShowSigninErrorCallback show_signin_error_callback, + const GURL& redirect_url = GURL::EmptyGURL()); ~ProcessDiceHeaderDelegateImpl() override; // ProcessDiceHeaderDelegate: @@ -60,6 +61,7 @@ EnableSyncCallback enable_sync_callback_; ShowSigninErrorCallback show_signin_error_callback_; bool is_sync_signin_tab_; + GURL redirect_url_; DISALLOW_COPY_AND_ASSIGN(ProcessDiceHeaderDelegateImpl); };
diff --git a/chrome/browser/ssl/security_state_tab_helper.cc b/chrome/browser/ssl/security_state_tab_helper.cc index c88e272..aebdb13 100644 --- a/chrome/browser/ssl/security_state_tab_helper.cc +++ b/chrome/browser/ssl/security_state_tab_helper.cc
@@ -148,7 +148,7 @@ UMA_HISTOGRAM_ENUMERATION( "Security.CertificateTransparency.MainFrameNavigationCompliance", entry->GetSSL().ct_policy_compliance, - net::ct::CTPolicyCompliance::CT_POLICY_MAX); + net::ct::CTPolicyCompliance::CT_POLICY_COUNT); } logged_http_warning_on_current_navigation_ = false;
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 3f588b9f..fa7c5ec5 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -46,12 +46,6 @@ # TODO(ellyjones): Remove this variable once 804950 and 802257 are fixed. if (is_mac) { cocoa_browser_sources = [ - "cocoa/animatable_image.h", - "cocoa/animatable_image.mm", - "cocoa/animatable_view.h", - "cocoa/animatable_view.mm", - "cocoa/background_gradient_view.h", - "cocoa/background_gradient_view.mm", "cocoa/browser_dialogs_views_mac.cc", "cocoa/browser_dialogs_views_mac.h", "cocoa/browser_window_cocoa.h", @@ -74,8 +68,6 @@ "cocoa/chrome_browser_window.mm", "cocoa/chrome_event_processing_window.h", "cocoa/chrome_event_processing_window.mm", - "cocoa/cocoa_util.h", - "cocoa/cocoa_util.mm", "cocoa/constrained_window/constrained_window_control_utils.h", "cocoa/constrained_window/constrained_window_control_utils.mm", "cocoa/constrained_window/constrained_window_custom_sheet.h", @@ -121,8 +113,6 @@ "cocoa/main_menu_item.h", "cocoa/nsview_additions.h", "cocoa/nsview_additions.mm", - "cocoa/rect_path_utils.h", - "cocoa/rect_path_utils.mm", "cocoa/restart_browser.h", "cocoa/restart_browser.mm", "cocoa/simple_message_box_cocoa.h", @@ -131,11 +121,6 @@ "cocoa/single_web_contents_dialog_manager_cocoa.mm", "cocoa/ssl_client_certificate_selector_cocoa.h", "cocoa/ssl_client_certificate_selector_cocoa.mm", - "cocoa/spinner_util.h", - "cocoa/styled_text_field.h", - "cocoa/styled_text_field.mm", - "cocoa/styled_text_field_cell.h", - "cocoa/styled_text_field_cell.mm", "cocoa/tab_contents/favicon_util_mac.h", "cocoa/tab_contents/favicon_util_mac.mm", "cocoa/tab_contents/overlayable_contents_controller.h", @@ -1420,6 +1405,8 @@ "ash/browser_image_registrar.h", "ash/cast_config_client_media_router.cc", "ash/cast_config_client_media_router.h", + "ash/chrome_accessibility_delegate.cc", + "ash/chrome_accessibility_delegate.h", "ash/chrome_browser_main_extra_parts_ash.cc", "ash/chrome_browser_main_extra_parts_ash.h", "ash/chrome_keyboard_controller_observer.cc", @@ -1951,10 +1938,10 @@ "webui/signin/user_manager_screen_handler.h", "webui/welcome/nux_helper.cc", "webui/welcome/nux_helper.h", - "webui/welcome_handler.cc", - "webui/welcome_handler.h", - "webui/welcome_ui.cc", - "webui/welcome_ui.h", + "webui/welcome/welcome_handler.cc", + "webui/welcome/welcome_handler.h", + "webui/welcome/welcome_ui.cc", + "webui/welcome/welcome_ui.h", ] if (enable_dice_support) { @@ -2252,10 +2239,10 @@ "webui/settings/chrome_cleanup_handler.cc", "webui/settings/chrome_cleanup_handler.h", "webui/settings_utils_win.cc", - "webui/welcome_win10_handler.cc", - "webui/welcome_win10_handler.h", - "webui/welcome_win10_ui.cc", - "webui/welcome_win10_ui.h", + "webui/welcome/welcome_win10_handler.cc", + "webui/welcome/welcome_win10_handler.h", + "webui/welcome/welcome_win10_ui.cc", + "webui/welcome/welcome_win10_ui.h", ] public_deps += [ "//ui/views", @@ -3676,8 +3663,6 @@ "//ui/views:test_support", ] sources += [ - "../../test/views/scoped_macviews_browser_mode.cc", - "../../test/views/scoped_macviews_browser_mode.h", "extensions/browser_action_test_util.h", "views/find_bar_host_unittest_util_views.cc", "views/payments/test_chrome_payment_request_delegate.cc",
diff --git a/chrome/browser/ui/ash/DEPS b/chrome/browser/ui/ash/DEPS index 2b01c236..359629c 100644 --- a/chrome/browser/ui/ash/DEPS +++ b/chrome/browser/ui/ash/DEPS
@@ -10,7 +10,7 @@ "!ash", "+ash/public", ], - # AshShellInit supports CLASSIC and MUS modes so allow ash/ includes. + # AshShellInit supports classic (non-mash) mode so allow ash/ includes. "ash_shell_init\.cc": [ "+ash", ], @@ -20,6 +20,10 @@ "+ash/accelerators/accelerator_controller.h", "+ash/shell.h", ], + # https://crbug.com/756054 + "chrome_accessibility_delegate.*": [ + "+ash/accessibility/accessibility_delegate.h", + ], # For ash::Shell::SetIsBrowserProcessWithMash() "chrome_browser_main_extra_parts_ash\.cc": [ "+ash/shell.h", @@ -40,8 +44,6 @@ ], # https://crbug.com/665064 "chrome_shell_delegate.*": [ - # https://crbug.com/756054 - "+ash/accessibility/accessibility_delegate.h", # https://crbug.com/557397 "+ash/screenshot_delegate.h", # https://crbug.com/665064
diff --git a/chrome/browser/ui/ash/assistant/device_actions.cc b/chrome/browser/ui/ash/assistant/device_actions.cc index a306441..b64e50b 100644 --- a/chrome/browser/ui/ash/assistant/device_actions.cc +++ b/chrome/browser/ui/ash/assistant/device_actions.cc
@@ -8,6 +8,7 @@ #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" #include "chromeos/dbus/dbus_thread_manager.h" +#include "chromeos/dbus/power_manager/backlight.pb.h" #include "chromeos/dbus/power_manager_client.h" #include "chromeos/network/network_state_handler.h" #include "components/prefs/pref_service.h" @@ -57,7 +58,15 @@ } void DeviceActions::SetScreenBrightnessLevel(double level, bool gradual) { + power_manager::SetBacklightBrightnessRequest request; + request.set_percent(level * 100); + request.set_transition( + gradual + ? power_manager::SetBacklightBrightnessRequest_Transition_GRADUAL + : power_manager::SetBacklightBrightnessRequest_Transition_INSTANT); + request.set_cause( + power_manager::SetBacklightBrightnessRequest_Cause_USER_REQUEST); chromeos::DBusThreadManager::Get() ->GetPowerManagerClient() - ->SetScreenBrightnessPercent(level * 100.0f, gradual); + ->SetScreenBrightness(request); }
diff --git a/chrome/browser/ui/ash/chrome_accessibility_delegate.cc b/chrome/browser/ui/ash/chrome_accessibility_delegate.cc new file mode 100644 index 0000000..8001a75 --- /dev/null +++ b/chrome/browser/ui/ash/chrome_accessibility_delegate.cc
@@ -0,0 +1,44 @@ +// 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/ash/chrome_accessibility_delegate.h" + +#include <limits> + +#include "chrome/browser/chromeos/accessibility/accessibility_manager.h" +#include "chrome/browser/chromeos/accessibility/magnification_manager.h" + +using chromeos::AccessibilityManager; +using chromeos::MagnificationManager; + +ChromeAccessibilityDelegate::ChromeAccessibilityDelegate() = default; + +ChromeAccessibilityDelegate::~ChromeAccessibilityDelegate() = default; + +void ChromeAccessibilityDelegate::SetMagnifierEnabled(bool enabled) { + DCHECK(MagnificationManager::Get()); + return MagnificationManager::Get()->SetMagnifierEnabled(enabled); +} + +bool ChromeAccessibilityDelegate::IsMagnifierEnabled() const { + DCHECK(MagnificationManager::Get()); + return MagnificationManager::Get()->IsMagnifierEnabled(); +} + +bool ChromeAccessibilityDelegate::ShouldShowAccessibilityMenu() const { + DCHECK(AccessibilityManager::Get()); + return AccessibilityManager::Get()->ShouldShowAccessibilityMenu(); +} + +void ChromeAccessibilityDelegate::SaveScreenMagnifierScale(double scale) { + if (MagnificationManager::Get()) + MagnificationManager::Get()->SaveScreenMagnifierScale(scale); +} + +double ChromeAccessibilityDelegate::GetSavedScreenMagnifierScale() { + if (MagnificationManager::Get()) + return MagnificationManager::Get()->GetSavedScreenMagnifierScale(); + + return std::numeric_limits<double>::min(); +}
diff --git a/chrome/browser/ui/ash/chrome_accessibility_delegate.h b/chrome/browser/ui/ash/chrome_accessibility_delegate.h new file mode 100644 index 0000000..015bd0f --- /dev/null +++ b/chrome/browser/ui/ash/chrome_accessibility_delegate.h
@@ -0,0 +1,28 @@ +// 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_ASH_CHROME_ACCESSIBILITY_DELEGATE_H_ +#define CHROME_BROWSER_UI_ASH_CHROME_ACCESSIBILITY_DELEGATE_H_ + +#include "ash/accessibility/accessibility_delegate.h" +#include "base/macros.h" + +// See ash::AccessibilityDelegate for details. +class ChromeAccessibilityDelegate : public ash::AccessibilityDelegate { + public: + ChromeAccessibilityDelegate(); + ~ChromeAccessibilityDelegate() override; + + // ash::AccessibilityDelegate: + void SetMagnifierEnabled(bool enabled) override; + bool IsMagnifierEnabled() const override; + bool ShouldShowAccessibilityMenu() const override; + void SaveScreenMagnifierScale(double scale) override; + double GetSavedScreenMagnifierScale() override; + + private: + DISALLOW_COPY_AND_ASSIGN(ChromeAccessibilityDelegate); +}; + +#endif // CHROME_BROWSER_UI_ASH_CHROME_ACCESSIBILITY_DELEGATE_H_
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.cc b/chrome/browser/ui/ash/chrome_shell_delegate.cc index 39266e3..d63a7ae2 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.cc +++ b/chrome/browser/ui/ash/chrome_shell_delegate.cc
@@ -4,24 +4,16 @@ #include "chrome/browser/ui/ash/chrome_shell_delegate.h" -#include <stddef.h> +#include <memory> -#include <limits> -#include <vector> - -#include "ash/accessibility/accessibility_delegate.h" #include "ash/screenshot_delegate.h" -#include "base/macros.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process_platform_part_chromeos.h" -#include "chrome/browser/chromeos/accessibility/accessibility_manager.h" -#include "chrome/browser/chromeos/accessibility/magnification_manager.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/ash/chrome_accessibility_delegate.h" #include "chrome/browser/ui/ash/chrome_keyboard_ui.h" #include "chrome/browser/ui/ash/chrome_screenshot_grabber.h" -#include "chrome/browser/ui/ash/multi_user/multi_user_util.h" -#include "chrome/browser/ui/ash/session_controller_client.h" #include "chrome/browser/ui/ash/session_util.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" @@ -30,57 +22,15 @@ #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h" -#include "content/public/common/service_manager_connection.h" -#include "content/public/common/url_constants.h" #include "services/ws/public/cpp/input_devices/input_device_controller_client.h" #include "ui/aura/window.h" -#include "ui/base/ui_base_features.h" -#include "url/url_constants.h" - -using chromeos::AccessibilityManager; +#include "url/gurl.h" namespace { const char kKeyboardShortcutHelpPageUrl[] = "https://support.google.com/chromebook/answer/183101"; -class AccessibilityDelegateImpl : public ash::AccessibilityDelegate { - public: - AccessibilityDelegateImpl() = default; - ~AccessibilityDelegateImpl() override = default; - - void SetMagnifierEnabled(bool enabled) override { - DCHECK(chromeos::MagnificationManager::Get()); - return chromeos::MagnificationManager::Get()->SetMagnifierEnabled(enabled); - } - - bool IsMagnifierEnabled() const override { - DCHECK(chromeos::MagnificationManager::Get()); - return chromeos::MagnificationManager::Get()->IsMagnifierEnabled(); - } - - bool ShouldShowAccessibilityMenu() const override { - DCHECK(AccessibilityManager::Get()); - return AccessibilityManager::Get()->ShouldShowAccessibilityMenu(); - } - - void SaveScreenMagnifierScale(double scale) override { - if (chromeos::MagnificationManager::Get()) - chromeos::MagnificationManager::Get()->SaveScreenMagnifierScale(scale); - } - - double GetSavedScreenMagnifierScale() override { - if (chromeos::MagnificationManager::Get()) { - return chromeos::MagnificationManager::Get() - ->GetSavedScreenMagnifierScale(); - } - return std::numeric_limits<double>::min(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(AccessibilityDelegateImpl); -}; - } // namespace ChromeShellDelegate::ChromeShellDelegate() = default; @@ -108,7 +58,7 @@ } ash::AccessibilityDelegate* ChromeShellDelegate::CreateAccessibilityDelegate() { - return new AccessibilityDelegateImpl; + return new ChromeAccessibilityDelegate; } std::unique_ptr<ash::ScreenshotDelegate>
diff --git a/chrome/browser/ui/ash/chrome_shell_delegate.h b/chrome/browser/ui/ash/chrome_shell_delegate.h index 1f9a7f4d6..641dc9cd7 100644 --- a/chrome/browser/ui/ash/chrome_shell_delegate.h +++ b/chrome/browser/ui/ash/chrome_shell_delegate.h
@@ -5,23 +5,15 @@ #ifndef CHROME_BROWSER_UI_ASH_CHROME_SHELL_DELEGATE_H_ #define CHROME_BROWSER_UI_ASH_CHROME_SHELL_DELEGATE_H_ -#include <memory> -#include <string> - #include "ash/shell_delegate.h" #include "base/macros.h" -#include "build/build_config.h" - -namespace keyboard { -class KeyboardUI; -} class ChromeShellDelegate : public ash::ShellDelegate { public: ChromeShellDelegate(); ~ChromeShellDelegate() override; - // ash::ShellDelegate overrides; + // ash::ShellDelegate: bool CanShowWindowForUser(aura::Window* window) const override; std::unique_ptr<keyboard::KeyboardUI> CreateKeyboardUI() override; std::unique_ptr<ash::ScreenshotDelegate> CreateScreenshotDelegate() override;
diff --git a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc index 364ba27d..d4937b7639 100644 --- a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc +++ b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc
@@ -194,9 +194,7 @@ #if BUILDFLAG(ENABLE_DICE_SUPPORT) if (AccountConsistencyModeManager::IsDiceEnabledForProfile( GetProfile())) { - return l10n_util::GetStringUTF16(dice_accounts_.empty() - ? IDS_AUTOFILL_SIGNIN_PROMO_MESSAGE - : IDS_AUTOFILL_SYNC_PROMO_MESSAGE); + return l10n_util::GetStringUTF16(IDS_AUTOFILL_SYNC_PROMO_MESSAGE); } #endif return l10n_util::GetStringUTF16(IDS_AUTOFILL_CARD_SAVED); @@ -503,11 +501,6 @@ return; account_info_ = account_tracker->GetAccountInfo( signin_manager->GetAuthenticatedAccountId()); - -#if BUILDFLAG(ENABLE_DICE_SUPPORT) - if (AccountConsistencyModeManager::IsDiceEnabledForProfile(profile)) - dice_accounts_ = signin_ui_util::GetAccountsForDicePromos(profile); -#endif } void SaveCardBubbleControllerImpl::ShowBubble() {
diff --git a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.h b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.h index 3792743..8eb14300 100644 --- a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.h +++ b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.h
@@ -6,7 +6,6 @@ #define CHROME_BROWSER_UI_AUTOFILL_SAVE_CARD_BUBBLE_CONTROLLER_IMPL_H_ #include <memory> -#include <vector> #include "base/macros.h" #include "base/timer/elapsed_timer.h" @@ -172,10 +171,6 @@ // The account info of the signed-in user. AccountInfo account_info_; - // The list of accounts that are signed-in but not syncing. Used for checking - // which promo message to show. - std::vector<AccountInfo> dice_accounts_; - // Contains the details of the card that will be saved if the user accepts. CreditCard card_;
diff --git a/chrome/browser/ui/cocoa/animatable_image.h b/chrome/browser/ui/cocoa/animatable_image.h deleted file mode 100644 index b859404..0000000 --- a/chrome/browser/ui/cocoa/animatable_image.h +++ /dev/null
@@ -1,53 +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_BROWSER_UI_COCOA_ANIMATABLE_IMAGE_H_ -#define CHROME_BROWSER_UI_COCOA_ANIMATABLE_IMAGE_H_ - -#import <Cocoa/Cocoa.h> -#import <QuartzCore/QuartzCore.h> - -#include "base/mac/scoped_nsobject.h" - -// This class helps animate an NSImage's frame and opacity. It works by creating -// a blank NSWindow in the size specified and giving it a layer on which the -// image can be animated. Clients are free to embed this object as a child -// window for easier window management. This class will clean itself up when -// the animation has finished. Clients that install this as a child window -// should listen for the NSWindowWillCloseNotification to perform any additional -// cleanup. -@interface AnimatableImage : NSWindow { - @private - // The image to animate. - base::scoped_nsobject<NSImage> image_; -} - -// The frame of the image before and after the animation. This is in this -// window's coordinate system. -@property(nonatomic) CGRect startFrame; -@property(nonatomic) CGRect endFrame; - -// Opacity values for the animation. -@property(nonatomic) CGFloat startOpacity; -@property(nonatomic) CGFloat endOpacity; - -// The amount of time it takes to animate the image. -@property(nonatomic) CGFloat duration; - -// The timing function to use for the animation. -@property(nonatomic, assign) CAMediaTimingFunction* timingFunction; - -// Designated initializer. Do not use any other NSWindow initializers. Creates -// but does not show the blank animation window of the given size. The -// |animationFrame| should usually be big enough to contain the |startFrame| -// and |endFrame| properties of the animation. -- (id)initWithImage:(NSImage*)image - animationFrame:(NSRect)animationFrame; - -// Begins the animation. -- (void)startAnimation; - -@end - -#endif // CHROME_BROWSER_UI_COCOA_ANIMATABLE_IMAGE_H_
diff --git a/chrome/browser/ui/cocoa/animatable_image.mm b/chrome/browser/ui/cocoa/animatable_image.mm deleted file mode 100644 index f21be0c..0000000 --- a/chrome/browser/ui/cocoa/animatable_image.mm +++ /dev/null
@@ -1,136 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "chrome/browser/ui/cocoa/animatable_image.h" - -#include "base/logging.h" -#import "base/mac/sdk_forward_declarations.h" -#import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSAnimation+Duration.h" - -@interface AnimatableImage (Private) <CAAnimationDelegate> -@end - -@implementation AnimatableImage - -@synthesize startFrame = startFrame_; -@synthesize endFrame = endFrame_; -@synthesize startOpacity = startOpacity_; -@synthesize endOpacity = endOpacity_; -@synthesize duration = duration_; -@synthesize timingFunction = timingFunction_; - -- (id)initWithImage:(NSImage*)image - animationFrame:(NSRect)animationFrame { - if ((self = [super initWithContentRect:animationFrame - styleMask:NSBorderlessWindowMask - backing:NSBackingStoreBuffered - defer:NO])) { - DCHECK(image); - image_.reset([image retain]); - duration_ = 1.0; - timingFunction_ = - [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; - startOpacity_ = 1.0; - endOpacity_ = 1.0; - - [self setOpaque:NO]; - [self setBackgroundColor:[NSColor clearColor]]; - [self setIgnoresMouseEvents:YES]; - - // Must be set or else self will be leaked. - [self setReleasedWhenClosed:YES]; - } - return self; -} - -- (void)startAnimation { - // Set up the root layer. By calling -setLayer: followed by -setWantsLayer: - // the view becomes a layer hosting view as opposed to a layer backed view. - NSView* view = [self contentView]; - CALayer* rootLayer = [CALayer layer]; - [view setLayer:rootLayer]; - [view setWantsLayer:YES]; - - // Create the layer that will be animated. - CALayer* layer = [CALayer layer]; - [layer setContents:image_.get()]; - [layer setAnchorPoint:CGPointMake(0, 1)]; - [layer setFrame:[self startFrame]]; - [layer setNeedsDisplayOnBoundsChange:YES]; - [rootLayer addSublayer:layer]; - - // Animate the bounds only if the image is resized. - CABasicAnimation* boundsAnimation = nil; - if (CGRectGetWidth([self startFrame]) != CGRectGetWidth([self endFrame]) || - CGRectGetHeight([self startFrame]) != CGRectGetHeight([self endFrame])) { - boundsAnimation = [CABasicAnimation animationWithKeyPath:@"bounds"]; - NSRect startRect = NSMakeRect(0, 0, - CGRectGetWidth([self startFrame]), - CGRectGetHeight([self startFrame])); - [boundsAnimation setFromValue:[NSValue valueWithRect:startRect]]; - NSRect endRect = NSMakeRect(0, 0, - CGRectGetWidth([self endFrame]), - CGRectGetHeight([self endFrame])); - [boundsAnimation setToValue:[NSValue valueWithRect:endRect]]; - [boundsAnimation gtm_setDuration:[self duration] - eventMask:NSLeftMouseUpMask]; - [boundsAnimation setTimingFunction:timingFunction_]; - } - - // Positional animation. - CABasicAnimation* positionAnimation = - [CABasicAnimation animationWithKeyPath:@"position"]; - [positionAnimation setFromValue: - [NSValue valueWithPoint:NSPointFromCGPoint([self startFrame].origin)]]; - [positionAnimation setToValue: - [NSValue valueWithPoint:NSPointFromCGPoint([self endFrame].origin)]]; - [positionAnimation gtm_setDuration:[self duration] - eventMask:NSLeftMouseUpMask]; - [positionAnimation setTimingFunction:timingFunction_]; - - // Opacity animation. - CABasicAnimation* opacityAnimation = - [CABasicAnimation animationWithKeyPath:@"opacity"]; - [opacityAnimation setFromValue: - [NSNumber numberWithFloat:[self startOpacity]]]; - [opacityAnimation setToValue:[NSNumber numberWithFloat:[self endOpacity]]]; - [opacityAnimation gtm_setDuration:[self duration] - eventMask:NSLeftMouseUpMask]; - [opacityAnimation setTimingFunction:timingFunction_]; - // Set the delegate just for one of the animations so that this window can - // be closed upon completion. - [opacityAnimation setDelegate:self]; - - // The CAAnimations only affect the presentational value of a layer, not the - // model value. This means that after the animation is done, it can flicker - // back to the original values. To avoid this, create an implicit animation of - // the values, which are then overridden with the CABasicAnimations. - // - // Ideally, a call to |-setBounds:| should be here, but, for reasons that - // are not understood, doing so causes the animation to break. - [layer setPosition:[self endFrame].origin]; - [layer setOpacity:[self endOpacity]]; - - // Start the animations. - [CATransaction begin]; - [CATransaction setValue:[NSNumber numberWithFloat:[self duration]] - forKey:kCATransactionAnimationDuration]; - if (boundsAnimation) { - [layer addAnimation:boundsAnimation forKey:@"bounds"]; - } - [layer addAnimation:positionAnimation forKey:@"position"]; - [layer addAnimation:opacityAnimation forKey:@"opacity"]; - [CATransaction commit]; -} - -- (void)animationDidStart:(CAAnimation*)animation { -} - -// CAAnimation delegate method called when the animation is complete. -- (void)animationDidStop:(CAAnimation*)animation finished:(BOOL)flag { - // Close the window, releasing self. - [self close]; -} - -@end
diff --git a/chrome/browser/ui/cocoa/animatable_image_unittest.mm b/chrome/browser/ui/cocoa/animatable_image_unittest.mm deleted file mode 100644 index 8ffe32b..0000000 --- a/chrome/browser/ui/cocoa/animatable_image_unittest.mm +++ /dev/null
@@ -1,45 +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. - -#import <Cocoa/Cocoa.h> - -#import "chrome/browser/ui/cocoa/animatable_image.h" -#import "chrome/browser/ui/cocoa/test/cocoa_test_helper.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" - -namespace { - -class AnimatableImageTest : public CocoaTest { - public: - AnimatableImageTest() { - NSRect frame = NSMakeRect(0, 0, 500, 500); - NSImage* image = [NSImage imageNamed:NSImageNameComputer]; - animation_ = [[AnimatableImage alloc] initWithImage:image - animationFrame:frame]; - } - - AnimatableImage* animation_; -}; - -TEST_F(AnimatableImageTest, BasicAnimation) { - [animation_ setStartFrame:CGRectMake(0, 0, 10, 10)]; - [animation_ setEndFrame:CGRectMake(500, 500, 100, 100)]; - [animation_ setStartOpacity:0.1]; - [animation_ setEndOpacity:1.0]; - [animation_ setDuration:0.5]; - [animation_ startAnimation]; -} - -TEST_F(AnimatableImageTest, CancelAnimation) { - [animation_ setStartFrame:CGRectMake(0, 0, 10, 10)]; - [animation_ setEndFrame:CGRectMake(500, 500, 100, 100)]; - [animation_ setStartOpacity:0.1]; - [animation_ setEndOpacity:1.0]; - [animation_ setDuration:5.0]; // Long enough to be able to test cancelling. - [animation_ startAnimation]; - [animation_ close]; -} - -} // namespace
diff --git a/chrome/browser/ui/cocoa/animatable_view.h b/chrome/browser/ui/cocoa/animatable_view.h deleted file mode 100644 index e787419..0000000 --- a/chrome/browser/ui/cocoa/animatable_view.h +++ /dev/null
@@ -1,57 +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. - -#ifndef CHROME_BROWSER_UI_COCOA_ANIMATABLE_VIEW_H_ -#define CHROME_BROWSER_UI_COCOA_ANIMATABLE_VIEW_H_ - -#import <Cocoa/Cocoa.h> - -#import "base/mac/scoped_nsobject.h" -#import "chrome/browser/ui/cocoa/background_gradient_view.h" -#import "chrome/browser/ui/cocoa/view_resizer.h" - -// A view that provides an animatable height property. Provides methods to -// animate to a new height, set a new height immediately, or cancel any running -// animations. -// -// AnimatableView sends an |animationDidEnd:| message to its delegate when the -// animation ends normally and an |animationDidStop:| message when the animation -// was canceled (even when canceled as a result of a new animation starting). - -@interface AnimatableView : BackgroundGradientView<NSAnimationDelegate> { - @protected - IBOutlet id delegate_; // weak, used to send animation ended messages. - - @private - base::scoped_nsobject<NSAnimation> currentAnimation_; - id<ViewResizer> resizeDelegate_; // weak, usually owns us -} - -// Properties for bindings. -@property(assign, nonatomic) id delegate; -@property(assign, nonatomic) id<ViewResizer> resizeDelegate; - -// Gets the current height of the view. If an animation is currently running, -// this will give the current height at the time of the call, not the target -// height at the end of the animation. -- (CGFloat)height; - -// Sets the height of the view immediately. Cancels any running animations. -- (void)setHeight:(CGFloat)newHeight; - -// Starts a new animation to the given |newHeight| for the given |duration|. -// Cancels any running animations. -- (void)animateToNewHeight:(CGFloat)newHeight - duration:(NSTimeInterval)duration; - -// Cancels any running animations, leaving the view at its current -// (mid-animation) height. -- (void)stopAnimation; - -// Gets the progress of any current animation. -- (NSAnimationProgress)currentAnimationProgress; - -@end - -#endif // CHROME_BROWSER_UI_COCOA_ANIMATABLE_VIEW_H_
diff --git a/chrome/browser/ui/cocoa/animatable_view.mm b/chrome/browser/ui/cocoa/animatable_view.mm deleted file mode 100644 index cb00e04..0000000 --- a/chrome/browser/ui/cocoa/animatable_view.mm +++ /dev/null
@@ -1,109 +0,0 @@ -// Copyright (c) 2009 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. - -#import <Cocoa/Cocoa.h> -#import <QuartzCore/QuartzCore.h> - -#import "chrome/browser/ui/cocoa/animatable_view.h" -#import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSAnimation+Duration.h" - -// NSAnimation subclass that animates the height of an AnimatableView. Allows -// the caller to start and cancel the animation as desired. -@interface HeightAnimation : NSAnimation { - @private - AnimatableView* view_; // weak, owns us. - CGFloat startHeight_; - CGFloat endHeight_; -} - -// Initialize a new height animation for the given view. The animation will not -// start until startAnimation: is called. -- (id)initWithView:(AnimatableView*)view - finalHeight:(CGFloat)height - duration:(NSTimeInterval)duration; -@end - -@implementation HeightAnimation -- (id)initWithView:(AnimatableView*)view - finalHeight:(CGFloat)height - duration:(NSTimeInterval)duration { - if ((self = [super gtm_initWithDuration:duration - eventMask:NSLeftMouseUpMask - animationCurve:NSAnimationEaseIn])) { - view_ = view; - startHeight_ = [view_ height]; - endHeight_ = height; - [self setAnimationBlockingMode:NSAnimationNonblocking]; - [self setDelegate:view_]; - } - return self; -} - -// Overridden to call setHeight for each progress tick. -- (void)setCurrentProgress:(NSAnimationProgress)progress { - [super setCurrentProgress:progress]; - [view_ setHeight:((progress * (endHeight_ - startHeight_)) + startHeight_)]; -} -@end - - -@implementation AnimatableView -@synthesize delegate = delegate_; -@synthesize resizeDelegate = resizeDelegate_; - -- (void)dealloc { - // Stop the animation if it is running, since it holds a pointer to this view. - [self stopAnimation]; - [super dealloc]; -} - -- (CGFloat)height { - return [self frame].size.height; -} - -- (void)setHeight:(CGFloat)newHeight { - // Force the height to be an integer because some animations look terrible - // with non-integer intermediate heights. We only ever set integer heights - // for our views, so this shouldn't be a limitation in practice. - int height = floor(newHeight); - [resizeDelegate_ resizeView:self newHeight:height]; -} - -- (void)animateToNewHeight:(CGFloat)newHeight - duration:(NSTimeInterval)duration { - [currentAnimation_ stopAnimation]; - - currentAnimation_.reset([[HeightAnimation alloc] initWithView:self - finalHeight:newHeight - duration:duration]); - if ([resizeDelegate_ respondsToSelector:@selector(setAnimationInProgress:)]) - [resizeDelegate_ setAnimationInProgress:YES]; - [currentAnimation_ startAnimation]; -} - -- (void)stopAnimation { - [currentAnimation_ stopAnimation]; -} - -- (NSAnimationProgress)currentAnimationProgress { - return [currentAnimation_ currentProgress]; -} - -- (void)animationDidStop:(NSAnimation*)animation { - if ([resizeDelegate_ respondsToSelector:@selector(setAnimationInProgress:)]) - [resizeDelegate_ setAnimationInProgress:NO]; - if ([delegate_ respondsToSelector:@selector(animationDidStop:)]) - [delegate_ animationDidStop:animation]; - currentAnimation_.reset(nil); -} - -- (void)animationDidEnd:(NSAnimation*)animation { - if ([resizeDelegate_ respondsToSelector:@selector(setAnimationInProgress:)]) - [resizeDelegate_ setAnimationInProgress:NO]; - if ([delegate_ respondsToSelector:@selector(animationDidEnd:)]) - [delegate_ animationDidEnd:animation]; - currentAnimation_.reset(nil); -} - -@end
diff --git a/chrome/browser/ui/cocoa/animatable_view_unittest.mm b/chrome/browser/ui/cocoa/animatable_view_unittest.mm deleted file mode 100644 index cd4561b..0000000 --- a/chrome/browser/ui/cocoa/animatable_view_unittest.mm +++ /dev/null
@@ -1,48 +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. - -#import <Cocoa/Cocoa.h> - -#include "base/mac/scoped_nsobject.h" -#import "chrome/browser/ui/cocoa/animatable_view.h" -#import "chrome/browser/ui/cocoa/test/cocoa_test_helper.h" -#import "chrome/browser/ui/cocoa/view_resizer_pong.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" - -namespace { - -class AnimatableViewTest : public CocoaTest { - public: - AnimatableViewTest() { - NSRect frame = NSMakeRect(0, 0, 100, 100); - view_.reset([[AnimatableView alloc] initWithFrame:frame]); - [[test_window() contentView] addSubview:view_.get()]; - - resizeDelegate_.reset([[ViewResizerPong alloc] init]); - [view_ setResizeDelegate:resizeDelegate_.get()]; - } - - base::scoped_nsobject<ViewResizerPong> resizeDelegate_; - base::scoped_nsobject<AnimatableView> view_; -}; - -// Basic view tests (AddRemove, Display). -TEST_VIEW(AnimatableViewTest, view_); - -TEST_F(AnimatableViewTest, GetAndSetHeight) { - // Make sure the view's height starts out at 100. - NSRect initialFrame = [view_ frame]; - ASSERT_EQ(100, initialFrame.size.height); - EXPECT_EQ(initialFrame.size.height, [view_ height]); - - // Set it directly to 50 and make sure it takes effect. - [resizeDelegate_ setHeight:-1]; - [view_ setHeight:50]; - EXPECT_EQ(50, [resizeDelegate_ height]); -} - -// TODO(rohitrao): Find a way to unittest the animations and delegate messages. - -} // namespace
diff --git a/chrome/browser/ui/cocoa/background_gradient_view.h b/chrome/browser/ui/cocoa/background_gradient_view.h deleted file mode 100644 index f4a33c1..0000000 --- a/chrome/browser/ui/cocoa/background_gradient_view.h +++ /dev/null
@@ -1,36 +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_BROWSER_UI_COCOA_BACKGROUND_GRADIENT_VIEW_H_ -#define CHROME_BROWSER_UI_COCOA_BACKGROUND_GRADIENT_VIEW_H_ - -#import <Cocoa/Cocoa.h> - -#import "chrome/browser/ui/cocoa/themed_window.h" - -// A custom view that draws a 'standard' background gradient. -// Base class for other Chromium views. -@interface BackgroundGradientView : NSView<ThemedWindowDrawing> - -// Controls whether the bar draws a dividing line. -@property(nonatomic, assign) BOOL showsDivider; - -// Controls where the bar draws a dividing line. -@property(nonatomic, assign) NSRectEdge dividerEdge; - -// The color used for the bottom stroke. Public so subclasses can use. -- (NSColor*)strokeColor; - -// The pattern phase that will be used by -drawBackground:. -// Defaults to align the top of the theme image with the top of the tabs. -// Views that draw at the bottom of the window (download bar) can override to -// change the pattern phase. -- (NSPoint)patternPhase; - -// Draws the background image into the current NSGraphicsContext. -- (void)drawBackground:(NSRect)dirtyRect; - -@end - -#endif // CHROME_BROWSER_UI_COCOA_BACKGROUND_GRADIENT_VIEW_H_
diff --git a/chrome/browser/ui/cocoa/background_gradient_view.mm b/chrome/browser/ui/cocoa/background_gradient_view.mm deleted file mode 100644 index c96fc7a..0000000 --- a/chrome/browser/ui/cocoa/background_gradient_view.mm +++ /dev/null
@@ -1,188 +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/browser/ui/cocoa/background_gradient_view.h" - -#import "chrome/browser/themes/theme_properties.h" -#import "chrome/browser/themes/theme_service.h" -#import "chrome/browser/ui/cocoa/themed_window.h" -#include "chrome/grit/theme_resources.h" -#import "ui/base/cocoa/nsgraphics_context_additions.h" -#import "ui/base/cocoa/nsview_additions.h" -#include "ui/base/material_design/material_design_controller.h" - -@implementation BackgroundGradientView - -@synthesize showsDivider = showsDivider_; -@synthesize dividerEdge = dividerEdge_; - -- (id)initWithFrame:(NSRect)frameRect { - if ((self = [super initWithFrame:frameRect])) { - [self commonInit]; - } - return self; -} - -- (id)initWithCoder:(NSCoder*)decoder { - if ((self = [super initWithCoder:decoder])) { - [self commonInit]; - } - return self; -} - -- (void)commonInit { - showsDivider_ = YES; - dividerEdge_ = NSMinYEdge; -} - -- (void)setShowsDivider:(BOOL)show { - if (showsDivider_ == show) - return; - showsDivider_ = show; - [self setNeedsDisplay:YES]; -} - -- (void)setDividerEdge:(NSRectEdge)dividerEdge { - if (dividerEdge_ == dividerEdge) - return; - dividerEdge_ = dividerEdge; - [self setNeedsDisplay:YES]; -} - -- (NSPoint)patternPhase { - return [[self window] - themeImagePositionForAlignment:THEME_IMAGE_ALIGN_WITH_TAB_STRIP]; -} - -- (void)drawBackground:(NSRect)dirtyRect { - [[NSGraphicsContext currentContext] - cr_setPatternPhase:[self patternPhase] - forView:[self cr_viewBeingDrawnTo]]; - - const ui::ThemeProvider* themeProvider = [[self window] themeProvider]; - if (themeProvider && !themeProvider->UsingSystemTheme()) { - // If the background image is semi transparent then we need something - // to blend against. Using 20% black gives us a color similar to Windows. - [[NSColor colorWithCalibratedWhite:0.2 alpha:1.0] set]; - NSRectFill(dirtyRect); - } - - [[self backgroundImageColor] set]; - NSRectFillUsingOperation(dirtyRect, NSCompositeSourceOver); - - if (showsDivider_) { - // Draw stroke - NSRect borderRect, contentRect; - NSDivideRect([self bounds], &borderRect, &contentRect, [self cr_lineWidth], - dividerEdge_); - if (NSIntersectsRect(borderRect, dirtyRect)) { - [[self strokeColor] set]; - NSRectFillUsingOperation(NSIntersectionRect(borderRect, dirtyRect), - NSCompositeSourceOver); - } - } -} - -- (NSColor*)strokeColor { - NSWindow* window = [self window]; - - // Some views have a child NSWindow between them and the window that is - // active (e.g, OmniboxPopupTopSeparatorView). For these, check the status - // of parentWindow instead. Note that this is not tracked correctly (but - // the views that do this appear to be removed when the window loses focus - // anyway). - if ([window parentWindow]) - window = [window parentWindow]; - - const ui::ThemeProvider* themeProvider = [window themeProvider]; - if (!themeProvider) - return [NSColor blackColor]; - if (themeProvider->ShouldIncreaseContrast()) { - if ([window hasDarkTheme]) - return [NSColor whiteColor]; - else - return [NSColor blackColor]; - } - return themeProvider->GetNSColor( - ThemeProperties::COLOR_TOOLBAR_CONTENT_AREA_SEPARATOR); -} - -- (NSColor*)backgroundImageColor { - const ui::ThemeProvider* themeProvider = [[self window] themeProvider]; - if (!themeProvider) - return [[self window] backgroundColor]; - - // Themes don't have an inactive image so only look for one if there's no - // theme. - BOOL isActive = [[self window] isMainWindow]; - if (!isActive && themeProvider->UsingSystemTheme()) { - NSColor* color = themeProvider->GetNSImageColorNamed( - IDR_THEME_TOOLBAR_INACTIVE); - if (color) - return color; - } - - return themeProvider->GetNSImageColorNamed(IDR_THEME_TOOLBAR); -} - -- (void)viewDidMoveToWindow { - [super viewDidMoveToWindow]; - if ([self window]) { - // The new window for the view may have a different focus state than the - // last window this view was part of. - // This happens when the view is moved into a TabWindowOverlayWindow for - // tab dragging. - [self windowDidChangeActive]; - } -} - -- (void)viewWillStartLiveResize { - [super viewWillStartLiveResize]; - - const ui::ThemeProvider* themeProvider = [[self window] themeProvider]; - if (themeProvider && themeProvider->UsingSystemTheme()) { - // The default theme's background image is a subtle texture pattern that - // we can scale without being easily noticed. Optimize this case by - // skipping redraws during live resize. - [self setLayerContentsRedrawPolicy: - NSViewLayerContentsRedrawOnSetNeedsDisplay]; - } -} - -- (void)viewDidEndLiveResize { - [super viewDidEndLiveResize]; - - if ([self layerContentsRedrawPolicy] != - NSViewLayerContentsRedrawDuringViewResize) { - // If we have been scaling the layer during live resize, now is the time to - // redraw the layer. - [self setLayerContentsRedrawPolicy: - NSViewLayerContentsRedrawDuringViewResize]; - [self setNeedsDisplay:YES]; - } -} - -- (void)setFrameOrigin:(NSPoint)origin { - // The background color depends on the view's vertical position. This impacts - // any child views that draw using this view's functions. - // When resizing the window, the view's vertical position (NSMinY) may change - // even though our relative position to the nearest window edge is still the - // same. Don't redraw unnecessarily in this case. - if (![self inLiveResize] && NSMinY([self frame]) != origin.y) - [self cr_recursivelySetNeedsDisplay:YES]; - - [super setFrameOrigin:origin]; -} - -// ThemedWindowDrawing implementation. - -- (void)windowDidChangeTheme { - [self setNeedsDisplay:YES]; -} - -- (void)windowDidChangeActive { - [self setNeedsDisplay:YES]; -} - -@end
diff --git a/chrome/browser/ui/cocoa/background_gradient_view_unittest.mm b/chrome/browser/ui/cocoa/background_gradient_view_unittest.mm deleted file mode 100644 index 8b6e867..0000000 --- a/chrome/browser/ui/cocoa/background_gradient_view_unittest.mm +++ /dev/null
@@ -1,49 +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. - -#import <Cocoa/Cocoa.h> - -#include "base/mac/scoped_nsobject.h" -#import "chrome/browser/ui/cocoa/background_gradient_view.h" -#import "chrome/browser/ui/cocoa/test/cocoa_test_helper.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" - -// Since BackgroundGradientView doesn't do any drawing by default, we -// create a subclass to call its draw method for us. -@interface BackgroundGradientSubClassTest : BackgroundGradientView -@end - -@implementation BackgroundGradientSubClassTest - -- (void)drawRect:(NSRect)dirtyRect { - [self drawBackground:dirtyRect]; -} - -@end - -namespace { - -class BackgroundGradientViewTest : public CocoaTest { - public: - BackgroundGradientViewTest() { - NSRect frame = NSMakeRect(0, 0, 100, 30); - base::scoped_nsobject<BackgroundGradientSubClassTest> view( - [[BackgroundGradientSubClassTest alloc] initWithFrame:frame]); - view_ = view.get(); - [[test_window() contentView] addSubview:view_]; - } - - BackgroundGradientSubClassTest* view_; -}; - -TEST_VIEW(BackgroundGradientViewTest, view_) - -// Test drawing, mostly to ensure nothing leaks or crashes. -TEST_F(BackgroundGradientViewTest, DisplayWithDivider) { - [view_ setShowsDivider:YES]; - [view_ display]; -} - -} // namespace
diff --git a/chrome/browser/ui/cocoa/browser_window_controller.mm b/chrome/browser/ui/cocoa/browser_window_controller.mm index 45b77d8..ec5b395c 100644 --- a/chrome/browser/ui/cocoa/browser_window_controller.mm +++ b/chrome/browser/ui/cocoa/browser_window_controller.mm
@@ -39,7 +39,6 @@ #include "chrome/browser/ui/browser_instant_controller.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window_state.h" -#import "chrome/browser/ui/cocoa/background_gradient_view.h" #include "chrome/browser/ui/cocoa/browser_dialogs_views_mac.h" #import "chrome/browser/ui/cocoa/browser_window_cocoa.h" #import "chrome/browser/ui/cocoa/browser_window_command_handler.h"
diff --git a/chrome/browser/ui/cocoa/browser_window_mac_browsertest.mm b/chrome/browser/ui/cocoa/browser_window_mac_browsertest.mm index df4e81a..43575c1a 100644 --- a/chrome/browser/ui/cocoa/browser_window_mac_browsertest.mm +++ b/chrome/browser/ui/cocoa/browser_window_mac_browsertest.mm
@@ -14,43 +14,21 @@ #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/test/base/in_process_browser_test.h" -#include "chrome/test/views/scoped_macviews_browser_mode.h" #include "content/public/browser/notification_service.h" #include "content/public/test/test_utils.h" -namespace { - -enum class BrowserType { VIEWS, COCOA }; - -std::string PrintBrowserType(const testing::TestParamInfo<BrowserType>& info) { - switch (info.param) { - case BrowserType::VIEWS: - return "Views"; - case BrowserType::COCOA: - return "Cocoa"; - } - NOTREACHED(); - return std::string(); -} - -} // namespace - -// Test harness for Mac-specific behaviors of BrowserWindow, whether it is -// Cocoa- or Views-based. -class BrowserWindowMacTest : public InProcessBrowserTest, - public ::testing::WithParamInterface<BrowserType> { +// Test harness for Mac-specific behaviors of BrowserWindow. +class BrowserWindowMacTest : public InProcessBrowserTest { public: - BrowserWindowMacTest() : mode_(GetParam() == BrowserType::VIEWS) {} + BrowserWindowMacTest() {} private: - test::ScopedMacViewsBrowserMode mode_; - DISALLOW_COPY_AND_ASSIGN(BrowserWindowMacTest); }; // Test that mainMenu commands do not attempt to validate against a Browser* // that is destroyed. -IN_PROC_BROWSER_TEST_P(BrowserWindowMacTest, MenuCommandsAfterDestroy) { +IN_PROC_BROWSER_TEST_F(BrowserWindowMacTest, MenuCommandsAfterDestroy) { // Simulate AppKit (e.g. NSMenu) retaining an NSWindow. base::scoped_nsobject<NSWindow> window(browser()->window()->GetNativeWindow(), base::scoped_policy::RETAIN); @@ -82,9 +60,3 @@ // which currently asks |super|. That is, NSWindow. Which says YES. EXPECT_TRUE([window validateUserInterfaceItem:bookmark_menu_item]); } - -INSTANTIATE_TEST_CASE_P(, - BrowserWindowMacTest, - ::testing::Values(BrowserType::VIEWS, - BrowserType::COCOA), - &PrintBrowserType);
diff --git a/chrome/browser/ui/cocoa/cocoa_util.h b/chrome/browser/ui/cocoa/cocoa_util.h deleted file mode 100644 index ceb95769..0000000 --- a/chrome/browser/ui/cocoa/cocoa_util.h +++ /dev/null
@@ -1,29 +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_COCOA_COCOA_UTIL_H_ -#define CHROME_BROWSER_UI_COCOA_COCOA_UTIL_H_ - -#import <Cocoa/Cocoa.h> - -#include <limits> - -#include "base/mac/foundation_util.h" - -namespace cocoa_util { - -// The minimum representable time interval. This can be used as the value -// passed to +[NSAnimationContext setDuration:] to stop an in-progress -// animation as quickly as possible. -const NSTimeInterval kMinimumTimeInterval = - std::numeric_limits<NSTimeInterval>::min(); - -// Remove underlining from the specified range of characters in a text view. -void RemoveUnderlining(NSTextView* textView, int offset, int length); - -CGFloat LineWidthFromContext(CGContextRef context); - -} // namespace cocoa_util - -#endif // CHROME_BROWSER_UI_COCOA_COCOA_UTIL_H_
diff --git a/chrome/browser/ui/cocoa/cocoa_util.mm b/chrome/browser/ui/cocoa/cocoa_util.mm deleted file mode 100644 index ebf3c79..0000000 --- a/chrome/browser/ui/cocoa/cocoa_util.mm +++ /dev/null
@@ -1,26 +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/cocoa/cocoa_util.h" - -namespace cocoa_util { - -void RemoveUnderlining(NSTextView* textView, int offset, int length) { - // Clear the default link attributes that were set by the - // HyperlinkTextView, otherwise removing the underline doesn't matter. - [textView setLinkTextAttributes:nil]; - NSTextStorage* text = [textView textStorage]; - NSRange range = NSMakeRange(offset, length); - [text addAttribute:NSUnderlineStyleAttributeName - value:[NSNumber numberWithInt:NSUnderlineStyleNone] - range:range]; -} - -CGFloat LineWidthFromContext(CGContextRef context) { - CGRect unitRect = CGRectMake(0.0, 0.0, 1.0, 1.0); - CGRect deviceRect = CGContextConvertRectToDeviceSpace(context, unitRect); - return 1.0 / deviceRect.size.height; -} - -} // namespace cocoa_util
diff --git a/chrome/browser/ui/cocoa/permission_bubble/permission_bubble_cocoa_interactive_uitest.mm b/chrome/browser/ui/cocoa/permission_bubble/permission_bubble_cocoa_interactive_uitest.mm index f62a9ad7..d5c7cf3 100644 --- a/chrome/browser/ui/cocoa/permission_bubble/permission_bubble_cocoa_interactive_uitest.mm +++ b/chrome/browser/ui/cocoa/permission_bubble/permission_bubble_cocoa_interactive_uitest.mm
@@ -18,7 +18,6 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/interactive_test_utils.h" -#include "chrome/test/views/scoped_macviews_browser_mode.h" #include "ui/base/test/ui_controls.h" #import "ui/base/test/windowed_nsnotification_observer.h" #include "ui/base/ui_base_features.h" @@ -97,9 +96,6 @@ base::test::ScopedFeatureList scoped_feature_list_; private: - // TDOO(thakis): Remove this, this should test views mode. - test::ScopedMacViewsBrowserMode cocoa_browser_mode_{false}; - DISALLOW_COPY_AND_ASSIGN(PermissionBubbleInteractiveUITest); };
diff --git a/chrome/browser/ui/cocoa/rect_path_utils.h b/chrome/browser/ui/cocoa/rect_path_utils.h deleted file mode 100644 index cb91fc1..0000000 --- a/chrome/browser/ui/cocoa/rect_path_utils.h +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_COCOA_RECT_PATH_UTILS_H_ -#define CHROME_BROWSER_UI_COCOA_RECT_PATH_UTILS_H_ - -#import <Cocoa/Cocoa.h> - -namespace rect_path_utils { - -enum RoundedCornerFlags { - RoundedCornerAll = 0, - RoundedCornerLeft = 1 -}; - -NSBezierPath *RectPathWithInset(RoundedCornerFlags roundedCornerFlags, - const NSRect frame, - const CGFloat insetX, - const CGFloat insetY, - const CGFloat outerRadius); - -void FillRectWithInset(RoundedCornerFlags roundedCornerFlags, - const NSRect frame, - const CGFloat insetX, - const CGFloat insetY, - const CGFloat outerRadius, - NSColor *color); - -void FrameRectWithInset(RoundedCornerFlags roundedCornerFlags, - const NSRect frame, - const CGFloat insetX, - const CGFloat insetY, - const CGFloat outerRadius, - const CGFloat lineWidth, - NSColor *color); - -} // namespace rect_path_utils - -#endif // CHROME_BROWSER_UI_COCOA_RECT_PATH_UTILS_H_
diff --git a/chrome/browser/ui/cocoa/rect_path_utils.mm b/chrome/browser/ui/cocoa/rect_path_utils.mm deleted file mode 100644 index 11503a1c..0000000 --- a/chrome/browser/ui/cocoa/rect_path_utils.mm +++ /dev/null
@@ -1,69 +0,0 @@ -// Copyright (c) 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import "chrome/browser/ui/cocoa/rect_path_utils.h" - -#import "third_party/google_toolbox_for_mac/src/AppKit/GTMNSBezierPath+RoundRect.h" - -namespace rect_path_utils { - -NSBezierPath* RectPathWithInset(RoundedCornerFlags roundedCornerFlags, - const NSRect frame, - const CGFloat insetX, - const CGFloat insetY, - const CGFloat outerRadius) { - NSRect insetFrame = NSInsetRect(frame, insetX, insetY); - - if (outerRadius > 0.0) { - CGFloat leftRadius = outerRadius - insetX; - CGFloat rightRadius = - (roundedCornerFlags == RoundedCornerLeft) ? 0 : leftRadius; - - return [NSBezierPath gtm_bezierPathWithRoundRect:insetFrame - topLeftCornerRadius:leftRadius - topRightCornerRadius:rightRadius - bottomLeftCornerRadius:leftRadius - bottomRightCornerRadius:rightRadius]; - } else { - return [NSBezierPath bezierPathWithRect:insetFrame]; - } -} - -// Similar to |NSRectFill()|, additionally sets |color| as the fill -// color. |outerRadius| greater than 0.0 uses rounded corners, with -// inset backed out of the radius. -void FillRectWithInset(RoundedCornerFlags roundedCornerFlags, - const NSRect frame, - const CGFloat insetX, - const CGFloat insetY, - const CGFloat outerRadius, - NSColor* color) { - NSBezierPath* path = - RectPathWithInset(roundedCornerFlags, frame, insetX, insetY, outerRadius); - [color setFill]; - [path fill]; -} - -// Similar to |NSFrameRectWithWidth()|, additionally sets |color| as -// the stroke color (as opposed to the fill color). |outerRadius| -// greater than 0.0 uses rounded corners, with inset backed out of the -// radius. -void FrameRectWithInset(RoundedCornerFlags roundedCornerFlags, - const NSRect frame, - const CGFloat insetX, - const CGFloat insetY, - const CGFloat outerRadius, - const CGFloat lineWidth, - NSColor* color) { - const CGFloat finalInsetX = insetX + (lineWidth / 2.0); - const CGFloat finalInsetY = insetY + (lineWidth / 2.0); - NSBezierPath* path = - RectPathWithInset(roundedCornerFlags, frame, finalInsetX, finalInsetY, - outerRadius); - [color setStroke]; - [path setLineWidth:lineWidth]; - [path stroke]; -} - -} // namespace rect_path_utils
diff --git a/chrome/browser/ui/cocoa/spinner_util.h b/chrome/browser/ui/cocoa/spinner_util.h deleted file mode 100644 index 25c73da..0000000 --- a/chrome/browser/ui/cocoa/spinner_util.h +++ /dev/null
@@ -1,33 +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_COCOA_SPINNER_UTIL_H_ -#define CHROME_BROWSER_UI_COCOA_SPINNER_UTIL_H_ - -#include "ui/gfx/geometry/angle_conversions.h" - -namespace cocoa_spinner_util { - -constexpr CGFloat kDegrees90 = gfx::DegToRad(90.0f); -constexpr CGFloat kDegrees135 = gfx::DegToRad(135.0f); -constexpr CGFloat kDegrees180 = gfx::DegToRad(180.0f); -constexpr CGFloat kDegrees270 = gfx::DegToRad(270.0f); -constexpr CGFloat kDegrees360 = gfx::DegToRad(360.0f); -constexpr CGFloat kSpinnerViewUnitWidth = 28.0; -constexpr CGFloat kSpinnerUnitInset = 2.0; -constexpr CGFloat kArcDiameter = - (kSpinnerViewUnitWidth - kSpinnerUnitInset * 2.0); -constexpr CGFloat kArcRadius = kArcDiameter / 2.0; -constexpr CGFloat kArcLength = - kDegrees135 * kArcDiameter; // 135 degrees of circumference. -constexpr CGFloat kArcStrokeWidth = 3.0; -constexpr CGFloat kArcAnimationTime = 1.333; -constexpr CGFloat kRotationTime = 1.56863; -NSString* const kSpinnerAnimationName = @"SpinnerAnimationName"; -NSString* const kRotationAnimationName = @"RotationAnimationName"; -constexpr CGFloat kWaitingStrokeAlpha = 0.5; - -} // namespace cocoa_spinner_util - -#endif // CHROME_BROWSER_UI_COCOA_SPINNER_UTIL_H_
diff --git a/chrome/browser/ui/cocoa/styled_text_field.h b/chrome/browser/ui/cocoa/styled_text_field.h deleted file mode 100644 index c55dfb2..0000000 --- a/chrome/browser/ui/cocoa/styled_text_field.h +++ /dev/null
@@ -1,34 +0,0 @@ -// Copyright (c) 2009 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_COCOA_STYLED_TEXT_FIELD_H_ -#define CHROME_BROWSER_UI_COCOA_STYLED_TEXT_FIELD_H_ - -#import <Cocoa/Cocoa.h> - -@class StyledTextFieldCell; - -// An implementation of NSTextField that is designed to work with -// StyledTextFieldCell. Provides methods to redraw the field when cell -// decorations have changed and overrides |mouseDown:| to properly handle clicks -// in sections of the cell with decorations. -@interface StyledTextField : NSTextField { -} - -// Repositions and redraws the field editor. Call this method when the cell's -// text frame has changed (whenever changing cell decorations). -- (void)resetFieldEditorFrameIfNeeded; - -// Returns the amount of the field's width which is not being taken up -// by the text contents. May be negative if the contents are large -// enough to scroll. -- (CGFloat)availableDecorationWidth; - -@end - -@interface StyledTextField (ExposedForTesting) -- (StyledTextFieldCell*)styledTextFieldCell; -@end - -#endif // CHROME_BROWSER_UI_COCOA_STYLED_TEXT_FIELD_H_
diff --git a/chrome/browser/ui/cocoa/styled_text_field.mm b/chrome/browser/ui/cocoa/styled_text_field.mm deleted file mode 100644 index 1acac18e..0000000 --- a/chrome/browser/ui/cocoa/styled_text_field.mm +++ /dev/null
@@ -1,72 +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. - -#import "chrome/browser/ui/cocoa/styled_text_field.h" - -#include "base/logging.h" -#import "chrome/browser/ui/cocoa/styled_text_field_cell.h" - -@implementation StyledTextField - -- (StyledTextFieldCell*)styledTextFieldCell { - DCHECK([[self cell] isKindOfClass:[StyledTextFieldCell class]]); - return static_cast<StyledTextFieldCell*>([self cell]); -} - -// Cocoa text fields are edited by placing an NSTextView as subview, -// positioned by the cell's -editWithFrame:inView:... method. Using -// the standard -makeFirstResponder: machinery to reposition the field -// editor results in resetting the field editor's editing state, which -// OmniboxViewMac monitors. This causes problems because -// editing can require the field editor to be repositioned, which -// could disrupt editing. This code repositions the subview directly, -// which causes no editing-state changes. -- (void)resetFieldEditorFrameIfNeeded { - // No action if not editing. - NSText* editor = [self currentEditor]; - if (!editor) { - return; - } - - // When editing, we should have exactly one subview, which is a - // clipview containing the editor (for purposes of scrolling). - NSArray* subviews = [self subviews]; - DCHECK_EQ([subviews count], 1U); - DCHECK([editor isDescendantOf:self]); - if ([subviews count] == 0) { - return; - } - - // If the frame is already right, don't make any visible changes. - StyledTextFieldCell* cell = [self styledTextFieldCell]; - const NSRect frame([cell drawingRectForBounds:[self bounds]]); - NSView* subview = [subviews objectAtIndex:0]; - if (NSEqualRects(frame, [subview frame])) { - return; - } - - [subview setFrame:frame]; - - // Make sure the selection remains visible. - [editor scrollRangeToVisible:[editor selectedRange]]; -} - -- (CGFloat)availableDecorationWidth { - NSAttributedString* as = [self attributedStringValue]; - const NSSize size([as size]); - const NSRect bounds([self bounds]); - return NSWidth(bounds) - size.width; -} - -- (NSFocusRingType)focusRingType { - // This is taken care of by the custom drawing code in the cell. - return NSFocusRingTypeNone; -} - -// Due to theming, parts of the field are transparent. -- (BOOL)isOpaque { - return NO; -} - -@end
diff --git a/chrome/browser/ui/cocoa/styled_text_field_cell.h b/chrome/browser/ui/cocoa/styled_text_field_cell.h deleted file mode 100644 index d0d0e49..0000000 --- a/chrome/browser/ui/cocoa/styled_text_field_cell.h +++ /dev/null
@@ -1,58 +0,0 @@ -// Copyright (c) 2009 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_COCOA_STYLED_TEXT_FIELD_CELL_H_ -#define CHROME_BROWSER_UI_COCOA_STYLED_TEXT_FIELD_CELL_H_ - -#import <Cocoa/Cocoa.h> - -#import "chrome/browser/ui/cocoa/rect_path_utils.h" - -// StyledTextFieldCell customizes the look of the standard Cocoa text field. -// The border and focus ring are modified, as is the drawing rect. Subclasses -// can override |drawInteriorWithFrame:inView:| to provide custom drawing for -// decorations, but they must make sure to call the superclass' implementation -// with a modified frame after performing any custom drawing. - -@interface StyledTextFieldCell : NSTextFieldCell { -} - -@end - -// Methods intended to be overridden by subclasses, not part of the public API -// and should not be called outside of subclasses. -@interface StyledTextFieldCell (ProtectedMethods) - -// Return the portion of the cell to show the text cursor over. The default -// implementation returns the full |cellFrame|. Subclasses should override this -// method if they add any decorations. -- (NSRect)textCursorFrameForFrame:(NSRect)cellFrame; - -// Return the portion of the cell to use for text display. This corresponds to -// the frame with our added decorations sliced off. The default implementation -// returns the full |cellFrame|, as by default there are no decorations. -// Subclasses should override this method if they add any decorations. -- (NSRect)textFrameForFrame:(NSRect)cellFrame; - -// Offset from the top of the cell frame to the text frame. Defaults to 0. -// Subclasses should -- (CGFloat)topTextFrameOffset; - -// Offset from the bottom of the cell frame to the text frame. Defaults to 0. -// Subclasses should -- (CGFloat)bottomTextFrameOffset; - -// Radius of the corners of the field. Defaults to square corners (0.0). -- (CGFloat)cornerRadius; - -// Which corners of the field to round. Defaults to RoundedAll. -- (rect_path_utils::RoundedCornerFlags)roundedFlags; - -// Returns YES if a light themed bezel should be drawn under the text field. -// Default implementation returns NO. -- (BOOL)shouldDrawBezel; - -@end - -#endif // CHROME_BROWSER_UI_COCOA_STYLED_TEXT_FIELD_CELL_H_
diff --git a/chrome/browser/ui/cocoa/styled_text_field_cell.mm b/chrome/browser/ui/cocoa/styled_text_field_cell.mm deleted file mode 100644 index a2484418..0000000 --- a/chrome/browser/ui/cocoa/styled_text_field_cell.mm +++ /dev/null
@@ -1,175 +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. - -#import "chrome/browser/ui/cocoa/styled_text_field_cell.h" - -#include "base/logging.h" -#include "chrome/browser/themes/theme_properties.h" -#include "chrome/browser/themes/theme_service.h" -#import "chrome/browser/ui/cocoa/themed_window.h" -#include "chrome/grit/theme_resources.h" -#import "ui/base/cocoa/nsgraphics_context_additions.h" -#import "ui/base/cocoa/nsview_additions.h" -#include "ui/base/cocoa/scoped_cg_context_smooth_fonts.h" -#include "ui/gfx/font.h" -#include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" - -@implementation StyledTextFieldCell - -- (CGFloat)topTextFrameOffset { - return 0.0; -} - -- (CGFloat)bottomTextFrameOffset { - return 0.0; -} - -- (CGFloat)cornerRadius { - return 0.0; -} - -- (rect_path_utils::RoundedCornerFlags)roundedCornerFlags { - return rect_path_utils::RoundedCornerAll; -} - -- (BOOL)shouldDrawBezel { - return NO; -} - -- (NSRect)textFrameForFrameInternal:(NSRect)cellFrame { - CGFloat topOffset = [self topTextFrameOffset]; - NSRect textFrame = cellFrame; - textFrame.origin.y += topOffset; - textFrame.size.height -= topOffset + [self bottomTextFrameOffset]; - return textFrame; -} - -// Returns the same value as textCursorFrameForFrame, but does not call it -// directly to avoid potential infinite loops. -- (NSRect)textFrameForFrame:(NSRect)cellFrame { - return [self textFrameForFrameInternal:cellFrame]; -} - -// Returns the same value as textFrameForFrame, but does not call it directly to -// avoid potential infinite loops. -- (NSRect)textCursorFrameForFrame:(NSRect)cellFrame { - return [self textFrameForFrameInternal:cellFrame]; -} - -// Override to show the I-beam cursor only in the area given by -// |textCursorFrameForFrame:|. -- (void)resetCursorRect:(NSRect)cellFrame inView:(NSView *)controlView { - [super resetCursorRect:[self textCursorFrameForFrame:cellFrame] - inView:controlView]; -} - -// For NSTextFieldCell this is the area within the borders. For our -// purposes, we count the info decorations as being part of the -// border. -- (NSRect)drawingRectForBounds:(NSRect)theRect { - return [super drawingRectForBounds:[self textFrameForFrame:theRect]]; -} - -// TODO(shess): This code is manually drawing the cell's border area, -// but otherwise the cell assumes -setBordered:YES for purposes of -// calculating things like the editing area. This is probably -// incorrect. I know that this affects -drawingRectForBounds:. -- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView { - const CGFloat lineWidth = [controlView cr_lineWidth]; - const CGFloat halfLineWidth = lineWidth / 2.0; - - DCHECK([controlView isFlipped]); - rect_path_utils::RoundedCornerFlags roundedCornerFlags = - [self roundedCornerFlags]; - - // TODO(shess): This inset is also reflected by |kFieldVisualInset| - // in omnibox_popup_view_mac.mm. - const NSRect frame = NSInsetRect(cellFrame, 0, lineWidth); - const CGFloat radius = [self cornerRadius]; - - // Paint button background image if there is one (otherwise the border won't - // look right). - const ui::ThemeProvider* themeProvider = [[controlView window] themeProvider]; - if (themeProvider) { - NSColor* backgroundImageColor = nil; - if (themeProvider->HasCustomImage(IDR_THEME_BUTTON_BACKGROUND)) { - backgroundImageColor = - themeProvider->GetNSImageColorNamed(IDR_THEME_BUTTON_BACKGROUND); - } - if (backgroundImageColor) { - // Set the phase to match window. - NSRect trueRect = [controlView convertRect:cellFrame toView:nil]; - NSPoint midPoint = NSMakePoint(NSMinX(trueRect), NSMaxY(trueRect)); - [[NSGraphicsContext currentContext] cr_setPatternPhase:midPoint - forView:controlView]; - - // NOTE(shess): This seems like it should be using a 0.0 inset, - // but AFAICT using a halfLineWidth inset is important in mixing the - // toolbar background and the omnibox background. - rect_path_utils::FillRectWithInset(roundedCornerFlags, frame, - halfLineWidth, halfLineWidth, radius, - backgroundImageColor); - } - - // Draw the outer stroke (over the background). - BOOL active = [[controlView window] isMainWindow]; - NSColor* strokeColor = themeProvider->GetNSColor( - active ? ThemeProperties::COLOR_TOOLBAR_BUTTON_STROKE : - ThemeProperties::COLOR_TOOLBAR_BUTTON_STROKE_INACTIVE); - rect_path_utils::FrameRectWithInset(roundedCornerFlags, frame, 0.0, 0.0, - radius, lineWidth, strokeColor); - } - - // Fill interior with background color. - rect_path_utils::FillRectWithInset(roundedCornerFlags, frame, lineWidth, - lineWidth, radius, - [self backgroundColor]); - - // Draw the shadow. For the rounded-rect case, the shadow needs to - // slightly turn in at the corners. |shadowFrame| is at the same - // midline as the inner border line on the top and left, but at the - // outer border line on the bottom and right. The clipping change - // will clip the bottom and right edges (and corner). - { - gfx::ScopedNSGraphicsContextSaveGState state; - [rect_path_utils::RectPathWithInset(roundedCornerFlags, frame, lineWidth, - lineWidth, radius) addClip]; - const NSRect shadowFrame = - NSOffsetRect(frame, halfLineWidth, halfLineWidth); - NSColor* shadowShade = [NSColor colorWithCalibratedWhite:0.0 - alpha:0.05 / lineWidth]; - rect_path_utils::FrameRectWithInset(roundedCornerFlags, shadowFrame, - halfLineWidth, halfLineWidth, - radius - halfLineWidth, lineWidth, - shadowShade); - } - - // Draw optional bezel below bottom stroke. - if ([self shouldDrawBezel] && themeProvider && - themeProvider->UsingSystemTheme()) { - NSColor* bezelColor = themeProvider->GetNSColor( - ThemeProperties::COLOR_TOOLBAR_BEZEL); - [[bezelColor colorWithAlphaComponent:0.5 / lineWidth] set]; - NSRect bezelRect = NSMakeRect(cellFrame.origin.x, - NSMaxY(cellFrame) - lineWidth, - NSWidth(cellFrame), - lineWidth); - bezelRect = NSInsetRect(bezelRect, radius - halfLineWidth, 0.0); - NSRectFillUsingOperation(bezelRect, NSCompositeSourceOver); - } - - // Draw the interior before the focus ring, to make sure nothing overlaps it. - ui::ScopedCGContextSmoothFonts fontSmoothing; - [self drawInteriorWithFrame:cellFrame inView:controlView]; - - // Draw the focus ring if needed. - if ([self showsFirstResponder]) { - NSColor* color = [[NSColor keyboardFocusIndicatorColor] - colorWithAlphaComponent:0.5 / lineWidth]; - rect_path_utils::FrameRectWithInset(roundedCornerFlags, frame, 0.0, 0.0, - radius, lineWidth * 2, color); - } -} - -@end
diff --git a/chrome/browser/ui/cocoa/styled_text_field_cell_unittest.mm b/chrome/browser/ui/cocoa/styled_text_field_cell_unittest.mm deleted file mode 100644 index 409738e..0000000 --- a/chrome/browser/ui/cocoa/styled_text_field_cell_unittest.mm +++ /dev/null
@@ -1,93 +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. - -#import <Cocoa/Cocoa.h> - -#include "base/mac/scoped_nsobject.h" -#import "chrome/browser/ui/cocoa/styled_text_field_cell.h" -#import "chrome/browser/ui/cocoa/test/cocoa_test_helper.h" -#import "chrome/browser/ui/cocoa/test/styled_text_field_test_helper.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/platform_test.h" - -namespace { - -// Width of the field so that we don't have to ask |field_| for it all -// the time. -const CGFloat kWidth(300.0); - -class StyledTextFieldCellTest : public CocoaTest { - public: - StyledTextFieldCellTest() { - // Make sure this is wide enough to play games with the cell - // decorations. - const NSRect frame = NSMakeRect(0, 0, kWidth, 30); - - base::scoped_nsobject<StyledTextFieldTestCell> cell( - [[StyledTextFieldTestCell alloc] initTextCell:@"Testing"]); - cell_ = cell.get(); - [cell_ setEditable:YES]; - [cell_ setBordered:YES]; - - base::scoped_nsobject<NSTextField> view( - [[NSTextField alloc] initWithFrame:frame]); - view_ = view.get(); - [view_ setCell:cell_]; - - [[test_window() contentView] addSubview:view_]; - } - - NSTextField* view_; - StyledTextFieldTestCell* cell_; -}; - -// Basic view tests (AddRemove, Display). -TEST_VIEW(StyledTextFieldCellTest, view_); - -// Test drawing, mostly to ensure nothing leaks or crashes. -TEST_F(StyledTextFieldCellTest, FocusedDisplay) { - [view_ display]; - - // Test focused drawing. - [test_window() makePretendKeyWindowAndSetFirstResponder:view_]; - [view_ display]; - [test_window() clearPretendKeyWindowAndFirstResponder]; - - // Test display of various cell configurations. - [cell_ setLeftMargin:5]; - [view_ display]; - - [cell_ setRightMargin:15]; - [view_ display]; -} - -// The editor frame should be slightly inset from the text frame. -TEST_F(StyledTextFieldCellTest, DrawingRectForBounds) { - const NSRect bounds = [view_ bounds]; - NSRect textFrame = [cell_ textFrameForFrame:bounds]; - NSRect drawingRect = [cell_ drawingRectForBounds:bounds]; - - EXPECT_FALSE(NSIsEmptyRect(drawingRect)); - EXPECT_TRUE(NSContainsRect(textFrame, NSInsetRect(drawingRect, 1, 1))); - - [cell_ setLeftMargin:10]; - textFrame = [cell_ textFrameForFrame:bounds]; - drawingRect = [cell_ drawingRectForBounds:bounds]; - EXPECT_FALSE(NSIsEmptyRect(drawingRect)); - EXPECT_TRUE(NSContainsRect(textFrame, NSInsetRect(drawingRect, 1, 1))); - - [cell_ setRightMargin:20]; - textFrame = [cell_ textFrameForFrame:bounds]; - drawingRect = [cell_ drawingRectForBounds:bounds]; - EXPECT_FALSE(NSIsEmptyRect(drawingRect)); - EXPECT_TRUE(NSContainsRect(NSInsetRect(textFrame, 1, 1), drawingRect)); - - [cell_ setLeftMargin:0]; - textFrame = [cell_ textFrameForFrame:bounds]; - drawingRect = [cell_ drawingRectForBounds:bounds]; - EXPECT_FALSE(NSIsEmptyRect(drawingRect)); - EXPECT_TRUE(NSContainsRect(NSInsetRect(textFrame, 1, 1), drawingRect)); -} - -} // namespace
diff --git a/chrome/browser/ui/cocoa/styled_text_field_unittest.mm b/chrome/browser/ui/cocoa/styled_text_field_unittest.mm deleted file mode 100644 index 0885aa93..0000000 --- a/chrome/browser/ui/cocoa/styled_text_field_unittest.mm +++ /dev/null
@@ -1,197 +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. - -#import <Cocoa/Cocoa.h> - -#include "base/mac/scoped_nsobject.h" -#import "chrome/browser/ui/cocoa/styled_text_field.h" -#import "chrome/browser/ui/cocoa/styled_text_field_cell.h" -#import "chrome/browser/ui/cocoa/test/cocoa_test_helper.h" -#import "chrome/browser/ui/cocoa/test/styled_text_field_test_helper.h" -#include "testing/gtest/include/gtest/gtest.h" -#import "testing/gtest_mac.h" - -namespace { - -// Width of the field so that we don't have to ask |field_| for it all -// the time. -static const CGFloat kWidth(300.0); - -class StyledTextFieldTest : public CocoaTest { - public: - StyledTextFieldTest() { - // Make sure this is wide enough to play games with the cell - // decorations. - NSRect frame = NSMakeRect(0, 0, kWidth, 30); - - base::scoped_nsobject<StyledTextFieldTestCell> cell( - [[StyledTextFieldTestCell alloc] initTextCell:@"Testing"]); - cell_ = cell.get(); - [cell_ setEditable:YES]; - [cell_ setBordered:YES]; - - base::scoped_nsobject<StyledTextField> field( - [[StyledTextField alloc] initWithFrame:frame]); - field_ = field.get(); - [field_ setCell:cell_]; - - [[test_window() contentView] addSubview:field_]; - } - - // Helper to return the field-editor frame being used w/in |field_|. - NSRect EditorFrame() { - EXPECT_TRUE([field_ currentEditor]); - EXPECT_EQ([[field_ subviews] count], 1U); - if ([[field_ subviews] count] > 0) { - return [[[field_ subviews] objectAtIndex:0] frame]; - } else { - // Return something which won't work so the caller can soldier - // on. - return NSZeroRect; - } - } - - StyledTextField* field_; - StyledTextFieldTestCell* cell_; -}; - -// Basic view tests (AddRemove, Display). -TEST_VIEW(StyledTextFieldTest, field_); - -// Test that we get the same cell from -cell and -// -styledTextFieldCell. -TEST_F(StyledTextFieldTest, Cell) { - StyledTextFieldCell* cell = [field_ styledTextFieldCell]; - EXPECT_EQ(cell, [field_ cell]); - EXPECT_TRUE(cell != nil); -} - -// Test that becoming first responder sets things up correctly. -TEST_F(StyledTextFieldTest, FirstResponder) { - EXPECT_EQ(nil, [field_ currentEditor]); - EXPECT_EQ([[field_ subviews] count], 0U); - [test_window() makePretendKeyWindowAndSetFirstResponder:field_]; - EXPECT_FALSE(nil == [field_ currentEditor]); - EXPECT_EQ([[field_ subviews] count], 1U); - EXPECT_TRUE([[field_ currentEditor] isDescendantOf:field_]); -} - -TEST_F(StyledTextFieldTest, AvailableDecorationWidth) { - // A fudge factor to account for how much space the border takes up. - // The test shouldn't be too dependent on the field's internals, but - // it also shouldn't let deranged cases fall through the cracks - // (like nothing available with no text, or everything available - // with some text). - const CGFloat kBorderWidth = 20.0; - - // With no contents, almost the entire width is available for - // decorations. - [field_ setStringValue:@""]; - CGFloat availableWidth = [field_ availableDecorationWidth]; - EXPECT_LE(availableWidth, kWidth); - EXPECT_GT(availableWidth, kWidth - kBorderWidth); - - // With minor contents, most of the remaining width is available for - // decorations. - NSDictionary* attributes = - [NSDictionary dictionaryWithObject:[field_ font] - forKey:NSFontAttributeName]; - NSString* string = @"Hello world"; - const NSSize size([string sizeWithAttributes:attributes]); - [field_ setStringValue:string]; - availableWidth = [field_ availableDecorationWidth]; - EXPECT_LE(availableWidth, kWidth - size.width); - EXPECT_GT(availableWidth, kWidth - size.width - kBorderWidth); - - // With huge contents, nothing at all is left for decorations. - string = @"A long string which is surely wider than field_ can hold."; - [field_ setStringValue:string]; - availableWidth = [field_ availableDecorationWidth]; - EXPECT_LT(availableWidth, 0.0); -} - -// Test drawing, mostly to ensure nothing leaks or crashes. -TEST_F(StyledTextFieldTest, Display) { - [field_ display]; - - // Test focused drawing. - [test_window() makePretendKeyWindowAndSetFirstResponder:field_]; - [field_ display]; -} - -// Test that the field editor gets the same bounds when focus is delivered by -// the standard focusing machinery, or by -resetFieldEditorFrameIfNeeded. -TEST_F(StyledTextFieldTest, ResetFieldEditorBase) { - // Capture the editor frame resulting from the standard focus machinery. - [test_window() makePretendKeyWindowAndSetFirstResponder:field_]; - const NSRect baseEditorFrame(EditorFrame()); - - // Setting a hint should result in a strictly smaller editor frame. - EXPECT_EQ(0, [cell_ leftMargin]); - EXPECT_EQ(0, [cell_ rightMargin]); - [cell_ setLeftMargin:10]; - [field_ resetFieldEditorFrameIfNeeded]; - EXPECT_NSNE(baseEditorFrame, EditorFrame()); - EXPECT_TRUE(NSContainsRect(baseEditorFrame, EditorFrame())); - - // Resetting the margin and using -resetFieldEditorFrameIfNeeded should result - // in the same frame as the standard focus machinery. - [cell_ setLeftMargin:0]; - [field_ resetFieldEditorFrameIfNeeded]; - EXPECT_NSEQ(baseEditorFrame, EditorFrame()); -} - -// Test that the field editor gets the same bounds when focus is delivered by -// the standard focusing machinery, or by -resetFieldEditorFrameIfNeeded. -TEST_F(StyledTextFieldTest, ResetFieldEditorLeftMargin) { - const CGFloat kLeftMargin = 20; - - // Start the cell off with a non-zero left margin. - [cell_ setLeftMargin:kLeftMargin]; - [cell_ setRightMargin:0]; - - // Capture the editor frame resulting from the standard focus machinery. - [test_window() makePretendKeyWindowAndSetFirstResponder:field_]; - const NSRect baseEditorFrame(EditorFrame()); - - // Clearing the margin should result in a strictly larger editor frame. - [cell_ setLeftMargin:0]; - [field_ resetFieldEditorFrameIfNeeded]; - EXPECT_NSNE(baseEditorFrame, EditorFrame()); - EXPECT_TRUE(NSContainsRect(EditorFrame(), baseEditorFrame)); - - // Setting the same margin and using -resetFieldEditorFrameIfNeeded should - // result in the same frame as the standard focus machinery. - [cell_ setLeftMargin:kLeftMargin]; - [field_ resetFieldEditorFrameIfNeeded]; - EXPECT_NSEQ(baseEditorFrame, EditorFrame()); -} - -// Test that the field editor gets the same bounds when focus is delivered by -// the standard focusing machinery, or by -resetFieldEditorFrameIfNeeded. -TEST_F(StyledTextFieldTest, ResetFieldEditorRightMargin) { - const CGFloat kRightMargin = 20; - - // Start the cell off with a non-zero right margin. - [cell_ setLeftMargin:0]; - [cell_ setRightMargin:kRightMargin]; - - // Capture the editor frame resulting from the standard focus machinery. - [test_window() makePretendKeyWindowAndSetFirstResponder:field_]; - const NSRect baseEditorFrame(EditorFrame()); - - // Clearing the margin should result in a strictly larger editor frame. - [cell_ setRightMargin:0]; - [field_ resetFieldEditorFrameIfNeeded]; - EXPECT_NSNE(baseEditorFrame, EditorFrame()); - EXPECT_TRUE(NSContainsRect(EditorFrame(), baseEditorFrame)); - - // Setting the same margin and using -resetFieldEditorFrameIfNeeded should - // result in the same frame as the standard focus machinery. - [cell_ setRightMargin:kRightMargin]; - [field_ resetFieldEditorFrameIfNeeded]; - EXPECT_NSEQ(baseEditorFrame, EditorFrame()); -} - -} // namespace
diff --git a/chrome/browser/ui/cocoa/test/cocoa_profile_test.h b/chrome/browser/ui/cocoa/test/cocoa_profile_test.h index 2b98dd6b..c36602e 100644 --- a/chrome/browser/ui/cocoa/test/cocoa_profile_test.h +++ b/chrome/browser/ui/cocoa/test/cocoa_profile_test.h
@@ -9,6 +9,7 @@ #import "chrome/browser/ui/cocoa/test/cocoa_test_helper.h" #include "chrome/test/base/testing_profile_manager.h" +#include "ui/views/test/scoped_views_test_helper.h" namespace content { class TestBrowserThreadBundle; @@ -27,10 +28,9 @@ // would never be deleted and would report as a leak under Valgrind. Note that // these are fake threads and they all share the same MessageLoop. // -// TODO(jrg): move up a level (chrome/browser/ui/cocoa --> -// chrome/browser), and use in non-Mac unit tests such as -// back_forward_menu_model_unittest.cc, -// navigation_controller_unittest.cc, .. +// TODO(rsesek): There is very little "Cocoa" about this class anymore. It +// should likely be removed in favor of +// chrome/browser/ui/views/frame/test_with_browser_view.h. class CocoaProfileTest : public CocoaTest { public: CocoaProfileTest(); @@ -67,12 +67,14 @@ } private: + std::unique_ptr<content::TestBrowserThreadBundle> thread_bundle_; + + views::ScopedViewsTestHelper views_helper_; + TestingProfileManager profile_manager_; TestingProfile* profile_; // Weak; owned by profile_manager_. TestingProfile::TestingFactories testing_factories_; std::unique_ptr<Browser> browser_; - - std::unique_ptr<content::TestBrowserThreadBundle> thread_bundle_; }; #endif // CHROME_BROWSER_UI_COCOA_TEST_COCOA_PROFILE_TEST_H_
diff --git a/chrome/browser/ui/cocoa/test/cocoa_profile_test.mm b/chrome/browser/ui/cocoa/test/cocoa_profile_test.mm index 4362c46..5deaed2 100644 --- a/chrome/browser/ui/cocoa/test/cocoa_profile_test.mm +++ b/chrome/browser/ui/cocoa/test/cocoa_profile_test.mm
@@ -10,20 +10,27 @@ #include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/search_engines/template_url_service_factory.h" +#include "chrome/browser/signin/fake_gaia_cookie_manager_service_builder.h" +#include "chrome/browser/signin/gaia_cookie_manager_service_factory.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/testing_profile.h" +#include "chrome/test/views/chrome_test_views_delegate.h" #include "components/bookmarks/test/bookmark_test_helpers.h" +#include "components/signin/core/browser/fake_gaia_cookie_manager_service.h" #include "components/sync_preferences/pref_service_syncable.h" #include "content/public/test/test_browser_thread_bundle.h" +#include "ui/views/test/widget_test.h" CocoaProfileTest::CocoaProfileTest() - : profile_manager_(TestingBrowserProcess::GetGlobal()), - profile_(NULL), - thread_bundle_(new content::TestBrowserThreadBundle) {} + : thread_bundle_(new content::TestBrowserThreadBundle), + views_helper_(std::make_unique<ChromeTestViewsDelegate>()), + profile_manager_(TestingBrowserProcess::GetGlobal()), + profile_(nullptr) {} CocoaProfileTest::~CocoaProfileTest() { // Delete the testing profile on the UI thread. But first release the @@ -36,7 +43,7 @@ // thread. If the scoper in TestingBrowserProcess, owned by ChromeTestSuite, // were to delete the ProfileManager, the UI thread would at that point no // longer exist. - TestingBrowserProcess::GetGlobal()->SetProfileManager(NULL); + TestingBrowserProcess::GetGlobal()->SetProfileManager(nullptr); // Make sure any pending tasks run before we destroy other threads. base::RunLoop().RunUntilIdle(); @@ -54,6 +61,10 @@ ASSERT_TRUE(profile_manager_.SetUp()); + // Always fake out the Gaia service to avoid issuing network requests. + testing_factories_.push_back({GaiaCookieManagerServiceFactory::GetInstance(), + &BuildFakeGaiaCookieManagerService}); + profile_ = profile_manager_.CreateTestingProfile( "Person 1", std::unique_ptr<sync_preferences::PrefServiceSyncable>(), base::UTF8ToUTF16("Person 1"), 0, std::string(), testing_factories_); @@ -69,6 +80,14 @@ AutocompleteClassifierFactory::GetInstance()->SetTestingFactoryAndUse( profile_, &AutocompleteClassifierFactory::BuildInstanceFor); + // Configure the GaiaCookieManagerService to return no accounts. + // This is copied from + // chrome/browser/ui/views/frame/test_with_browser_view.cc. + FakeGaiaCookieManagerService* gcms = + static_cast<FakeGaiaCookieManagerService*>( + GaiaCookieManagerServiceFactory::GetForProfile(profile_)); + gcms->SetListAccountsResponseHttpNotFound(); + profile_->CreateBookmarkModel(true); bookmarks::test::WaitForBookmarkModelToLoad( BookmarkModelFactory::GetForBrowserContext(profile_)); @@ -89,8 +108,14 @@ DCHECK(browser_->window()); browser_->tab_strip_model()->CloseAllTabs(); chrome::CloseWindow(browser_.get()); - // |browser_| will be deleted by its BrowserWindowController. - ignore_result(browser_.release()); + + // |browser_| will be deleted by its frame. + Browser* browser = browser_.release(); + auto* browser_view = BrowserView::GetBrowserViewForBrowser(browser); + + // Wait for the close to happen so that this method is synchronous. + views::test::WidgetDestroyedWaiter waiter(browser_view->frame()); + waiter.Wait(); } Browser* CocoaProfileTest::CreateBrowser() {
diff --git a/chrome/browser/ui/cocoa/test/cocoa_test_helper.h b/chrome/browser/ui/cocoa/test/cocoa_test_helper.h index 4b1e564..95371bc 100644 --- a/chrome/browser/ui/cocoa/test/cocoa_test_helper.h +++ b/chrome/browser/ui/cocoa/test/cocoa_test_helper.h
@@ -7,7 +7,6 @@ #import <Cocoa/Cocoa.h> -#include "chrome/test/views/scoped_macviews_browser_mode.h" #import "ui/base/test/cocoa_helper.h" // A test class that all tests that depend on AppKit should inherit from. @@ -26,9 +25,6 @@ static void BootstrapCocoa(); CocoaTest(); - - private: - test::ScopedMacViewsBrowserMode cocoa_mode_{false}; }; #endif // CHROME_BROWSER_UI_COCOA_TEST_COCOA_TEST_HELPER_H_
diff --git a/chrome/browser/ui/cocoa/test/styled_text_field_test_helper.h b/chrome/browser/ui/cocoa/test/styled_text_field_test_helper.h deleted file mode 100644 index 97ca884..0000000 --- a/chrome/browser/ui/cocoa/test/styled_text_field_test_helper.h +++ /dev/null
@@ -1,21 +0,0 @@ -// Copyright (c) 2009 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_COCOA_TEST_STYLED_TEXT_FIELD_TEST_HELPER_H_ -#define CHROME_BROWSER_UI_COCOA_TEST_STYLED_TEXT_FIELD_TEST_HELPER_H_ - -#import <Cocoa/Cocoa.h> -#import "chrome/browser/ui/cocoa/styled_text_field_cell.h" - -// Subclass of StyledTextFieldCell that allows you to slice off sections on the -// left and right of the cell. -@interface StyledTextFieldTestCell : StyledTextFieldCell { - CGFloat leftMargin_; - CGFloat rightMargin_; -} -@property(nonatomic, assign) CGFloat leftMargin; -@property(nonatomic, assign) CGFloat rightMargin; -@end - -#endif // CHROME_BROWSER_UI_COCOA_TEST_STYLED_TEXT_FIELD_TEST_HELPER_H_
diff --git a/chrome/browser/ui/cocoa/test/styled_text_field_test_helper.mm b/chrome/browser/ui/cocoa/test/styled_text_field_test_helper.mm deleted file mode 100644 index 43d1e8a..0000000 --- a/chrome/browser/ui/cocoa/test/styled_text_field_test_helper.mm +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright (c) 2009 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. - -#import <Cocoa/Cocoa.h> -#import "chrome/browser/ui/cocoa/test/styled_text_field_test_helper.h" - -@implementation StyledTextFieldTestCell -@synthesize leftMargin = leftMargin_; -@synthesize rightMargin = rightMargin_; - -- (NSRect)textFrameForFrame:(NSRect)frame { - NSRect textFrame = [super textFrameForFrame:frame]; - textFrame.origin.x += leftMargin_; - textFrame.size.width -= (leftMargin_ + rightMargin_); - return textFrame; -} -@end
diff --git a/chrome/browser/ui/omnibox/omnibox_theme.cc b/chrome/browser/ui/omnibox/omnibox_theme.cc index 92ee7304..6416c25 100644 --- a/chrome/browser/ui/omnibox/omnibox_theme.cc +++ b/chrome/browser/ui/omnibox/omnibox_theme.cc
@@ -6,6 +6,7 @@ #include "base/logging.h" #include "build/build_config.h" +#include "components/omnibox/browser/omnibox_field_trial.h" #include "ui/base/material_design/material_design_controller.h" #include "ui/gfx/color_palette.h" #include "ui/gfx/color_utils.h" @@ -279,6 +280,8 @@ return dark ? gfx::kGoogleBlueDark600 : gfx::kGoogleBlue600; case OmniboxPart::LOCATION_BAR_BUBBLE_OUTLINE: + if (OmniboxFieldTrial::IsExperimentalKeywordModeEnabled()) + return gfx::kGoogleBlue700; return dark ? gfx::kGoogleGrey100 : SkColorSetA(gfx::kGoogleGrey900, 0x24);
diff --git a/chrome/browser/ui/signin_view_controller.cc b/chrome/browser/ui/signin_view_controller.cc index 35eeb95..81ca9ea9 100644 --- a/chrome/browser/ui/signin_view_controller.cc +++ b/chrome/browser/ui/signin_view_controller.cc
@@ -111,10 +111,10 @@ mode == profiles::BUBBLE_VIEW_MODE_GAIA_REAUTH; } -void SigninViewController::ShowSignin( - profiles::BubbleViewMode mode, - Browser* browser, - signin_metrics::AccessPoint access_point) { +void SigninViewController::ShowSignin(profiles::BubbleViewMode mode, + Browser* browser, + signin_metrics::AccessPoint access_point, + const GURL& redirect_url) { DCHECK(ShouldShowSigninForMode(mode)); #if defined(OS_CHROMEOS) @@ -135,7 +135,8 @@ signin_metrics::PromoAction promo_action = GetPromoActionForNewAccount( AccountTrackerServiceFactory::GetForProfile(profile), account_consistency); - ShowDiceSigninTab(mode, browser, access_point, promo_action, email); + ShowDiceSigninTab(mode, browser, access_point, promo_action, email, + redirect_url); } else { ShowModalSigninDialog(mode, browser, access_point); } @@ -219,7 +220,8 @@ Browser* browser, signin_metrics::AccessPoint access_point, signin_metrics::PromoAction promo_action, - const std::string& email) { + const std::string& email, + const GURL& redirect_url) { signin_metrics::Reason signin_reason = GetSigninReasonFromMode(mode); GURL signin_url = signin::GetSigninURLForDice(browser->profile(), email); content::WebContents* active_contents = nullptr; @@ -253,7 +255,7 @@ DiceTabHelper::CreateForWebContents(active_contents); DiceTabHelper* tab_helper = DiceTabHelper::FromWebContents(active_contents); tab_helper->InitializeSigninFlow(signin_url, access_point, signin_reason, - promo_action); + promo_action, redirect_url); } #endif // !defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/signin_view_controller.h b/chrome/browser/ui/signin_view_controller.h index 53e6fd1..7a3013f 100644 --- a/chrome/browser/ui/signin_view_controller.h +++ b/chrome/browser/ui/signin_view_controller.h
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "chrome/browser/ui/profile_chooser_constants.h" +#include "url/gurl.h" class Browser; class SigninViewControllerDelegate; @@ -42,7 +43,8 @@ // page. void ShowSignin(profiles::BubbleViewMode mode, Browser* browser, - signin_metrics::AccessPoint access_point); + signin_metrics::AccessPoint access_point, + const GURL& redirect_url = GURL::EmptyGURL()); #if !defined(OS_CHROMEOS) // Shows the DICE-specific sign-in flow: opens a Gaia sign-in webpage in a new @@ -51,7 +53,8 @@ Browser* browser, signin_metrics::AccessPoint access_point, signin_metrics::PromoAction promo_action, - const std::string& email); + const std::string& email, + const GURL& redirect_url = GURL::EmptyGURL()); #endif // !defined(OS_CHROMEOS) // Shows the modal sync confirmation dialog as a browser-modal dialog on top
diff --git a/chrome/browser/ui/views/location_bar/keyword_hint_view.cc b/chrome/browser/ui/views/location_bar/keyword_hint_view.cc index 5953c58..be2344c 100644 --- a/chrome/browser/ui/views/location_bar/keyword_hint_view.cc +++ b/chrome/browser/ui/views/location_bar/keyword_hint_view.cc
@@ -18,6 +18,7 @@ #include "chrome/browser/ui/views/location_bar/background_with_1_px_border.h" #include "chrome/browser/ui/views/location_bar/location_bar_view.h" #include "chrome/grit/generated_resources.h" +#include "components/omnibox/browser/omnibox_field_trial.h" #include "components/search_engines/template_url_service.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/l10n/l10n_util.h" @@ -39,6 +40,8 @@ chip_label_( new views::Label(base::string16(), CONTEXT_OMNIBOX_DECORATION)), trailing_label_(nullptr) { + const bool experimental_keyword_mode = + OmniboxFieldTrial::IsExperimentalKeywordModeEnabled(); const bool is_newer_material = ui::MaterialDesignController::IsNewerMaterialUi(); SkColor text_color = @@ -57,24 +60,30 @@ : kPaddingInsideBorder + 1; chip_label_->SetBorder( views::CreateEmptyBorder(gfx::Insets(0, horizontal_padding))); - chip_label_->SetEnabledColor(text_color); - bool inverted = color_utils::IsDark(background_color); - SkColor tab_bg_color = - inverted ? SK_ColorWHITE : SkColorSetA(text_color, 0x13); - SkColor tab_border_color = inverted ? SK_ColorWHITE : text_color; + SkColor tab_bg_color = SkColorSetA(text_color, 0x13); + SkColor tab_border_color = text_color; + if (color_utils::IsDark(background_color)) { + tab_bg_color = SK_ColorWHITE; + tab_border_color = SK_ColorWHITE; + } if (is_newer_material) { - tab_bg_color = background_color; tab_border_color = GetOmniboxColor(OmniboxPart::LOCATION_BAR_BUBBLE_OUTLINE, tint); + if (!experimental_keyword_mode) { + tab_bg_color = GetOmniboxColor(OmniboxPart::RESULTS_BACKGROUND, tint); + } else { + tab_bg_color = tab_border_color; + text_color = SK_ColorWHITE; + } } + chip_label_->SetEnabledColor(text_color); chip_label_->SetBackgroundColor(tab_bg_color); - chip_container_->SetBackground(views::CreateSolidBackground(tab_bg_color)); - chip_container_->SetBorder(views::CreateRoundedRectBorder( - 1, GetLayoutConstant(LOCATION_BAR_BUBBLE_CORNER_RADIUS), - tab_border_color)); - + chip_container_->SetBackground(CreateBackgroundFromPainter( + views::Painter::CreateRoundRectWith1PxBorderPainter( + tab_bg_color, tab_border_color, + GetLayoutConstant(LOCATION_BAR_BUBBLE_CORNER_RADIUS)))); chip_container_->AddChildView(chip_label_); chip_container_->SetLayoutManager(std::make_unique<views::FillLayout>()); AddChildView(chip_container_); @@ -91,13 +100,7 @@ KeywordHintView::~KeywordHintView() {} -void KeywordHintView::SetKeyword(const base::string16& keyword, - SkColor background_color) { - if (ui::MaterialDesignController::IsNewerMaterialUi()) { - chip_label_->SetBackgroundColor(background_color); - chip_container_->background()->SetNativeControlColor(background_color); - } - +void KeywordHintView::SetKeyword(const base::string16& keyword) { // When the virtual keyboard is visible, we show a modified touch UI // containing only the chip and no surrounding labels. const bool was_touch_ui = leading_label_->text().empty();
diff --git a/chrome/browser/ui/views/location_bar/keyword_hint_view.h b/chrome/browser/ui/views/location_bar/keyword_hint_view.h index 96285d3..78d46ad 100644 --- a/chrome/browser/ui/views/location_bar/keyword_hint_view.h +++ b/chrome/browser/ui/views/location_bar/keyword_hint_view.h
@@ -35,7 +35,7 @@ OmniboxTint tint); ~KeywordHintView() override; - void SetKeyword(const base::string16& keyword, SkColor background_color); + void SetKeyword(const base::string16& keyword); // views::View: gfx::Insets GetInsets() const override;
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index f3677da..2b2a3ba8 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -590,8 +590,7 @@ trailing_decorations.AddDecoration(vertical_padding, location_height, true, 0, edge_padding, internal_padding, keyword_hint_view_); - keyword_hint_view_->SetKeyword( - keyword, GetOmniboxColor(OmniboxPart::RESULTS_BACKGROUND, tint())); + keyword_hint_view_->SetKeyword(keyword); } add_trailing_decoration(clear_all_button_);
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.cc b/chrome/browser/ui/views/overlay/overlay_window_views.cc index b2ae2fe..b37ab7c2 100644 --- a/chrome/browser/ui/views/overlay/overlay_window_views.cc +++ b/chrome/browser/ui/views/overlay/overlay_window_views.cc
@@ -439,10 +439,16 @@ void OverlayWindowViews::UpdateControlsPositions() { int mid_window_x = GetBounds().size().width() / 2; + + // The controls should always be centered, regardless of how many there are. + // When there are only two controls, make them symmetric from the center. + // __________________________ + // | | + // | | + // | [1] [P] | + // | | + // |__________________________| if (OnlyOneCustomControlAdded()) { - // Draw |first_custom_controls_view_| to the left of - // |play_pause_controls_view_| and offset both so they are centered on the - // screen. play_pause_controls_view_->SetBoundsRect( CalculateControlsBounds(mid_window_x, button_size_)); first_custom_controls_view_->SetBoundsRect(CalculateControlsBounds( @@ -450,13 +456,19 @@ return; } + // Place the play / pause control in the center of the window. If both custom + // controls are specified, place them on either side to maintain the balance, + // from left to right. + // __________________________ + // | | + // | | + // | [1] [P] [2] | + // | | + // |__________________________| play_pause_controls_view_->SetBoundsRect(CalculateControlsBounds( mid_window_x - button_size_.width() / 2, button_size_)); if (first_custom_controls_view_ && second_custom_controls_view_) { - // Draw |first_custom_controls_view_| to the left and - // |second_custom_controls_view_| to the right of - // |play_pause_controls_view_|. first_custom_controls_view_->SetBoundsRect(CalculateControlsBounds( mid_window_x - button_size_.width() / 2 - button_size_.width(), button_size_));
diff --git a/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc b/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc index 2f8e2f6..510d8bb 100644 --- a/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc +++ b/chrome/browser/ui/views/toolbar/browser_actions_container_browsertest.cc
@@ -18,7 +18,6 @@ #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_action_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" -#include "chrome/test/views/scoped_macviews_browser_mode.h" #include "extensions/browser/extension_prefs.h" #include "extensions/browser/extension_registry.h" #include "extensions/common/extension.h" @@ -267,8 +266,6 @@ void SetUpOnMainThread() override; void TearDownOnMainThread() override; - test::ScopedMacViewsBrowserMode views_mode_{true}; - // The main BrowserActionsContainer (owned by the browser view). BrowserActionsContainer* main_bar_;
diff --git a/chrome/browser/ui/webui/about_ui.cc b/chrome/browser/ui/webui/about_ui.cc index 81841eb..6efb0ca 100644 --- a/chrome/browser/ui/webui/about_ui.cc +++ b/chrome/browser/ui/webui/about_ui.cc
@@ -78,6 +78,7 @@ #if defined(OS_CHROMEOS) #include <map> +#include "base/base64.h" #include "base/stl_util.h" #include "base/strings/strcat.h" #include "chrome/browser/browser_process_platform_part_chromeos.h" @@ -203,6 +204,13 @@ FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE}, base::BindOnce(&ChromeOSTermsHandler::LoadArcTermsFileAsync, this), base::BindOnce(&ChromeOSTermsHandler::ResponseOnUIThread, this)); + } else if (path_ == chrome::kArcPrivacyPolicyURLPath) { + // Load ARC++ privacy policy from the file. + base::PostTaskWithTraitsAndReply( + FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE}, + base::BindOnce(&ChromeOSTermsHandler::LoadArcPrivacyPolicyFileAsync, + this), + base::BindOnce(&ChromeOSTermsHandler::ResponseOnUIThread, this)); } else { // Load local ChromeOS terms from the file. base::PostTaskWithTraitsAndReply( @@ -247,49 +255,76 @@ } } + void LoadArcPrivacyPolicyFileAsync() { + base::ScopedBlockingCall scoped_blocking_call( + base::BlockingType::MAY_BLOCK); + + for (const auto& locale : CreateArcLocaleLookupArray()) { + auto path = CreateArcPrivacyPolicyPath(locale.c_str()); + std::string contents; + if (base::ReadFileToString(path, &contents)) { + base::Base64Encode(contents, &contents_); + VLOG(1) << "Read offline Play Store privacy policy for: " << locale; + return; + } + LOG(WARNING) << "Could not find offline Play Store privacy policy for: " + << locale; + } + LOG(ERROR) << "Failed to load offline Play Store privacy policy"; + contents_.clear(); + } + void LoadArcTermsFileAsync() { base::ScopedBlockingCall scoped_blocking_call( base::BlockingType::MAY_BLOCK); - const CountryRegionMap kCountryRegionMap = CreateCountryRegionMap(); - const std::string kDeviceRegion = ReadDeviceRegionFromVpd(); - // To determine version of Play Store ToS: - // * try to match language and device region combination - // * if not found check the mapping to default region (APAC, EMEA, EU) - // * if no default region mapping default to en-US - // Note: AMERICAS region defaults to en-US and to simplify it is not - // included in the country region map. - const std::string locale_region = base::StrCat( - {base::ToLowerASCII(language::ExtractBaseLanguage(locale_)), "-", - kDeviceRegion}); - if (base::ReadFileToString(CreateArcTermsPath(locale_region), &contents_)) - return; - - const auto region = kCountryRegionMap.find(kDeviceRegion); - if (region != kCountryRegionMap.end()) { - LOG(WARNING) << "Could not find offline Play Store ToS for: " - << locale_region << ". Trying by region: " << region->second; - if (base::ReadFileToString(CreateArcTermsPath(region->second.c_str()), - &contents_)) { + for (const auto& locale : CreateArcLocaleLookupArray()) { + auto path = CreateArcTermsPath(locale.c_str()); + std::string contents; + if (base::ReadFileToString(CreateArcTermsPath(locale), &contents_)) { + VLOG(1) << "Read offline Play Store terms for: " << locale; return; } + LOG(WARNING) << "Could not find offline Play Store terms for: " << locale; } - - LOG(WARNING) << "Could not find offline Play Store ToS by locale nor " - "region for: " - << locale_region << ". Loading: en-US"; - if (base::ReadFileToString(CreateArcTermsPath("en-us"), &contents_)) - return; - LOG(ERROR) << "Failed to load offline Play Store ToS"; contents_.clear(); } + std::vector<std::string> CreateArcLocaleLookupArray() { + // To get Play Store asset we look for the first locale match in the + // following order: + // * language and device region combination + // * default region (APAC, EMEA, EU) + // * en-US + // Note: AMERICAS region defaults to en-US and to simplify it is not + // included in the country region map. + std::vector<std::string> locale_lookup_array; + const std::string device_region = ReadDeviceRegionFromVpd(); + locale_lookup_array.push_back(base::StrCat( + {base::ToLowerASCII(language::ExtractBaseLanguage(locale_)), "-", + device_region})); + + const CountryRegionMap country_region_map = CreateCountryRegionMap(); + const auto region = country_region_map.find(device_region); + if (region != country_region_map.end()) { + locale_lookup_array.push_back(region->second.c_str()); + } + + locale_lookup_array.push_back("en-us"); + return locale_lookup_array; + } + base::FilePath CreateArcTermsPath(const std::string& locale) const { return chromeos_assets_path_.Append( base::StringPrintf(chrome::kArcTermsPathFormat, locale.c_str())); } + base::FilePath CreateArcPrivacyPolicyPath(const std::string& locale) const { + return chromeos_assets_path_.Append(base::StringPrintf( + chrome::kArcPrivacyPolicyPathFormat, locale.c_str())); + } + void ResponseOnUIThread() { DCHECK_CURRENTLY_ON(BrowserThread::UI); // If we fail to load Chrome OS EULA from disk, load it from resources.
diff --git a/chrome/browser/ui/webui/about_ui_unittest.cc b/chrome/browser/ui/webui/about_ui_unittest.cc index 951b965f..73b4632 100644 --- a/chrome/browser/ui/webui/about_ui_unittest.cc +++ b/chrome/browser/ui/webui/about_ui_unittest.cc
@@ -7,6 +7,7 @@ #include <memory> #include <string> +#include "base/base64.h" #include "base/bind.h" #include "base/files/file_path.h" #include "base/files/file_util.h" @@ -39,6 +40,12 @@ std::string data() const { return data_; } + std::string Base64DecodedData() const { + std::string decoded; + base::Base64Decode(data_, &decoded); + return decoded; + } + void OnDataReceived(scoped_refptr<base::RefCountedMemory> bytes) { data_received_ = true; data_ = base::StringPiece(reinterpret_cast<const char*>(bytes->front()), @@ -55,6 +62,7 @@ } // namespace +// Base class for ChromeOS offline terms tests. class ChromeOSTermsTest : public testing::Test { protected: ChromeOSTermsTest() @@ -90,17 +98,32 @@ return true; } + // Creates directory for the given |locale| that contains privacy_policy.pdf. + // Writes the |locale| string to the created file. + bool CreatePrivacyPolicyForLocale(const std::string& locale) { + base::FilePath dir = arc_tos_dir_.Append(base::ToLowerASCII(locale)); + if (!base::CreateDirectory(dir)) + return false; + + if (base::WriteFile(dir.AppendASCII("privacy_policy.pdf"), locale.c_str(), + locale.length()) != static_cast<int>(locale.length())) { + return false; + } + return true; + } + // Sets device region in VPD. void SetRegion(const std::string& region) { statistics_provider_.SetMachineStatistic(chromeos::system::kRegionKey, region); } - // Starts data request. - void StartRequest(TestDataReceiver* data_receiver) { + // Starts data request with the |request_url|. + void StartRequest(const std::string& request_url, + TestDataReceiver* data_receiver) { content::ResourceRequestInfo::WebContentsGetter wc_getter; tested_html_source_->StartDataRequest( - chrome::kArcTermsURLPath, std::move(wc_getter), + request_url, std::move(wc_getter), base::BindRepeating(&TestDataReceiver::OnDataReceived, base::Unretained(data_receiver))); scoped_task_environment_.RunUntilIdle(); @@ -124,13 +147,20 @@ SetRegion("ca"); ScopedBrowserLocale browser_locale("en-CA"); - TestDataReceiver data_receiver; - StartRequest(&data_receiver); + TestDataReceiver terms_data_receiver; + StartRequest(chrome::kArcTermsURLPath, &terms_data_receiver); - EXPECT_TRUE(data_receiver.data_received()); - EXPECT_EQ("", data_receiver.data()); + EXPECT_TRUE(terms_data_receiver.data_received()); + EXPECT_EQ("", terms_data_receiver.data()); + + TestDataReceiver privacy_policy_data_receiver; + StartRequest(chrome::kArcPrivacyPolicyURLPath, &privacy_policy_data_receiver); + + EXPECT_TRUE(privacy_policy_data_receiver.data_received()); + EXPECT_EQ("", privacy_policy_data_receiver.data()); } +// Demo mode ARC++ ToS and privacy policy test. class DemoModeChromeOSTermsTest : public ChromeOSTermsTest { protected: DemoModeChromeOSTermsTest() = default; @@ -161,19 +191,33 @@ ASSERT_TRUE(CreateTermsForLocale("nl-BE")); ASSERT_TRUE(CreateTermsForLocale("nl-NL")); ASSERT_TRUE(CreateTermsForLocale("sv-SE")); + + ASSERT_TRUE(CreatePrivacyPolicyForLocale("da-DK")); + ASSERT_TRUE(CreatePrivacyPolicyForLocale("de-de")); + ASSERT_TRUE(CreatePrivacyPolicyForLocale("en-US")); + ASSERT_TRUE(CreatePrivacyPolicyForLocale("eu")); + ASSERT_TRUE(CreatePrivacyPolicyForLocale("fi-FI")); + ASSERT_TRUE(CreatePrivacyPolicyForLocale("fr-BE")); + ASSERT_TRUE(CreatePrivacyPolicyForLocale("fr-CA")); + ASSERT_TRUE(CreatePrivacyPolicyForLocale("fr-FR")); + ASSERT_TRUE(CreatePrivacyPolicyForLocale("ko-KR")); + ASSERT_TRUE(CreatePrivacyPolicyForLocale("nb-NO")); + ASSERT_TRUE(CreatePrivacyPolicyForLocale("nl-BE")); + ASSERT_TRUE(CreatePrivacyPolicyForLocale("nl-NL")); + ASSERT_TRUE(CreatePrivacyPolicyForLocale("sv-SE")); } private: DISALLOW_COPY_AND_ASSIGN(DemoModeChromeOSTermsTest); }; -TEST_F(DemoModeChromeOSTermsTest, SimpleRegion) { +TEST_F(DemoModeChromeOSTermsTest, TermsSimpleRegion) { SetRegion("ca"); for (const char* locale : {"en-CA", "fr-CA"}) { ScopedBrowserLocale browser_locale(locale); TestDataReceiver data_receiver; - StartRequest(&data_receiver); + StartRequest(chrome::kArcTermsURLPath, &data_receiver); EXPECT_TRUE(data_receiver.data_received()); EXPECT_EQ(locale, data_receiver.data()); @@ -187,11 +231,18 @@ {"ca.hybridansi", "ca.ansi", "ca.multix", "ca.fr"}) { SetRegion(region); - TestDataReceiver data_receiver; - StartRequest(&data_receiver); + TestDataReceiver terms_data_receiver; + StartRequest(chrome::kArcTermsURLPath, &terms_data_receiver); - EXPECT_TRUE(data_receiver.data_received()); - EXPECT_EQ(kLocale, data_receiver.data()); + EXPECT_TRUE(terms_data_receiver.data_received()); + EXPECT_EQ(kLocale, terms_data_receiver.data()); + + TestDataReceiver privacy_data_receiver; + StartRequest(chrome::kArcPrivacyPolicyURLPath, &privacy_data_receiver); + + // Privacy policy for en-CA defaults to en-US. + EXPECT_TRUE(privacy_data_receiver.data_received()); + EXPECT_EQ("en-US", privacy_data_receiver.Base64DecodedData()); } } @@ -200,72 +251,112 @@ for (const char* locale : {"EN-CA", "en-CA", "EN-ca"}) { ScopedBrowserLocale browser_locale(locale); - TestDataReceiver data_receiver; - StartRequest(&data_receiver); + TestDataReceiver terms_data_receiver; + StartRequest(chrome::kArcTermsURLPath, &terms_data_receiver); - EXPECT_TRUE(data_receiver.data_received()); - EXPECT_EQ("en-CA", data_receiver.data()); + EXPECT_TRUE(terms_data_receiver.data_received()); + EXPECT_EQ("en-CA", terms_data_receiver.data()); + + TestDataReceiver privacy_data_receiver; + StartRequest(chrome::kArcPrivacyPolicyURLPath, &privacy_data_receiver); + + // Privacy policy for en-CA defaults to en-US. + EXPECT_TRUE(privacy_data_receiver.data_received()); + EXPECT_EQ("en-US", privacy_data_receiver.Base64DecodedData()); } } -TEST_F(DemoModeChromeOSTermsTest, DefaultToEuRegion) { +TEST_F(DemoModeChromeOSTermsTest, DefaultsForEuRegion) { const std::string kLocale = "pl-PL"; ScopedBrowserLocale browser_locale(kLocale); SetRegion("pl"); - TestDataReceiver data_receiver; - StartRequest(&data_receiver); + TestDataReceiver terms_data_receiver; + StartRequest(chrome::kArcTermsURLPath, &terms_data_receiver); - EXPECT_TRUE(data_receiver.data_received()); - EXPECT_EQ("eu", data_receiver.data()); + EXPECT_TRUE(terms_data_receiver.data_received()); + EXPECT_EQ("eu", terms_data_receiver.data()); + + TestDataReceiver privacy_data_receiver; + StartRequest(chrome::kArcPrivacyPolicyURLPath, &privacy_data_receiver); + + EXPECT_TRUE(privacy_data_receiver.data_received()); + EXPECT_EQ("eu", privacy_data_receiver.Base64DecodedData()); } -TEST_F(DemoModeChromeOSTermsTest, DefaultToEmeaRegion) { +TEST_F(DemoModeChromeOSTermsTest, DefaultsForEmeaRegion) { const std::string kLocale = "fr-CH"; ScopedBrowserLocale browser_locale(kLocale); SetRegion("ch"); - TestDataReceiver data_receiver; - StartRequest(&data_receiver); + TestDataReceiver terms_data_receiver; + StartRequest(chrome::kArcTermsURLPath, &terms_data_receiver); - EXPECT_TRUE(data_receiver.data_received()); - EXPECT_EQ("emea", data_receiver.data()); + EXPECT_TRUE(terms_data_receiver.data_received()); + EXPECT_EQ("emea", terms_data_receiver.data()); + + TestDataReceiver privacy_data_receiver; + StartRequest(chrome::kArcPrivacyPolicyURLPath, &privacy_data_receiver); + + // Privacy policy for EMEA defaults to en-US. + EXPECT_TRUE(privacy_data_receiver.data_received()); + EXPECT_EQ("en-US", privacy_data_receiver.Base64DecodedData()); } -TEST_F(DemoModeChromeOSTermsTest, DefaultToApacRegion) { +TEST_F(DemoModeChromeOSTermsTest, DefaultsForApacRegion) { const std::string kLocale = "en-PH"; ScopedBrowserLocale browser_locale(kLocale); SetRegion("ph"); - TestDataReceiver data_receiver; - StartRequest(&data_receiver); + TestDataReceiver terms_data_receiver; + StartRequest(chrome::kArcTermsURLPath, &terms_data_receiver); - EXPECT_TRUE(data_receiver.data_received()); - EXPECT_EQ("apac", data_receiver.data()); + EXPECT_TRUE(terms_data_receiver.data_received()); + EXPECT_EQ("apac", terms_data_receiver.data()); + + TestDataReceiver privacy_data_receiver; + StartRequest(chrome::kArcPrivacyPolicyURLPath, &privacy_data_receiver); + + // Privacy policy for APAC defaults to en-US. + EXPECT_TRUE(privacy_data_receiver.data_received()); + EXPECT_EQ("en-US", privacy_data_receiver.Base64DecodedData()); } -TEST_F(DemoModeChromeOSTermsTest, DefaultToAmericasRegion) { +TEST_F(DemoModeChromeOSTermsTest, DefaultsForAmericasRegion) { const std::string kLocale = "en-MX"; ScopedBrowserLocale browser_locale(kLocale); SetRegion("mx"); - TestDataReceiver data_receiver; - StartRequest(&data_receiver); + // Both ToS and privacy policy default to en-US for AMERICAS. + TestDataReceiver terms_data_receiver; + StartRequest(chrome::kArcTermsURLPath, &terms_data_receiver); - EXPECT_TRUE(data_receiver.data_received()); - EXPECT_EQ("en-US", data_receiver.data()); + EXPECT_TRUE(terms_data_receiver.data_received()); + EXPECT_EQ("en-US", terms_data_receiver.data()); + + TestDataReceiver privacy_data_receiver; + StartRequest(chrome::kArcPrivacyPolicyURLPath, &privacy_data_receiver); + + EXPECT_TRUE(privacy_data_receiver.data_received()); + EXPECT_EQ("en-US", privacy_data_receiver.Base64DecodedData()); } -TEST_F(DemoModeChromeOSTermsTest, DefaultToEnUs) { +TEST_F(DemoModeChromeOSTermsTest, DefaultsToEnUs) { const std::string kLocale = "en-SA"; ScopedBrowserLocale browser_locale(kLocale); SetRegion("sa"); - TestDataReceiver data_receiver; - StartRequest(&data_receiver); + TestDataReceiver terms_data_receiver; + StartRequest(chrome::kArcTermsURLPath, &terms_data_receiver); - EXPECT_TRUE(data_receiver.data_received()); - EXPECT_EQ("en-US", data_receiver.data()); + EXPECT_TRUE(terms_data_receiver.data_received()); + EXPECT_EQ("en-US", terms_data_receiver.data()); + + TestDataReceiver privacy_data_receiver; + StartRequest(chrome::kArcPrivacyPolicyURLPath, &privacy_data_receiver); + + EXPECT_TRUE(privacy_data_receiver.data_received()); + EXPECT_EQ("en-US", privacy_data_receiver.Base64DecodedData()); } TEST_F(DemoModeChromeOSTermsTest, NoLangCountryCombination) { @@ -274,22 +365,34 @@ const std::string kLocale = "nl-BE"; ScopedBrowserLocale browser_locale(kLocale); - TestDataReceiver data_receiver; - StartRequest(&data_receiver); + TestDataReceiver terms_data_receiver; + StartRequest(chrome::kArcTermsURLPath, &terms_data_receiver); - EXPECT_TRUE(data_receiver.data_received()); - EXPECT_EQ(kLocale, data_receiver.data()); + EXPECT_TRUE(terms_data_receiver.data_received()); + EXPECT_EQ(kLocale, terms_data_receiver.data()); + + TestDataReceiver privacy_data_receiver; + StartRequest(chrome::kArcPrivacyPolicyURLPath, &privacy_data_receiver); + + EXPECT_TRUE(privacy_data_receiver.data_received()); + EXPECT_EQ(kLocale, privacy_data_receiver.Base64DecodedData()); } { const std::string kLocale = "de-BE"; ScopedBrowserLocale browser_locale(kLocale); - TestDataReceiver data_receiver; - StartRequest(&data_receiver); + TestDataReceiver terms_data_receiver; + StartRequest(chrome::kArcTermsURLPath, &terms_data_receiver); // No language - country combination - defaults to region. - EXPECT_TRUE(data_receiver.data_received()); - EXPECT_EQ("eu", data_receiver.data()); + EXPECT_TRUE(terms_data_receiver.data_received()); + EXPECT_EQ("eu", terms_data_receiver.data()); + + TestDataReceiver privacy_data_receiver; + StartRequest(chrome::kArcPrivacyPolicyURLPath, &privacy_data_receiver); + + EXPECT_TRUE(privacy_data_receiver.data_received()); + EXPECT_EQ("eu", privacy_data_receiver.Base64DecodedData()); } } @@ -298,11 +401,17 @@ ScopedBrowserLocale browser_locale(kLocale); for (const char* region : {"", " ", ".", "..", "-", "xyz"}) { SetRegion(region); - TestDataReceiver data_receiver; - StartRequest(&data_receiver); + TestDataReceiver terms_data_receiver; + StartRequest(chrome::kArcTermsURLPath, &terms_data_receiver); - EXPECT_TRUE(data_receiver.data_received()); - EXPECT_EQ("en-US", data_receiver.data()); + EXPECT_TRUE(terms_data_receiver.data_received()); + EXPECT_EQ("en-US", terms_data_receiver.data()); + + TestDataReceiver privacy_data_receiver; + StartRequest(chrome::kArcPrivacyPolicyURLPath, &privacy_data_receiver); + + EXPECT_TRUE(privacy_data_receiver.data_received()); + EXPECT_EQ("en-US", privacy_data_receiver.Base64DecodedData()); } } @@ -311,10 +420,16 @@ for (const char* locale : {"", " ", ".", "-", "-sv"}) { ScopedBrowserLocale browser_locale(locale); - TestDataReceiver data_receiver; - StartRequest(&data_receiver); + TestDataReceiver terms_data_receiver; + StartRequest(chrome::kArcTermsURLPath, &terms_data_receiver); - EXPECT_TRUE(data_receiver.data_received()); - EXPECT_EQ("eu", data_receiver.data()); + EXPECT_TRUE(terms_data_receiver.data_received()); + EXPECT_EQ("eu", terms_data_receiver.data()); + + TestDataReceiver privacy_data_receiver; + StartRequest(chrome::kArcPrivacyPolicyURLPath, &privacy_data_receiver); + + EXPECT_TRUE(privacy_data_receiver.data_received()); + EXPECT_EQ("eu", privacy_data_receiver.Base64DecodedData()); } }
diff --git a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc index 795785b4..b4d09f5 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_controller_factory.cc
@@ -179,13 +179,13 @@ #include "chrome/browser/ui/webui/signin/signin_email_confirmation_ui.h" #include "chrome/browser/ui/webui/signin/signin_error_ui.h" #include "chrome/browser/ui/webui/signin/sync_confirmation_ui.h" -#include "chrome/browser/ui/webui/welcome_ui.h" +#include "chrome/browser/ui/webui/welcome/welcome_ui.h" #endif #if defined(OS_WIN) #include "chrome/browser/ui/webui/conflicts/conflicts_ui.h" #include "chrome/browser/ui/webui/set_as_default_browser_ui_win.h" -#include "chrome/browser/ui/webui/welcome_win10_ui.h" +#include "chrome/browser/ui/webui/welcome/welcome_win10_ui.h" #endif #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.cc b/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.cc index a0a09f3..3dff4d9 100644 --- a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.cc +++ b/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.cc
@@ -4,9 +4,12 @@ #include "chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_dialog.h" +#include "ash/public/cpp/shell_window_ids.h" #include "base/strings/utf_string_conversions.h" #include "base/sys_info.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/browser_dialogs.h" #include "chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_handler.h" #include "chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_localized_strings_provider.h" #include "chrome/common/url_constants.h" @@ -44,13 +47,20 @@ return; current_instance_ = new MultiDeviceSetupDialog(); - current_instance_->ShowSystemDialog(); + + // TODO(crbug.com/888629): In order to remove the X button on the top right of + // of the dialog, passing |is_minimal_style| == true is required, but as of + // now, that will prevent the dialog from presenting in full screen if tablet + // mode is on. See bug for more details. + chrome::ShowWebDialogInContainer( + ash::kShellWindowId_DefaultContainer /* container_id */, + ProfileManager::GetActiveUserProfile(), current_instance_, + false /* is_minimal_style */); } MultiDeviceSetupDialog::MultiDeviceSetupDialog() - : SystemWebDialogDelegate( - GURL(chrome::kChromeUIMultiDeviceSetupUrl), - l10n_util::GetStringUTF16(IDS_MULTIDEVICE_SETUP_DIALOG_TITLE)) {} + : SystemWebDialogDelegate(GURL(chrome::kChromeUIMultiDeviceSetupUrl), + base::string16()) {} MultiDeviceSetupDialog::~MultiDeviceSetupDialog() = default;
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_localized_strings_provider.cc b/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_localized_strings_provider.cc index ec88028..edd2778 100644 --- a/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/chromeos/multidevice_setup/multidevice_setup_localized_strings_provider.cc
@@ -59,7 +59,6 @@ {"setupSucceededPageMessage", IDS_MULTIDEVICE_SETUP_SETUP_SUCCEEDED_PAGE_MESSAGE}, {"startSetupPageHeader", IDS_MULTIDEVICE_SETUP_START_SETUP_PAGE_HEADER}, - {"title", IDS_MULTIDEVICE_SETUP_DIALOG_TITLE}, {"tryAgain", IDS_MULTIDEVICE_SETUP_TRY_AGAIN_LABEL}, };
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc index c7852d3..6f46b0d 100644 --- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -139,6 +139,9 @@ {"moreActions", IDS_SETTINGS_MORE_ACTIONS}, {"ok", IDS_OK}, {"restart", IDS_SETTINGS_RESTART}, +#if !defined(OS_CHROMEOS) + {"restartToApplyChanges", IDS_SETTINGS_RESTART_TO_APPLY_CHANGES}, +#endif {"retry", IDS_SETTINGS_RETRY}, {"save", IDS_SAVE}, {"settings", IDS_SETTINGS_SETTINGS}, @@ -1641,15 +1644,14 @@ {"cancelSync", IDS_SETTINGS_SYNC_SETTINGS_CANCEL_SYNC}, #endif // defined(OS_CHROMEOS) #if BUILDFLAG(ENABLE_DICE_SUPPORT) - {"peopleSignIn", IDS_SETTINGS_PEOPLE_SIGN_IN}, + {"peopleSignIn", IDS_PROFILES_DICE_SIGNIN_BUTTON}, {"peopleSignOut", IDS_SETTINGS_PEOPLE_SIGN_OUT}, {"peopleSignInPrompt", IDS_SETTINGS_PEOPLE_SIGN_IN_PROMPT}, {"peopleSignInPromptSecondaryWithNoAccount", - IDS_SETTINGS_PEOPLE_SIGN_IN_PROMPT_SECONDARY_WITH_NO_ACCOUNT}, + IDS_SETTINGS_PEOPLE_SIGN_IN_PROMPT_SECONDARY_WITH_ACCOUNT}, {"peopleSignInPromptSecondaryWithAccount", IDS_SETTINGS_PEOPLE_SIGN_IN_PROMPT_SECONDARY_WITH_ACCOUNT}, {"useAnotherAccount", IDS_SETTINGS_PEOPLE_SYNC_ANOTHER_ACCOUNT}, - {"syncAsName", IDS_SETTINGS_PEOPLE_SYNC_AS_NAME}, {"syncingTo", IDS_SETTINGS_PEOPLE_SYNCING_TO_ACCOUNT}, {"turnOffSync", IDS_SETTINGS_PEOPLE_SYNC_TURN_OFF}, {"signInAgain", IDS_SYNC_ERROR_USER_MENU_SIGNIN_AGAIN_BUTTON}, @@ -1972,6 +1974,8 @@ Profile* profile) { LocalizedString localized_strings[] = { {"privacyPageTitle", IDS_SETTINGS_PRIVACY}, + {"signinAllowedTitle", IDS_SETTINGS_SIGNIN_ALLOWED}, + {"signinAllowedDescription", IDS_SETTINGS_SIGNIN_ALLOWED_DESC}, {"doNotTrack", IDS_SETTINGS_ENABLE_DO_NOT_TRACK}, {"doNotTrackDialogTitle", IDS_SETTINGS_ENABLE_DO_NOT_TRACK_DIALOG_TITLE}, {"enableContentProtectionAttestation",
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc b/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc index 38f324c..df687d3 100644 --- a/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc +++ b/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
@@ -134,8 +134,8 @@ title_ids = AccountConsistencyModeManager::IsDiceEnabledForProfile(profile) ? IDS_SYNC_CONFIRMATION_DICE_TITLE : IDS_SYNC_CONFIRMATION_TITLE; - confirm_button_ids = IDS_SYNC_CONFIRMATION_CONFIRM_BUTTON_LABEL; - undo_button_ids = IDS_SYNC_CONFIRMATION_UNDO_BUTTON_LABEL; + confirm_button_ids = IDS_SETTINGS_TURN_ON; + undo_button_ids = IDS_CANCEL; consent_feature_ = consent_auditor::Feature::CHROME_SYNC; if (!is_sync_allowed) { title_ids = IDS_SYNC_DISABLED_CONFIRMATION_CHROME_SYNC_TITLE;
diff --git a/chrome/browser/ui/webui/welcome_handler.cc b/chrome/browser/ui/webui/welcome/welcome_handler.cc similarity index 83% rename from chrome/browser/ui/webui/welcome_handler.cc rename to chrome/browser/ui/webui/welcome/welcome_handler.cc index b092abfb..7c80873 100644 --- a/chrome/browser/ui/webui/welcome_handler.cc +++ b/chrome/browser/ui/webui/welcome/welcome_handler.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/webui/welcome_handler.h" +#include "chrome/browser/ui/webui/welcome/welcome_handler.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" @@ -18,6 +18,8 @@ #include "services/identity/public/cpp/identity_manager.h" #include "ui/base/page_transition_types.h" +const char kWelcomeReturningUserUrl[] = "chrome://welcome/returning-user"; + WelcomeHandler::WelcomeHandler(content::WebUI* web_ui) : profile_(Profile::FromWebUI(web_ui)), login_ui_service_(LoginUIServiceFactory::GetForProfile(profile_)), @@ -44,7 +46,13 @@ LoginUIService::SyncConfirmationUIClosedResult result) { if (result != LoginUIService::ABORT_SIGNIN) { result_ = WelcomeResult::SIGNED_IN; - GoToNewTabPage(); + + // When signed in from NUX onboarding flow, it's possible to come back to + // chrome://welcome/... after closing sync-confirmation UI. If current URL + // matches such a case, do not navigate away. + GURL current_url = web_ui()->GetWebContents()->GetVisibleURL(); + if (current_url != kWelcomeReturningUserUrl) + GoToNewTabPage(); } } @@ -60,10 +68,18 @@ // them away to the NTP instead. GoToNewTabPage(); } else { + GURL redirect_url = GURL::EmptyGURL(); + if (args->GetSize() == 1U) { + std::string url_string; + CHECK(args->GetString(0, &url_string)); + redirect_url = GURL(url_string); + DCHECK(redirect_url.is_valid()); + } + Browser* browser = GetBrowser(); browser->signin_view_controller()->ShowSignin( profiles::BubbleViewMode::BUBBLE_VIEW_MODE_GAIA_SIGNIN, browser, - signin_metrics::AccessPoint::ACCESS_POINT_START_PAGE); + signin_metrics::AccessPoint::ACCESS_POINT_START_PAGE, redirect_url); } }
diff --git a/chrome/browser/ui/webui/welcome_handler.h b/chrome/browser/ui/webui/welcome/welcome_handler.h similarity index 89% rename from chrome/browser/ui/webui/welcome_handler.h rename to chrome/browser/ui/webui/welcome/welcome_handler.h index b685467..7959b417 100644 --- a/chrome/browser/ui/webui/welcome_handler.h +++ b/chrome/browser/ui/webui/welcome/welcome_handler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_WEBUI_WELCOME_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_WELCOME_HANDLER_H_ +#ifndef CHROME_BROWSER_UI_WEBUI_WELCOME_WELCOME_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_WELCOME_WELCOME_HANDLER_H_ #include "base/macros.h" #include "chrome/browser/ui/webui/signin/login_ui_service.h" @@ -57,4 +57,4 @@ DISALLOW_COPY_AND_ASSIGN(WelcomeHandler); }; -#endif // CHROME_BROWSER_UI_WEBUI_WELCOME_HANDLER_H_ +#endif // CHROME_BROWSER_UI_WEBUI_WELCOME_WELCOME_HANDLER_H_
diff --git a/chrome/browser/ui/webui/welcome_ui.cc b/chrome/browser/ui/webui/welcome/welcome_ui.cc similarity index 97% rename from chrome/browser/ui/webui/welcome_ui.cc rename to chrome/browser/ui/webui/welcome/welcome_ui.cc index 95e1a67..501dbc7 100644 --- a/chrome/browser/ui/webui/welcome_ui.cc +++ b/chrome/browser/ui/webui/welcome/welcome_ui.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/webui/welcome_ui.h" +#include "chrome/browser/ui/webui/welcome/welcome_ui.h" #include <memory> #include <string> @@ -11,7 +11,7 @@ #include "chrome/browser/favicon/favicon_service_factory.h" #include "chrome/browser/signin/account_consistency_mode_manager.h" #include "chrome/browser/ui/webui/welcome/nux_helper.h" -#include "chrome/browser/ui/webui/welcome_handler.h" +#include "chrome/browser/ui/webui/welcome/welcome_handler.h" #include "chrome/common/pref_names.h" #include "chrome/grit/browser_resources.h" #include "chrome/grit/chrome_unscaled_resources.h" @@ -34,13 +34,13 @@ #endif // defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD) namespace { - const bool kIsBranded = +const bool kIsBranded = #if defined(GOOGLE_CHROME_BUILD) - true; + true; #else - false; + false; #endif -} +} // namespace WelcomeUI::WelcomeUI(content::WebUI* web_ui, const GURL& url) : content::WebUIController(web_ui) {
diff --git a/chrome/browser/ui/webui/welcome_ui.h b/chrome/browser/ui/webui/welcome/welcome_ui.h similarity index 82% rename from chrome/browser/ui/webui/welcome_ui.h rename to chrome/browser/ui/webui/welcome/welcome_ui.h index 7ff85eb..acadd2f 100644 --- a/chrome/browser/ui/webui/welcome_ui.h +++ b/chrome/browser/ui/webui/welcome/welcome_ui.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_WEBUI_WELCOME_UI_H_ -#define CHROME_BROWSER_UI_WEBUI_WELCOME_UI_H_ +#ifndef CHROME_BROWSER_UI_WEBUI_WELCOME_WELCOME_UI_H_ +#define CHROME_BROWSER_UI_WEBUI_WELCOME_WELCOME_UI_H_ #include "chrome/browser/profiles/profile.h" #include "content/public/browser/web_ui_controller.h" @@ -22,4 +22,4 @@ void StorePageSeen(Profile* profile, const GURL& url); }; -#endif // CHROME_BROWSER_UI_WEBUI_WELCOME_UI_H_ +#endif // CHROME_BROWSER_UI_WEBUI_WELCOME_WELCOME_UI_H_
diff --git a/chrome/browser/ui/webui/welcome_win10_handler.cc b/chrome/browser/ui/webui/welcome/welcome_win10_handler.cc similarity index 98% rename from chrome/browser/ui/webui/welcome_win10_handler.cc rename to chrome/browser/ui/webui/welcome/welcome_win10_handler.cc index da5eeb1..f629bf3 100644 --- a/chrome/browser/ui/webui/welcome_win10_handler.cc +++ b/chrome/browser/ui/webui/welcome/welcome_win10_handler.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/webui/welcome_win10_handler.h" +#include "chrome/browser/ui/webui/welcome/welcome_win10_handler.h" #include "base/bind.h" #include "base/metrics/histogram_functions.h"
diff --git a/chrome/browser/ui/webui/welcome_win10_handler.h b/chrome/browser/ui/webui/welcome/welcome_win10_handler.h similarity index 91% rename from chrome/browser/ui/webui/welcome_win10_handler.h rename to chrome/browser/ui/webui/welcome/welcome_win10_handler.h index 70a09709..504dada 100644 --- a/chrome/browser/ui/webui/welcome_win10_handler.h +++ b/chrome/browser/ui/webui/welcome/welcome_win10_handler.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_WEBUI_WELCOME_WIN10_HANDLER_H_ -#define CHROME_BROWSER_UI_WEBUI_WELCOME_WIN10_HANDLER_H_ +#ifndef CHROME_BROWSER_UI_WEBUI_WELCOME_WELCOME_WIN10_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_WELCOME_WELCOME_WIN10_HANDLER_H_ #include <string> @@ -64,4 +64,4 @@ DISALLOW_COPY_AND_ASSIGN(WelcomeWin10Handler); }; -#endif // CHROME_BROWSER_UI_WEBUI_WELCOME_WIN10_HANDLER_H_ +#endif // CHROME_BROWSER_UI_WEBUI_WELCOME_WELCOME_WIN10_HANDLER_H_
diff --git a/chrome/browser/ui/webui/welcome_win10_ui.cc b/chrome/browser/ui/webui/welcome/welcome_win10_ui.cc similarity index 97% rename from chrome/browser/ui/webui/welcome_win10_ui.cc rename to chrome/browser/ui/webui/welcome/welcome_win10_ui.cc index 018ed4d..111b5be 100644 --- a/chrome/browser/ui/webui/welcome_win10_ui.cc +++ b/chrome/browser/ui/webui/welcome/welcome_win10_ui.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/webui/welcome_win10_ui.h" +#include "chrome/browser/ui/webui/welcome/welcome_win10_ui.h" #include <memory> #include <string> @@ -10,7 +10,7 @@ #include "base/feature_list.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/webui/welcome_win10_handler.h" +#include "chrome/browser/ui/webui/welcome/welcome_win10_handler.h" #include "chrome/common/chrome_features.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/webui/welcome_win10_ui.h b/chrome/browser/ui/webui/welcome/welcome_win10_ui.h similarity index 75% rename from chrome/browser/ui/webui/welcome_win10_ui.h rename to chrome/browser/ui/webui/welcome/welcome_win10_ui.h index 21c926d..08c97ead 100644 --- a/chrome/browser/ui/webui/welcome_win10_ui.h +++ b/chrome/browser/ui/webui/welcome/welcome_win10_ui.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_WEBUI_WELCOME_WIN10_UI_H_ -#define CHROME_BROWSER_UI_WEBUI_WELCOME_WIN10_UI_H_ +#ifndef CHROME_BROWSER_UI_WEBUI_WELCOME_WELCOME_WIN10_UI_H_ +#define CHROME_BROWSER_UI_WEBUI_WELCOME_WELCOME_WIN10_UI_H_ #include "content/public/browser/web_ui_controller.h" @@ -18,4 +18,4 @@ ~WelcomeWin10UI() override; }; -#endif // CHROME_BROWSER_UI_WEBUI_WELCOME_WIN10_UI_H_ +#endif // CHROME_BROWSER_UI_WEBUI_WELCOME_WELCOME_WIN10_UI_H_
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 201b0ef..d203e86 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -2217,6 +2217,10 @@ // Whether profile can be used before sign in. const char kForceBrowserSignin[] = "profile.force_browser_signin"; +// Boolean which indicates if the user is allowed to sign into Chrome on the +// next startup. +const char kSigninAllowedOnNextStartup[] = "signin.allowed_on_next_startup"; + // Device identifier used by CryptAuth stored in local state. This ID is // combined with a user ID before being registered with the CryptAuth server, // so it can't correlate users on the same device.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index d8ffbc0..c5346b3 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -769,6 +769,7 @@ extern const char kBrowserGuestModeEnabled[]; extern const char kBrowserAddPersonEnabled[]; extern const char kForceBrowserSignin[]; +extern const char kSigninAllowedOnNextStartup[]; extern const char kCryptAuthDeviceId[]; extern const char kEasyUnlockHardlockState[];
diff --git a/chrome/common/url_constants.cc b/chrome/common/url_constants.cc index 84842846..7a1395c 100644 --- a/chrome/common/url_constants.cc +++ b/chrome/common/url_constants.cc
@@ -271,6 +271,8 @@ const char kArcTermsPathFormat[] = "arc_tos/%s/terms.html"; +const char kArcPrivacyPolicyPathFormat[] = "arc_tos/%s/privacy_policy.pdf"; + const char kEolNotificationURL[] = "https://www.google.com/chromebook/older/"; const char kGoogleNameserversLearnMoreURL[] = @@ -302,7 +304,9 @@ const char kOemEulaURLPath[] = "oem"; -const char kArcTermsURLPath[] = "arc"; +const char kArcTermsURLPath[] = "arc/terms"; + +const char kArcPrivacyPolicyURLPath[] = "arc/privacy_policy"; const char kOnlineEulaURLPath[] = "https://www.google.com/intl/%s/chrome/eula_text.html";
diff --git a/chrome/common/url_constants.h b/chrome/common/url_constants.h index 966f9d36..7ddffa8e 100644 --- a/chrome/common/url_constants.h +++ b/chrome/common/url_constants.h
@@ -223,6 +223,10 @@ // Relative to |kChromeOSAssetPath|. extern const char kArcTermsPathFormat[]; +// The path format to the localized offline ARC++ Privacy Policy. +// Relative to |kChromeOSAssetPath|. +extern const char kArcPrivacyPolicyPathFormat[]; + // The URL for EOL notification extern const char kEolNotificationURL[]; @@ -256,9 +260,12 @@ // The URL path to offline OEM EULA. extern const char kOemEulaURLPath[]; -// THE URL path to offline ARC++ Terms of Service. +// The URL path to offline ARC++ Terms of Service. extern const char kArcTermsURLPath[]; +// The URL path to offline ARC++ Privacy Policy. +extern const char kArcPrivacyPolicyURLPath[]; + extern const char kOnlineEulaURLPath[]; // The URL for the "learn more" link for TPM firmware update.
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 5e62636..186a805 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -4115,9 +4115,6 @@ # the place this variable is used below. if (true) { cocoa_test_sources = [ - "../browser/ui/cocoa/animatable_image_unittest.mm", - "../browser/ui/cocoa/animatable_view_unittest.mm", - "../browser/ui/cocoa/background_gradient_view_unittest.mm", "../browser/ui/cocoa/bookmarks/bookmark_menu_bridge_unittest.mm", "../browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller_unittest.mm", "../browser/ui/cocoa/browser_window_cocoa_unittest.mm", @@ -4144,14 +4141,10 @@ "../browser/ui/cocoa/profiles/profile_menu_controller_unittest.mm", "../browser/ui/cocoa/scoped_menu_bar_lock_unittest.mm", "../browser/ui/cocoa/status_icons/status_icon_mac_unittest.mm", - "../browser/ui/cocoa/styled_text_field_cell_unittest.mm", - "../browser/ui/cocoa/styled_text_field_unittest.mm", "../browser/ui/cocoa/tabbed_browser_window_unittest.mm", "../browser/ui/cocoa/test/cocoa_profile_test.h", "../browser/ui/cocoa/test/cocoa_profile_test.mm", "../browser/ui/cocoa/test/run_loop_testing_unittest.mm", - "../browser/ui/cocoa/test/styled_text_field_test_helper.h", - "../browser/ui/cocoa/test/styled_text_field_test_helper.mm", "../browser/ui/cocoa/touchbar/browser_window_default_touch_bar_unittest.mm", "../browser/ui/cocoa/touchbar/credit_card_autofill_touch_bar_controller_unittest.mm", "../browser/ui/cocoa/touchbar/text_suggestions_touch_bar_controller_unittest.mm",
diff --git a/chrome/test/chromedriver/logging.cc b/chrome/test/chromedriver/logging.cc index 665a3a6b..8e3beaf 100644 --- a/chrome/test/chromedriver/logging.cc +++ b/chrome/test/chromedriver/logging.cc
@@ -236,15 +236,20 @@ bool InitLogging() { g_start_time = base::TimeTicks::Now().ToInternalValue(); - base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess(); + if (cmd_line->HasSwitch("log-path")) { g_log_level = Log::kInfo; base::FilePath log_path = cmd_line->GetSwitchValuePath("log-path"); + + const base::FilePath::CharType* logMode = FILE_PATH_LITERAL("w"); + if (cmd_line->HasSwitch("append-log")) { + logMode = FILE_PATH_LITERAL("a"); + } #if defined(OS_WIN) - FILE* redir_stderr = _wfreopen(log_path.value().c_str(), L"w", stderr); + FILE* redir_stderr = _wfreopen(log_path.value().c_str(), logMode, stderr); #else - FILE* redir_stderr = freopen(log_path.value().c_str(), "w", stderr); + FILE* redir_stderr = freopen(log_path.value().c_str(), logMode, stderr); #endif if (!redir_stderr) { printf("Failed to redirect stderr to log file.\n");
diff --git a/chrome/test/chromedriver/server/chromedriver_server.cc b/chrome/test/chromedriver/server/chromedriver_server.cc index 65b0f4b..13363ee 100644 --- a/chrome/test/chromedriver/server/chromedriver_server.cc +++ b/chrome/test/chromedriver/server/chromedriver_server.cc
@@ -360,6 +360,8 @@ "log verbosely (equivalent to --log-level=ALL)", "silent", "log nothing (equivalent to --log-level=OFF)", + "append-log", + "append log file instead of rewriting", "replayable", "(experimental) log verbosely and don't truncate long " "strings so that the log can be replayed.",
diff --git a/chrome/test/data/webui/multidevice_setup/integration_test.js b/chrome/test/data/webui/multidevice_setup/integration_test.js index c2d32dd..3842aba 100644 --- a/chrome/test/data/webui/multidevice_setup/integration_test.js +++ b/chrome/test/data/webui/multidevice_setup/integration_test.js
@@ -30,7 +30,7 @@ setup(() => { multiDeviceSetupElement = document.createElement('multidevice-setup'); - multiDeviceSetupElement.multideviceSetup = new FakeMojoService(); + multiDeviceSetupElement.multideviceSetup_ = new FakeMojoService(); multiDeviceSetupElement.uiMode = multidevice_setup.UiMode.POST_OOBE; document.body.appendChild(multiDeviceSetupElement); @@ -66,7 +66,7 @@ }); setVisiblePage(START); - multiDeviceSetupElement.multideviceSetup.shouldSetHostSucceed = true; + multiDeviceSetupElement.multideviceSetup_.shouldSetHostSucceed = true; multiDeviceSetupElement.uiMode = multidevice_setup.UiMode.OOBE; backwardButton.click(); @@ -83,7 +83,7 @@ }); setVisiblePage(START); - multiDeviceSetupElement.multideviceSetup.shouldSetHostSucceed = + multiDeviceSetupElement.multideviceSetup_.shouldSetHostSucceed = true; multiDeviceSetupElement.uiMode = multidevice_setup.UiMode.OOBE; @@ -98,7 +98,7 @@ multiDeviceSetupElement.addEventListener('setup-exited', () => done()); setVisiblePage(START); - multiDeviceSetupElement.multideviceSetup.shouldSetHostSucceed = true; + multiDeviceSetupElement.multideviceSetup_.shouldSetHostSucceed = true; multiDeviceSetupElement.uiMode = multidevice_setup.UiMode.POST_OOBE; backwardButton.click(); @@ -108,7 +108,7 @@ multiDeviceSetupElement.addEventListener('setup-exited', () => done()); setVisiblePage(PASSWORD); - multiDeviceSetupElement.multideviceSetup.shouldSetHostSucceed = true; + multiDeviceSetupElement.multideviceSetup_.shouldSetHostSucceed = true; multiDeviceSetupElement.uiMode = multidevice_setup.UiMode.POST_OOBE; backwardButton.click(); @@ -125,7 +125,7 @@ }); setVisiblePage(PASSWORD); - multiDeviceSetupElement.multideviceSetup.shouldSetHostSucceed = + multiDeviceSetupElement.multideviceSetup_.shouldSetHostSucceed = true; multiDeviceSetupElement.uiMode = multidevice_setup.UiMode.POST_OOBE;
diff --git a/chrome/test/data/webui/settings/sync_account_control_test.js b/chrome/test/data/webui/settings/sync_account_control_test.js index 1f246a0..1179e6e 100644 --- a/chrome/test/data/webui/settings/sync_account_control_test.js +++ b/chrome/test/data/webui/settings/sync_account_control_test.js
@@ -151,8 +151,6 @@ // correct account when clicked. assertVisible(syncButton, true); assertVisible(testElement.$$('#turn-off'), false); - assertTrue(syncButton.textContent.includes('foo')); - assertFalse(syncButton.textContent.includes('bar')); syncButton.click(); Polymer.dom.flush(); @@ -180,8 +178,6 @@ assertTrue(userInfo.textContent.includes('barName')); assertTrue(userInfo.textContent.includes('bar@bar.com')); assertVisible(syncButton, true); - assertTrue(syncButton.textContent.includes('bar')); - assertFalse(syncButton.textContent.includes('foo')); browserProxy.resetResolver('startSyncingWithEmail'); syncButton.click();
diff --git a/chrome/test/views/scoped_macviews_browser_mode.cc b/chrome/test/views/scoped_macviews_browser_mode.cc deleted file mode 100644 index 3a5808f..0000000 --- a/chrome/test/views/scoped_macviews_browser_mode.cc +++ /dev/null
@@ -1,24 +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/test/views/scoped_macviews_browser_mode.h" - -#include "build/build_config.h" -#include "build/buildflag.h" -#include "ui/base/ui_base_features.h" - -namespace test { - -ScopedMacViewsBrowserMode::ScopedMacViewsBrowserMode(bool is_views) { -#if defined(OS_MACOSX) && BUILDFLAG(MAC_VIEWS_BROWSER) - if (is_views) - feature_list_.InitAndEnableFeature(features::kViewsBrowserWindows); - else - feature_list_.InitAndDisableFeature(features::kViewsBrowserWindows); -#endif -} - -ScopedMacViewsBrowserMode::~ScopedMacViewsBrowserMode() {} - -} // namespace test
diff --git a/chrome/test/views/scoped_macviews_browser_mode.h b/chrome/test/views/scoped_macviews_browser_mode.h deleted file mode 100644 index 6f1ad76..0000000 --- a/chrome/test/views/scoped_macviews_browser_mode.h +++ /dev/null
@@ -1,37 +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_TEST_VIEWS_SCOPED_MACVIEWS_BROWSER_MODE_H_ -#define CHROME_TEST_VIEWS_SCOPED_MACVIEWS_BROWSER_MODE_H_ - -#include "base/macros.h" -#include "base/test/scoped_feature_list.h" - -namespace test { - -// TODO(ellyjones): Delete this class once Mac Chrome always uses a Views -// browser window. -// -// This is a transitional class, designed for forcing a test case to run with a -// specific type of browser window on the Mac. This class is available on all -// platforms so that every use of it doesn't have to be wrapped in preprocessor -// conditionals, but is a no-op on non-Mac platforms. -// -// Tests that care about using a specific type of browser window, or that only -// work with one type of browser window, can include a member variable of type -// ScopedMacViewsBrowserMode to enforce that. -class ScopedMacViewsBrowserMode { - public: - explicit ScopedMacViewsBrowserMode(bool is_views); - virtual ~ScopedMacViewsBrowserMode(); - - private: - base::test::ScopedFeatureList feature_list_; - - DISALLOW_COPY_AND_ASSIGN(ScopedMacViewsBrowserMode); -}; - -} // namespace test - -#endif // CHROME_TEST_VIEWS_SCOPED_MACVIEWS_BROWSER_MODE_H_
diff --git a/chromeos/components/drivefs/fake_drivefs.cc b/chromeos/components/drivefs/fake_drivefs.cc index db2e2c2f..1e504a3 100644 --- a/chromeos/components/drivefs/fake_drivefs.cc +++ b/chromeos/components/drivefs/fake_drivefs.cc
@@ -145,7 +145,7 @@ pending_callbacks_ = results_.size() + 1; for (size_t i = 0; i < results_.size(); ++i) { drive_fs_->GetMetadata( - results_[i]->path, false, + results_[i]->path, base::BindOnce(&SearchQuery::OnMetadata, weak_ptr_factory_.GetWeakPtr(), i)); } @@ -265,7 +265,6 @@ } void FakeDriveFs::GetMetadata(const base::FilePath& path, - bool want_thumbnail, GetMetadataCallback callback) { base::FilePath absolute_path = mount_path_; CHECK(base::FilePath("/").AppendRelativePath(path, &absolute_path));
diff --git a/chromeos/components/drivefs/fake_drivefs.h b/chromeos/components/drivefs/fake_drivefs.h index 9237eb2..853aca9d 100644 --- a/chromeos/components/drivefs/fake_drivefs.h +++ b/chromeos/components/drivefs/fake_drivefs.h
@@ -49,7 +49,6 @@ // drivefs::mojom::DriveFs: void GetMetadata(const base::FilePath& path, - bool want_thumbnail, GetMetadataCallback callback) override; void SetPinned(const base::FilePath& path,
diff --git a/chromeos/components/drivefs/mojom/drivefs.mojom b/chromeos/components/drivefs/mojom/drivefs.mojom index 8e5636f..712e1fdde 100644 --- a/chromeos/components/drivefs/mojom/drivefs.mojom +++ b/chromeos/components/drivefs/mojom/drivefs.mojom
@@ -20,11 +20,8 @@ // Implemented by DriveFS, used from Chrome. interface DriveFs { - // Returns the metadata for |path|. Thumbnail requests may require requesting - // a thumbnail from the server so thumbnails are only populated for requests - // where |want_thumbnail| is true. - GetMetadata(mojo_base.mojom.FilePath path, - [MinVersion=1] bool want_thumbnail) => ( + // Returns the metadata for |path|. + GetMetadata(mojo_base.mojom.FilePath path) => ( FileError error, FileMetadata? metadata); // Sets the file at |path| to pinned or unpinned depending on the value of @@ -172,9 +169,8 @@ // May be present if the file is an image. ImageMetadata? image_metadata; - // The thumbnail as a PNG. It is only set if |want_thumbnail| is true in the - // request and the file has a thumbnail available. - array<uint8>? thumbnail; + // Never set. + array<uint8>? deprecated_thumbnail; Capabilities capabilities; };
diff --git a/chromeos/dbus/fake_power_manager_client.cc b/chromeos/dbus/fake_power_manager_client.cc index 102f09b..e05082b 100644 --- a/chromeos/dbus/fake_power_manager_client.cc +++ b/chromeos/dbus/fake_power_manager_client.cc
@@ -38,6 +38,18 @@ } } +power_manager::BacklightBrightnessChange_Cause RequestCauseToChangeCause( + power_manager::SetBacklightBrightnessRequest_Cause cause) { + switch (cause) { + case power_manager::SetBacklightBrightnessRequest_Cause_USER_REQUEST: + return power_manager::BacklightBrightnessChange_Cause_USER_REQUEST; + case power_manager::SetBacklightBrightnessRequest_Cause_MODEL: + return power_manager::BacklightBrightnessChange_Cause_MODEL; + } + NOTREACHED() << "Unhandled brightness request cause " << cause; + return power_manager::BacklightBrightnessChange_Cause_USER_REQUEST; +} + } // namespace FakePowerManagerClient::FakePowerManagerClient() @@ -83,14 +95,14 @@ void FakePowerManagerClient::IncreaseScreenBrightness() {} -void FakePowerManagerClient::SetScreenBrightnessPercent(double percent, - bool gradual) { - screen_brightness_percent_ = percent; - requested_screen_brightness_percent_ = percent; +void FakePowerManagerClient::SetScreenBrightness( + const power_manager::SetBacklightBrightnessRequest& request) { + screen_brightness_percent_ = request.percent(); + requested_screen_brightness_percent_ = request.percent(); power_manager::BacklightBrightnessChange change; - change.set_percent(percent); - change.set_cause(power_manager::BacklightBrightnessChange_Cause_USER_REQUEST); + change.set_percent(request.percent()); + change.set_cause(RequestCauseToChangeCause(request.cause())); base::ThreadTaskRunnerHandle::Get()->PostTask( FROM_HERE, base::BindOnce(&FakePowerManagerClient::SendScreenBrightnessChanged,
diff --git a/chromeos/dbus/fake_power_manager_client.h b/chromeos/dbus/fake_power_manager_client.h index 71a5474f..0ba1771 100644 --- a/chromeos/dbus/fake_power_manager_client.h +++ b/chromeos/dbus/fake_power_manager_client.h
@@ -77,7 +77,8 @@ base::WeakPtr<RenderProcessManagerDelegate> delegate) override; void DecreaseScreenBrightness(bool allow_off) override; void IncreaseScreenBrightness() override; - void SetScreenBrightnessPercent(double percent, bool gradual) override; + void SetScreenBrightness( + const power_manager::SetBacklightBrightnessRequest& request) override; void GetScreenBrightnessPercent(DBusMethodCallback<double> callback) override; void DecreaseKeyboardBrightness() override; void IncreaseKeyboardBrightness() override; @@ -210,7 +211,7 @@ // Current keyboard brightness in the range [0.0, 100.0]. base::Optional<double> keyboard_brightness_percent_; - // Last screen brightness requested via SetScreenBrightnessPercent(). + // Last screen brightness requested via SetScreenBrightness(). // Unlike |screen_brightness_percent_|, this value will not be changed by // SetBacklightsForcedOff() method - a method that implicitly changes screen // brightness.
diff --git a/chromeos/dbus/power_manager_client.cc b/chromeos/dbus/power_manager_client.cc index a9f1798..2500390 100644 --- a/chromeos/dbus/power_manager_client.cc +++ b/chromeos/dbus/power_manager_client.cc
@@ -212,14 +212,16 @@ return proto_; } - void SetScreenBrightnessPercent(double percent, bool gradual) override { - dbus::MethodCall method_call( - power_manager::kPowerManagerInterface, - power_manager::kSetScreenBrightnessPercentMethod); - dbus::MessageWriter writer(&method_call); - writer.AppendDouble(percent); - writer.AppendInt32(gradual ? power_manager::kBrightnessTransitionGradual - : power_manager::kBrightnessTransitionInstant); + void SetScreenBrightness( + const power_manager::SetBacklightBrightnessRequest& request) override { + dbus::MethodCall method_call(power_manager::kPowerManagerInterface, + power_manager::kSetScreenBrightnessMethod); + if (!dbus::MessageWriter(&method_call).AppendProtoAsArrayOfBytes(request)) { + POWER_LOG(ERROR) << "Error serializing " + << power_manager::kSetScreenBrightnessMethod + << " request"; + return; + } power_manager_proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, base::DoNothing());
diff --git a/chromeos/dbus/power_manager_client.h b/chromeos/dbus/power_manager_client.h index b2e9ad7e..f8bfaff 100644 --- a/chromeos/dbus/power_manager_client.h +++ b/chromeos/dbus/power_manager_client.h
@@ -29,6 +29,7 @@ namespace power_manager { class BacklightBrightnessChange; class ScreenIdleState; +class SetBacklightBrightnessRequest; } // namespace power_manager namespace chromeos { @@ -183,9 +184,9 @@ // Increases the screen brightness. virtual void IncreaseScreenBrightness() = 0; - // Set the screen brightness to |percent|, in the range [0.0, 100.0]. - // If |gradual| is true, the transition will be animated. - virtual void SetScreenBrightnessPercent(double percent, bool gradual) = 0; + // Sets the screen brightness per |request|. + virtual void SetScreenBrightness( + const power_manager::SetBacklightBrightnessRequest& request) = 0; // Asynchronously gets the current screen brightness, in the range // [0.0, 100.0]. On error (e.g. powerd not running), |callback| will be run
diff --git a/components/arc/power/arc_power_bridge.cc b/components/arc/power/arc_power_bridge.cc index 2d93e73..28ab576 100644 --- a/components/arc/power/arc_power_bridge.cc +++ b/components/arc/power/arc_power_bridge.cc
@@ -262,9 +262,15 @@ } void ArcPowerBridge::OnScreenBrightnessUpdateRequest(double percent) { + power_manager::SetBacklightBrightnessRequest request; + request.set_percent(percent); + request.set_transition( + power_manager::SetBacklightBrightnessRequest_Transition_GRADUAL); + request.set_cause( + power_manager::SetBacklightBrightnessRequest_Cause_USER_REQUEST); chromeos::DBusThreadManager::Get() ->GetPowerManagerClient() - ->SetScreenBrightnessPercent(percent, true); + ->SetScreenBrightness(request); } ArcPowerBridge::WakeLockRequestor* ArcPowerBridge::GetWakeLockRequestor(
diff --git a/components/autofill/core/browser/payments/full_card_request.cc b/components/autofill/core/browser/payments/full_card_request.cc index a787034d..9aa14cbf 100644 --- a/components/autofill/core/browser/payments/full_card_request.cc +++ b/components/autofill/core/browser/payments/full_card_request.cc
@@ -69,7 +69,8 @@ if (should_unmask_card_) { payments_client_->Prepare(); request_->billing_customer_number = GetBillingCustomerId( - personal_data_manager_, payments_client_->GetPrefService()); + personal_data_manager_, payments_client_->GetPrefService(), + /*should_log_validity=*/true); } ui_delegate_->ShowUnmaskPrompt(request_->card, reason,
diff --git a/components/autofill/core/browser/payments/payments_util.cc b/components/autofill/core/browser/payments/payments_util.cc index 7063a7d..51beb60 100644 --- a/components/autofill/core/browser/payments/payments_util.cc +++ b/components/autofill/core/browser/payments/payments_util.cc
@@ -18,7 +18,8 @@ namespace payments { int64_t GetBillingCustomerId(PersonalDataManager* personal_data_manager, - PrefService* pref_service) { + PrefService* pref_service, + bool should_log_validity) { DCHECK(personal_data_manager); DCHECK(pref_service); @@ -33,16 +34,22 @@ int64_t billing_customer_id = 0; if (base::StringToInt64(base::StringPiece(customer_data->customer_id), &billing_customer_id)) { - AutofillMetrics::LogPaymentsCustomerDataBillingIdStatus( - AutofillMetrics::BillingIdStatus::VALID); + if (should_log_validity) { + AutofillMetrics::LogPaymentsCustomerDataBillingIdStatus( + AutofillMetrics::BillingIdStatus::VALID); + } return billing_customer_id; } else { - AutofillMetrics::LogPaymentsCustomerDataBillingIdStatus( - AutofillMetrics::BillingIdStatus::PARSE_ERROR); + if (should_log_validity) { + AutofillMetrics::LogPaymentsCustomerDataBillingIdStatus( + AutofillMetrics::BillingIdStatus::PARSE_ERROR); + } } } else { - AutofillMetrics::LogPaymentsCustomerDataBillingIdStatus( - AutofillMetrics::BillingIdStatus::MISSING); + if (should_log_validity) { + AutofillMetrics::LogPaymentsCustomerDataBillingIdStatus( + AutofillMetrics::BillingIdStatus::MISSING); + } } }
diff --git a/components/autofill/core/browser/payments/payments_util.h b/components/autofill/core/browser/payments/payments_util.h index 364284a1..aeca52b 100644 --- a/components/autofill/core/browser/payments/payments_util.h +++ b/components/autofill/core/browser/payments/payments_util.h
@@ -17,9 +17,11 @@ // Returns the billing customer ID (a.k.a. the customer number) for the Google // Payments account for this user. Obtains it from the synced data. Returns 0 -// if the customer ID was not found. +// if the customer ID was not found. If |should_log_validity| is true, will +// report on the validity state of the customer ID in PaymentsCustomerData. int64_t GetBillingCustomerId(PersonalDataManager* personal_data_manager, - PrefService* pref_service); + PrefService* pref_service, + bool should_log_validity = false); } // namespace payments } // namespace autofill
diff --git a/components/autofill/core/browser/payments/payments_util_unittest.cc b/components/autofill/core/browser/payments/payments_util_unittest.cc index fd0ca497..9ce775c 100644 --- a/components/autofill/core/browser/payments/payments_util_unittest.cc +++ b/components/autofill/core/browser/payments/payments_util_unittest.cc
@@ -46,7 +46,8 @@ std::make_unique<PaymentsCustomerData>(/*customer_id=*/"123456")); EXPECT_EQ(123456, - GetBillingCustomerId(&personal_data_manager_, &pref_service_)); + GetBillingCustomerId(&personal_data_manager_, &pref_service_, + /*should_log_validity=*/true)); histogram_tester.ExpectUniqueSample( "Autofill.PaymentsCustomerDataBillingIdStatus", @@ -61,7 +62,8 @@ personal_data_manager_.SetPaymentsCustomerData( std::make_unique<PaymentsCustomerData>(/*customer_id=*/"garbage")); - EXPECT_EQ(0, GetBillingCustomerId(&personal_data_manager_, &pref_service_)); + EXPECT_EQ(0, GetBillingCustomerId(&personal_data_manager_, &pref_service_, + /*should_log_validity=*/true)); histogram_tester.ExpectUniqueSample( "Autofill.PaymentsCustomerDataBillingIdStatus", @@ -75,7 +77,8 @@ // Explictly do not set PaymentsCustomerData. Nothing crashes and the returned // customer ID is 0. - EXPECT_EQ(0, GetBillingCustomerId(&personal_data_manager_, &pref_service_)); + EXPECT_EQ(0, GetBillingCustomerId(&personal_data_manager_, &pref_service_, + /*should_log_validity=*/true)); histogram_tester.ExpectUniqueSample( "Autofill.PaymentsCustomerDataBillingIdStatus", AutofillMetrics::BillingIdStatus::MISSING, 1); @@ -93,7 +96,8 @@ // We got the data from prefs and log that the PaymentsCustomerData is // invalid. EXPECT_EQ(123456, - GetBillingCustomerId(&personal_data_manager_, &pref_service_)); + GetBillingCustomerId(&personal_data_manager_, &pref_service_, + /*should_log_validity=*/true)); histogram_tester.ExpectUniqueSample( "Autofill.PaymentsCustomerDataBillingIdStatus", AutofillMetrics::BillingIdStatus::MISSING, 1); @@ -106,7 +110,8 @@ pref_service_.SetDouble(prefs::kAutofillBillingCustomerNumber, 123456.0); EXPECT_EQ(123456, - GetBillingCustomerId(&personal_data_manager_, &pref_service_)); + GetBillingCustomerId(&personal_data_manager_, &pref_service_, + /*should_log_validity=*/true)); } TEST_F(PaymentsUtilTest, GetBillingCustomerId_PriorityPrefs_NoData) { @@ -115,7 +120,8 @@ // Explictly do not set Prefs data. Nothing crashes and the returned customer // ID is 0. - EXPECT_EQ(0, GetBillingCustomerId(&personal_data_manager_, &pref_service_)); + EXPECT_EQ(0, GetBillingCustomerId(&personal_data_manager_, &pref_service_, + /*should_log_validity=*/true)); } } // namespace payments
diff --git a/components/bookmarks/browser/bookmark_storage.cc b/components/bookmarks/browser/bookmark_storage.cc index 2fc5d1bc..4131094 100644 --- a/components/bookmarks/browser/bookmark_storage.cc +++ b/components/bookmarks/browser/bookmark_storage.cc
@@ -15,6 +15,7 @@ #include "base/json/json_reader.h" #include "base/json/json_string_value_serializer.h" #include "base/metrics/histogram_macros.h" +#include "base/numerics/safe_conversions.h" #include "base/sequenced_task_runner.h" #include "base/time/time.h" #include "components/bookmarks/browser/bookmark_codec.h" @@ -115,6 +116,10 @@ } details->CreateUrlIndex(); + + UMA_HISTOGRAM_COUNTS_100000( + "Bookmarks.Count.OnProfileLoad", + base::saturated_cast<int>(details->url_index()->UrlCount())); } // BookmarkLoadDetails ---------------------------------------------------------
diff --git a/components/bookmarks/browser/url_index.cc b/components/bookmarks/browser/url_index.cc index 44aecac..39f2130 100644 --- a/components/bookmarks/browser/url_index.cc +++ b/components/bookmarks/browser/url_index.cc
@@ -71,11 +71,16 @@ } } -bool UrlIndex::HasBookmarks() { +bool UrlIndex::HasBookmarks() const { base::AutoLock url_lock(url_lock_); return !nodes_ordered_by_url_set_.empty(); } +size_t UrlIndex::UrlCount() const { + base::AutoLock url_lock(url_lock_); + return nodes_ordered_by_url_set_.size(); +} + bool UrlIndex::IsBookmarked(const GURL& url) { base::AutoLock url_lock(url_lock_); return IsBookmarkedNoLock(url);
diff --git a/components/bookmarks/browser/url_index.h b/components/bookmarks/browser/url_index.h index 1200247..1f7f131 100644 --- a/components/bookmarks/browser/url_index.h +++ b/components/bookmarks/browser/url_index.h
@@ -56,7 +56,10 @@ void GetNodesByUrl(const GURL& url, std::vector<const BookmarkNode*>* nodes); // Returns true if there is at least one bookmark. - bool HasBookmarks(); + bool HasBookmarks() const; + + // Returns the number of URL bookmarks stored. + size_t UrlCount() const; // HistoryBookmarkModel: bool IsBookmarked(const GURL& url) override; @@ -88,7 +91,7 @@ // such, be sure and wrap all usage of it around |url_lock_|. using NodesOrderedByUrlSet = std::multiset<BookmarkNode*, NodeUrlComparator>; NodesOrderedByUrlSet nodes_ordered_by_url_set_; - base::Lock url_lock_; + mutable base::Lock url_lock_; DISALLOW_COPY_AND_ASSIGN(UrlIndex); };
diff --git a/components/certificate_transparency/chrome_ct_policy_enforcer.cc b/components/certificate_transparency/chrome_ct_policy_enforcer.cc index a2e2b49..99a4405 100644 --- a/components/certificate_transparency/chrome_ct_policy_enforcer.cc +++ b/components/certificate_transparency/chrome_ct_policy_enforcer.cc
@@ -87,7 +87,7 @@ case CTPolicyCompliance::CT_POLICY_BUILD_NOT_TIMELY: return "BUILD_NOT_TIMELY"; case CTPolicyCompliance::CT_POLICY_COMPLIANCE_DETAILS_NOT_AVAILABLE: - case CTPolicyCompliance::CT_POLICY_MAX: + case CTPolicyCompliance::CT_POLICY_COUNT: NOTREACHED(); return "unknown"; }
diff --git a/components/drive/change_list_processor_unittest.cc b/components/drive/change_list_processor_unittest.cc index 638a637..02feb01 100644 --- a/components/drive/change_list_processor_unittest.cc +++ b/components/drive/change_list_processor_unittest.cc
@@ -570,6 +570,7 @@ ChangeListProcessor::RefreshDirectory( metadata_.get(), DirectoryFetchInfo(root.local_id(), kRootId, kNewStartpageToken, + util::GetDriveMyDriveRootPath(), util::GetDriveMyDriveRootPath()), std::move(change_list), &refreshed_entries)); @@ -608,6 +609,7 @@ ChangeListProcessor::RefreshDirectory( metadata_.get(), DirectoryFetchInfo(root.local_id(), kRootId, kNewStartpageToken, + util::GetDriveMyDriveRootPath(), util::GetDriveMyDriveRootPath()), std::move(change_list), &refreshed_entries));
diff --git a/components/drive/chromeos/change_list_processor.cc b/components/drive/chromeos/change_list_processor.cc index a81295d..8c741a9 100644 --- a/components/drive/chromeos/change_list_processor.cc +++ b/components/drive/chromeos/change_list_processor.cc
@@ -45,11 +45,13 @@ DirectoryFetchInfo::DirectoryFetchInfo(const std::string& local_id, const std::string& resource_id, const std::string& start_page_token, - const base::FilePath& root_entry_path) + const base::FilePath& root_entry_path, + const base::FilePath& directory_path) : local_id_(local_id), resource_id_(resource_id), start_page_token_(start_page_token), - root_entry_path_(root_entry_path) {} + root_entry_path_(root_entry_path), + directory_path_(directory_path) {} DirectoryFetchInfo::DirectoryFetchInfo(const DirectoryFetchInfo& other) = default; @@ -57,7 +59,8 @@ std::string DirectoryFetchInfo::ToString() const { return ("local_id: " + local_id_ + ", resource_id: " + resource_id_ + ", start_page_token: " + start_page_token_ + - ", root_entry_path: " + root_entry_path_.value()); + ", root_entry_path: " + root_entry_path_.value() + + ", directory_path: " + directory_path_.value()); } ChangeList::ChangeList() = default;
diff --git a/components/drive/chromeos/change_list_processor.h b/components/drive/chromeos/change_list_processor.h index 42fe89d..67a94583 100644 --- a/components/drive/chromeos/change_list_processor.h +++ b/components/drive/chromeos/change_list_processor.h
@@ -47,7 +47,8 @@ DirectoryFetchInfo(const std::string& local_id, const std::string& resource_id, const std::string& start_page_token, - const base::FilePath& root_entry_path); + const base::FilePath& root_entry_path, + const base::FilePath& directory_path); DirectoryFetchInfo(const DirectoryFetchInfo& other); @@ -67,6 +68,9 @@ // The root path of the directory being fetched. const base::FilePath& root_entry_path() const { return root_entry_path_; } + // The directory path that we are fetching. Used for logging. + const base::FilePath& directory_path() const { return directory_path_; } + // Returns a string representation of this object. std::string ToString() const; @@ -75,6 +79,7 @@ const std::string resource_id_; const std::string start_page_token_; const base::FilePath root_entry_path_; + const base::FilePath directory_path_; }; // Class to represent a change list.
diff --git a/components/drive/chromeos/default_corpus_change_list_loader.cc b/components/drive/chromeos/default_corpus_change_list_loader.cc index 68f83e43..e87a8c6 100644 --- a/components/drive/chromeos/default_corpus_change_list_loader.cc +++ b/components/drive/chromeos/default_corpus_change_list_loader.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "base/time/clock.h" #include "components/drive/chromeos/about_resource_root_folder_id_loader.h" #include "components/drive/file_system_core_util.h" @@ -18,13 +19,16 @@ ResourceMetadata* resource_metadata, JobScheduler* scheduler, AboutResourceLoader* about_resource_loader, - LoaderController* apply_task_controller) + LoaderController* apply_task_controller, + const base::Clock* clock) : logger_(logger), blocking_task_runner_(blocking_task_runner), resource_metadata_(resource_metadata), scheduler_(scheduler), loader_controller_(apply_task_controller), weak_ptr_factory_(this) { + DCHECK(clock); + root_folder_id_loader_ = std::make_unique<AboutResourceRootFolderIdLoader>(about_resource_loader); @@ -41,7 +45,7 @@ logger_, blocking_task_runner_.get(), resource_metadata_, scheduler_, root_folder_id_loader_.get(), start_page_token_loader_.get(), loader_controller_, util::GetDriveMyDriveRootPath(), - util::kTeamDriveIdDefaultCorpus); + util::kTeamDriveIdDefaultCorpus, clock); team_drive_list_loader_ = std::make_unique<TeamDriveListLoader>( logger_, blocking_task_runner_.get(), resource_metadata, scheduler_,
diff --git a/components/drive/chromeos/default_corpus_change_list_loader.h b/components/drive/chromeos/default_corpus_change_list_loader.h index fdce545..ef99e72 100644 --- a/components/drive/chromeos/default_corpus_change_list_loader.h +++ b/components/drive/chromeos/default_corpus_change_list_loader.h
@@ -9,6 +9,7 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/time/default_clock.h" #include "components/drive/chromeos/about_resource_root_folder_id_loader.h" #include "components/drive/chromeos/change_list_loader.h" #include "components/drive/chromeos/directory_loader.h" @@ -33,12 +34,15 @@ // users default corpus. class DefaultCorpusChangeListLoader : public DriveChangeListLoader { public: - DefaultCorpusChangeListLoader(EventLogger* logger, - base::SequencedTaskRunner* blocking_task_runner, - ResourceMetadata* resource_metadata, - JobScheduler* scheduler, - AboutResourceLoader* about_resource_loader, - LoaderController* apply_task_controller); + // |clock| can be mocked for testing. + DefaultCorpusChangeListLoader( + EventLogger* logger, + base::SequencedTaskRunner* blocking_task_runner, + ResourceMetadata* resource_metadata, + JobScheduler* scheduler, + AboutResourceLoader* about_resource_loader, + LoaderController* apply_task_controller, + const base::Clock* clock = base::DefaultClock::GetInstance()); ~DefaultCorpusChangeListLoader() override;
diff --git a/components/drive/chromeos/directory_loader.cc b/components/drive/chromeos/directory_loader.cc index 328f2e9..4056e37 100644 --- a/components/drive/chromeos/directory_loader.cc +++ b/components/drive/chromeos/directory_loader.cc
@@ -15,6 +15,7 @@ #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" #include "base/strings/string_number_conversions.h" +#include "base/time/clock.h" #include "base/time/time.h" #include "components/drive/chromeos/change_list_loader_observer.h" #include "components/drive/chromeos/change_list_processor.h" @@ -38,6 +39,9 @@ // Minimum changestamp gap required to start loading directory. constexpr int kMinimumChangestampGap = 50; +constexpr base::TimeDelta kMinimumPerDirectoryFetchTimeGap = + base::TimeDelta::FromSeconds(30); + FileError CheckLocalState(ResourceMetadata* resource_metadata, const base::FilePath& root_entry_path, const std::string& team_drive_id, @@ -71,7 +75,9 @@ FileError UpdateStartPageToken(ResourceMetadata* resource_metadata, const DirectoryFetchInfo& directory_fetch_info, - base::FilePath* directory_path) { + base::FilePath* directory_path, + const base::Clock* clock) { + DCHECK(clock); // Update the directory start page token. ResourceEntry directory; FileError error = resource_metadata->GetResourceEntryById( @@ -82,8 +88,14 @@ if (!directory.file_info().is_directory()) return FILE_ERROR_NOT_A_DIRECTORY; - directory.mutable_directory_specific_info()->set_start_page_token( + DirectorySpecificInfo* directory_specific_info = + directory.mutable_directory_specific_info(); + + directory_specific_info->set_start_page_token( directory_fetch_info.start_page_token()); + directory_specific_info->set_last_read_time_ms( + clock->Now().ToDeltaSinceWindowsEpoch().InMilliseconds()); + error = resource_metadata->RefreshEntry(directory); if (error != FILE_ERROR_OK) return error; @@ -217,7 +229,8 @@ StartPageTokenLoader* start_page_token_loader, LoaderController* loader_controller, const base::FilePath& root_entry_path, - const std::string& team_drive_id) + const std::string& team_drive_id, + const base::Clock* clock) : logger_(logger), blocking_task_runner_(blocking_task_runner), resource_metadata_(resource_metadata), @@ -227,6 +240,7 @@ loader_controller_(loader_controller), root_entry_path_(root_entry_path), team_drive_id_(team_drive_id), + clock_(clock), weak_ptr_factory_(this) {} DirectoryLoader::~DirectoryLoader() = default; @@ -293,7 +307,8 @@ DirectoryFetchInfo directory_fetch_info( entry->local_id(), entry->resource_id(), - entry->directory_specific_info().start_page_token(), root_entry_path_); + entry->directory_specific_info().start_page_token(), root_entry_path_, + directory_path); // Register the callback function to be called when it is loaded. const std::string& local_id = directory_fetch_info.local_id(); @@ -307,7 +322,7 @@ root_folder_id_loader_->GetRootFolderId( base::Bind(&DirectoryLoader::ReadDirectoryAfterGetRootFolderId, - weak_ptr_factory_.GetWeakPtr(), local_id)); + weak_ptr_factory_.GetWeakPtr(), directory_path, local_id)); } void DirectoryLoader::ReadDirectoryAfterLoadParent( @@ -336,6 +351,7 @@ } void DirectoryLoader::ReadDirectoryAfterGetRootFolderId( + const base::FilePath& directory_path, const std::string& local_id, FileError error, base::Optional<std::string> root_folder_id) { @@ -348,12 +364,14 @@ DCHECK(root_folder_id); - start_page_token_loader_->GetStartPageToken(base::Bind( - &DirectoryLoader::ReadDirectoryAfterGetStartPageToken, - weak_ptr_factory_.GetWeakPtr(), local_id, root_folder_id.value())); + start_page_token_loader_->GetStartPageToken( + base::Bind(&DirectoryLoader::ReadDirectoryAfterGetStartPageToken, + weak_ptr_factory_.GetWeakPtr(), directory_path, local_id, + root_folder_id.value())); } void DirectoryLoader::ReadDirectoryAfterGetStartPageToken( + const base::FilePath& directory_path, const std::string& local_id, const std::string& root_folder_id, google_apis::DriveApiErrorCode status, @@ -377,13 +395,14 @@ team_drive_id_, root_folder_id, local_id, entry, local_start_page_token), base::BindOnce(&DirectoryLoader::ReadDirectoryAfterCheckLocalState, - weak_ptr_factory_.GetWeakPtr(), + weak_ptr_factory_.GetWeakPtr(), directory_path, start_page_token->start_page_token(), local_id, root_folder_id, base::Owned(entry), base::Owned(local_start_page_token))); } void DirectoryLoader::ReadDirectoryAfterCheckLocalState( + const base::FilePath& directory_path, const std::string& remote_start_page_token, const std::string& local_id, const std::string& root_folder_id, @@ -409,7 +428,7 @@ DirectoryFetchInfo directory_fetch_info(local_id, entry->resource_id(), remote_start_page_token, - root_entry_path_); + root_entry_path_, directory_path); int64_t directory_changestamp = 0; // The directory_specific_info may be enpty, so default changestamp to 0. @@ -426,6 +445,26 @@ return; } + // If we haven't finished loading the drive corpus, local_start_page_token + // will be empty. In this case we will keep track of the last time we loaded + // the directory, and only reload after an appropriate delay. + if (local_start_page_token->empty()) { + if (entry->directory_specific_info().has_last_read_time_ms()) { + base::Time last_read = base::Time::FromDeltaSinceWindowsEpoch( + base::TimeDelta::FromMilliseconds( + entry->directory_specific_info().last_read_time_ms())); + base::TimeDelta elapsed = clock_->Now() - last_read; + if (elapsed < kMinimumPerDirectoryFetchTimeGap) { + logger_->Log( + logging::LOG_INFO, + "Skipping read of directory (%s), contents considered fresh.", + directory_fetch_info.ToString().c_str()); + OnDirectoryLoadComplete(local_id, FILE_ERROR_OK); + return; + } + } + } + int64_t remote_changestamp = 0; int64_t local_changestamp = 0; if (!drive::util::ConvertStartPageTokenToChangestamp(remote_start_page_token, @@ -515,7 +554,7 @@ void DirectoryLoader::SendEntries(const std::string& local_id, const ResourceEntryVector& entries) { LoadCallbackMap::iterator it = pending_load_callback_.find(local_id); - DCHECK(it != pending_load_callback_.end()); + DCHECK(it != pending_load_callback_.end()) << "local_id: " << local_id; for (size_t i = 0; i < it->second.size(); ++i) { ReadDirectoryCallbackState* callback_state = &it->second[i]; @@ -596,7 +635,8 @@ base::PostTaskAndReplyWithResult( blocking_task_runner_.get(), FROM_HERE, base::Bind(&UpdateStartPageToken, resource_metadata_, - directory_fetch_info, directory_path), + directory_fetch_info, directory_path, + base::Unretained(clock_)), base::Bind( &DirectoryLoader::LoadDirectoryFromServerAfterUpdateStartPageToken, weak_ptr_factory_.GetWeakPtr(), directory_fetch_info,
diff --git a/components/drive/chromeos/directory_loader.h b/components/drive/chromeos/directory_loader.h index 262107e0..06e075f9 100644 --- a/components/drive/chromeos/directory_loader.h +++ b/components/drive/chromeos/directory_loader.h
@@ -18,12 +18,14 @@ #include "base/memory/ref_counted.h" #include "base/observer_list.h" #include "base/threading/thread_checker.h" +#include "base/time/default_clock.h" #include "components/drive/chromeos/file_system_interface.h" #include "components/drive/file_errors.h" #include "google_apis/drive/drive_api_error_codes.h" #include "google_apis/drive/drive_common_callbacks.h" namespace base { +class Clock; class SequencedTaskRunner; } // namespace base @@ -45,6 +47,7 @@ // DirectoryLoader is used to load directory contents. class DirectoryLoader { public: + // |clock| can be mocked for testing DirectoryLoader(EventLogger* logger, base::SequencedTaskRunner* blocking_task_runner, ResourceMetadata* resource_metadata, @@ -53,7 +56,8 @@ StartPageTokenLoader* start_page_token_loader, LoaderController* apply_task_controller, const base::FilePath& root_entry_path, - const std::string& team_drive_id); + const std::string& team_drive_id, + const base::Clock* clock = base::DefaultClock::GetInstance()); ~DirectoryLoader(); // Adds and removes the observer. @@ -85,16 +89,19 @@ const FileOperationCallback& completion_callback, FileError error); void ReadDirectoryAfterGetRootFolderId( + const base::FilePath& directory_path, const std::string& local_id, FileError error, base::Optional<std::string> root_folder_id); void ReadDirectoryAfterGetStartPageToken( + const base::FilePath& directory_path, const std::string& local_id, const std::string& root_folder_id, google_apis::DriveApiErrorCode status, std::unique_ptr<google_apis::StartPageToken> start_page_token); void ReadDirectoryAfterCheckLocalState( + const base::FilePath& directory_path, const std::string& remote_start_page_token, const std::string& local_id, const std::string& root_folder_id, @@ -156,6 +163,8 @@ // page token when performing a fast fetch. const std::string team_drive_id_; + const base::Clock* clock_; // Not Owned + THREAD_CHECKER(thread_checker_); // Note: This should remain the last member so it'll be destroyed and
diff --git a/components/drive/chromeos/file_system.cc b/components/drive/chromeos/file_system.cc index 68cb10be..64699bb 100644 --- a/components/drive/chromeos/file_system.cc +++ b/components/drive/chromeos/file_system.cc
@@ -295,13 +295,15 @@ JobScheduler* scheduler, internal::ResourceMetadata* resource_metadata, base::SequencedTaskRunner* blocking_task_runner, - const base::FilePath& temporary_file_directory) + const base::FilePath& temporary_file_directory, + const base::Clock* clock) : logger_(logger), cache_(cache), scheduler_(scheduler), resource_metadata_(resource_metadata), blocking_task_runner_(blocking_task_runner), temporary_file_directory_(temporary_file_directory), + clock_(clock), weak_ptr_factory_(this) { ResetComponents(); } @@ -338,7 +340,7 @@ default_corpus_change_list_loader_ = std::make_unique<internal::DefaultCorpusChangeListLoader>( logger_, blocking_task_runner_.get(), resource_metadata_, scheduler_, - about_resource_loader_.get(), loader_controller_.get()); + about_resource_loader_.get(), loader_controller_.get(), clock_); default_corpus_change_list_loader_->AddChangeListLoaderObserver(this); default_corpus_change_list_loader_->AddTeamDriveListObserver(this);
diff --git a/components/drive/chromeos/file_system.h b/components/drive/chromeos/file_system.h index d177fa4f..792baa7 100644 --- a/components/drive/chromeos/file_system.h +++ b/components/drive/chromeos/file_system.h
@@ -18,6 +18,7 @@ #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/threading/thread_checker.h" +#include "base/time/default_clock.h" #include "components/drive/chromeos/change_list_loader_observer.h" #include "components/drive/chromeos/drive_operation_queue.h" #include "components/drive/chromeos/file_system/operation_delegate.h" @@ -72,12 +73,14 @@ public internal::TeamDriveListObserver, public file_system::OperationDelegate { public: + // |clock| can be mocked for testing. FileSystem(EventLogger* logger, internal::FileCache* cache, JobScheduler* scheduler, internal::ResourceMetadata* resource_metadata, base::SequencedTaskRunner* blocking_task_runner, - const base::FilePath& temporary_file_directory); + const base::FilePath& temporary_file_directory, + const base::Clock* clock = base::DefaultClock::GetInstance()); ~FileSystem() override; // FileSystemInterface overrides. @@ -301,6 +304,8 @@ base::FilePath temporary_file_directory_; + const base::Clock* clock_; // Not owned. + // Implementation of each file system operation. std::unique_ptr<file_system::CopyOperation> copy_operation_; std::unique_ptr<file_system::CreateDirectoryOperation>
diff --git a/components/drive/directory_loader_unittest.cc b/components/drive/directory_loader_unittest.cc index fd2ab8d..8f42bb8 100644 --- a/components/drive/directory_loader_unittest.cc +++ b/components/drive/directory_loader_unittest.cc
@@ -9,9 +9,9 @@ #include "base/callback_helpers.h" #include "base/files/scoped_temp_dir.h" #include "base/macros.h" -#include "base/run_loop.h" -#include "base/single_thread_task_runner.h" +#include "base/test/test_mock_time_task_runner.h" #include "base/threading/thread_task_runner_handle.h" +#include "base/time/clock.h" #include "components/drive/chromeos/about_resource_loader.h" #include "components/drive/chromeos/about_resource_root_folder_id_loader.h" #include "components/drive/chromeos/change_list_loader_observer.h" @@ -83,11 +83,23 @@ const std::string root_folder_id_; }; +struct DestroyHelper { + template <typename T> + void operator()(T* object) const { + if (object) { + object->Destroy(); + } + } +}; + } // namespace class DirectoryLoaderTest : public testing::Test { protected: void SetUp() override { + task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>( + base::TestMockTimeTaskRunner::Type::kBoundToThread); + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); pref_service_ = std::make_unique<TestingPrefServiceSimple>(); test_util::RegisterDrivePrefs(pref_service_->registry()); @@ -99,19 +111,18 @@ scheduler_ = std::make_unique<JobScheduler>( pref_service_.get(), logger_.get(), drive_service_.get(), - base::ThreadTaskRunnerHandle::Get().get(), nullptr); - metadata_storage_.reset(new ResourceMetadataStorage( - temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get())); + task_runner_.get(), nullptr); + metadata_storage_.reset( + new ResourceMetadataStorage(temp_dir_.GetPath(), task_runner_.get())); ASSERT_TRUE(metadata_storage_->Initialize()); cache_.reset(new FileCache(metadata_storage_.get(), temp_dir_.GetPath(), - base::ThreadTaskRunnerHandle::Get().get(), + task_runner_.get(), nullptr /* free_disk_space_getter */)); ASSERT_TRUE(cache_->Initialize()); - metadata_.reset(new ResourceMetadata( - metadata_storage_.get(), cache_.get(), - base::ThreadTaskRunnerHandle::Get().get())); + metadata_.reset(new ResourceMetadata(metadata_storage_.get(), cache_.get(), + task_runner_.get())); ASSERT_EQ(FILE_ERROR_OK, metadata_->Initialize()); about_resource_loader_ = @@ -122,13 +133,22 @@ drive::util::kTeamDriveIdDefaultCorpus, scheduler_.get()); loader_controller_ = std::make_unique<LoaderController>(); directory_loader_ = std::make_unique<DirectoryLoader>( - logger_.get(), base::ThreadTaskRunnerHandle::Get().get(), - metadata_.get(), scheduler_.get(), root_folder_id_loader_.get(), - start_page_token_loader_.get(), loader_controller_.get(), - util::GetDriveMyDriveRootPath(), - drive::util::kTeamDriveIdDefaultCorpus); + logger_.get(), task_runner_.get(), metadata_.get(), scheduler_.get(), + root_folder_id_loader_.get(), start_page_token_loader_.get(), + loader_controller_.get(), util::GetDriveMyDriveRootPath(), + drive::util::kTeamDriveIdDefaultCorpus, task_runner_->GetMockClock()); } + void TearDown() override { + // We need to manually reset the objects that implement the Destroy idiom, + // that deletes the object on the |task_runner_|. This is simpler than + // introducing custom deleters that capture the |task_runner_| and + // invoke RunUntilIdle(). + metadata_.reset(); + cache_.reset(); + metadata_storage_.reset(); + task_runner_->RunUntilIdle(); + } // Adds a new file to the root directory of the service. std::unique_ptr<google_apis::FileResource> AddNewFile( const std::string& title) { @@ -141,7 +161,7 @@ title, false, // shared_with_me google_apis::test_util::CreateCopyResultCallback(&error, &entry)); - base::RunLoop().RunUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(google_apis::HTTP_CREATED, error); return entry; } @@ -175,16 +195,15 @@ &local_id)); } - content::TestBrowserThreadBundle thread_bundle_; + scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; base::ScopedTempDir temp_dir_; std::unique_ptr<TestingPrefServiceSimple> pref_service_; std::unique_ptr<EventLogger> logger_; std::unique_ptr<FakeDriveService> drive_service_; std::unique_ptr<JobScheduler> scheduler_; - std::unique_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests> - metadata_storage_; - std::unique_ptr<FileCache, test_util::DestroyHelperForTests> cache_; - std::unique_ptr<ResourceMetadata, test_util::DestroyHelperForTests> metadata_; + std::unique_ptr<ResourceMetadataStorage, DestroyHelper> metadata_storage_; + std::unique_ptr<FileCache, DestroyHelper> cache_; + std::unique_ptr<ResourceMetadata, DestroyHelper> metadata_; std::unique_ptr<AboutResourceLoader> about_resource_loader_; std::unique_ptr<StartPageTokenLoader> start_page_token_loader_; std::unique_ptr<LoaderController> loader_controller_; @@ -202,7 +221,7 @@ util::GetDriveGrandRootPath(), base::Bind(&AccumulateReadDirectoryResult, &entries), google_apis::test_util::CreateCopyResultCallback(&error)); - base::RunLoop().RunUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); EXPECT_EQ(0U, observer.changed_directories().size()); observer.clear_changed_directories(); @@ -232,7 +251,7 @@ util::GetDriveMyDriveRootPath(), base::Bind(&AccumulateReadDirectoryResult, &entries), google_apis::test_util::CreateCopyResultCallback(&error)); - base::RunLoop().RunUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); EXPECT_EQ(1U, observer.changed_directories().count( util::GetDriveMyDriveRootPath())); @@ -252,6 +271,65 @@ metadata_->GetResourceEntryByPath(file_path, &entry)); } +// Ensure that multiple requests in succession do not hit the backend until the +// time to refresh expires. +TEST_F(DirectoryLoaderTest, ReadDirectory_MyDriveTimedCache) { + TestDirectoryLoaderObserver observer(directory_loader_.get()); + + // My Drive does not have resource ID yet. + ResourceEntry entry; + EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath( + util::GetDriveMyDriveRootPath(), &entry)); + EXPECT_TRUE(entry.resource_id().empty()); + + // Load My Drive. + FileError error = FILE_ERROR_FAILED; + ResourceEntryVector entries; + directory_loader_->ReadDirectory( + util::GetDriveMyDriveRootPath(), + base::Bind(&AccumulateReadDirectoryResult, &entries), + google_apis::test_util::CreateCopyResultCallback(&error)); + task_runner_->RunUntilIdle(); + EXPECT_EQ(FILE_ERROR_OK, error); + EXPECT_EQ(1U, observer.changed_directories().count( + util::GetDriveMyDriveRootPath())); + + // My Drive has resource ID. + EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath( + util::GetDriveMyDriveRootPath(), &entry)); + EXPECT_EQ(drive_service_->GetRootResourceId(), entry.resource_id()); + EXPECT_EQ(drive_service_->start_page_token().start_page_token(), + entry.directory_specific_info().start_page_token()); + EXPECT_TRUE(entry.directory_specific_info().has_last_read_time_ms()); + int64_t read_time = entry.directory_specific_info().last_read_time_ms(); + + // Move forward 1 second, should not cause a new read of the backend. + observer.clear_changed_directories(); + task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(1)); + directory_loader_->ReadDirectory( + util::GetDriveMyDriveRootPath(), + base::Bind(&AccumulateReadDirectoryResult, &entries), + google_apis::test_util::CreateCopyResultCallback(&error)); + task_runner_->RunUntilIdle(); + EXPECT_EQ(FILE_ERROR_OK, error); + EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath( + util::GetDriveMyDriveRootPath(), &entry)); + EXPECT_EQ(read_time, entry.directory_specific_info().last_read_time_ms()); + + // Move forward 60 seconds, should cause a new read of the backend. + observer.clear_changed_directories(); + task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(60)); + directory_loader_->ReadDirectory( + util::GetDriveMyDriveRootPath(), + base::Bind(&AccumulateReadDirectoryResult, &entries), + google_apis::test_util::CreateCopyResultCallback(&error)); + task_runner_->RunUntilIdle(); + EXPECT_EQ(FILE_ERROR_OK, error); + EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath( + util::GetDriveMyDriveRootPath(), &entry)); + EXPECT_LT(read_time, entry.directory_specific_info().last_read_time_ms()); +} + TEST_F(DirectoryLoaderTest, ReadDirectory_MultipleCalls) { TestDirectoryLoaderObserver observer(directory_loader_.get()); @@ -270,7 +348,7 @@ util::GetDriveGrandRootPath(), base::Bind(&AccumulateReadDirectoryResult, &entries2), google_apis::test_util::CreateCopyResultCallback(&error2)); - base::RunLoop().RunUntilIdle(); + task_runner_->RunUntilIdle(); // Callback is called for each method call. EXPECT_EQ(FILE_ERROR_OK, error); @@ -290,14 +368,14 @@ util::GetDriveMyDriveRootPath(), base::Bind(&AccumulateReadDirectoryResult, &entries), google_apis::test_util::CreateCopyResultCallback(&error)); - base::RunLoop().RunUntilIdle(); + task_runner_->RunUntilIdle(); // Update is pending due to the lock. EXPECT_TRUE(observer.changed_directories().empty()); // Unlock the loader, this should resume the pending udpate. lock.reset(); - base::RunLoop().RunUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(1U, observer.changed_directories().count( util::GetDriveMyDriveRootPath())); } @@ -330,7 +408,7 @@ local_directory_loader->ReadDirectory( team_drive_path, base::Bind(&AccumulateReadDirectoryResult, &entries), google_apis::test_util::CreateCopyResultCallback(&error)); - base::RunLoop().RunUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); EXPECT_EQ(1, drive_service_->start_page_token_load_count()); EXPECT_EQ(1, drive_service_->directory_load_count());
diff --git a/components/drive/drive.proto b/components/drive/drive.proto index 95fb527d..bc27539d 100644 --- a/components/drive/drive.proto +++ b/components/drive/drive.proto
@@ -111,6 +111,12 @@ // The start page token of this directory. This value may not match the // start_page_token of ResourceMetadata if the directory was "fast-fetched". optional string start_page_token = 2; + + // The last time we read this directory from the server when fast fetching. + // This is used on initial load when we do not have the full list of files + // fetched from the server to prevent repeated reading of the directory file + // list. + optional int64 last_read_time_ms = 3; } // Represents metadata of a resource (file or directory) on Drive.
diff --git a/components/drive/file_system_unittest.cc b/components/drive/file_system_unittest.cc index 59ccdd3..b1b11c7 100644 --- a/components/drive/file_system_unittest.cc +++ b/components/drive/file_system_unittest.cc
@@ -16,9 +16,7 @@ #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/macros.h" -#include "base/run_loop.h" -#include "base/single_thread_task_runner.h" -#include "base/threading/thread_task_runner_handle.h" +#include "base/test/test_mock_time_task_runner.h" #include "components/drive/chromeos/drive_change_list_loader.h" #include "components/drive/chromeos/drive_test_util.h" #include "components/drive/chromeos/fake_free_disk_space_getter.h" @@ -116,11 +114,35 @@ DISALLOW_COPY_AND_ASSIGN(MockDirectoryChangeObserver); }; +struct DestroyHelper { + // FileSystemTest needs to be default constructible, so we provide a default + // constructor here. + DestroyHelper() = default; + + explicit DestroyHelper( + scoped_refptr<base::TestMockTimeTaskRunner> task_runner) + : task_runner_(task_runner) {} + + template <typename T> + void operator()(T* object) const { + DCHECK(task_runner_); + if (object) { + object->Destroy(); + task_runner_->RunUntilIdle(); + } + } + + scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; +}; + } // namespace class FileSystemTest : public testing::Test { protected: void SetUp() override { + task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>( + base::TestMockTimeTaskRunner::Type::kBoundToThread); + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); pref_service_ = std::make_unique<TestingPrefServiceSimple>(); test_util::RegisterDrivePrefs(pref_service_->registry()); @@ -133,7 +155,7 @@ scheduler_ = std::make_unique<JobScheduler>( pref_service_.get(), logger_.get(), fake_drive_service_.get(), - base::ThreadTaskRunnerHandle::Get().get(), nullptr); + task_runner_.get(), nullptr); mock_directory_observer_ = std::make_unique<MockDirectoryChangeObserver>(); @@ -143,29 +165,34 @@ void SetUpResourceMetadataAndFileSystem() { const base::FilePath metadata_dir = temp_dir_.GetPath().AppendASCII("meta"); ASSERT_TRUE(base::CreateDirectory(metadata_dir)); - metadata_storage_.reset(new internal::ResourceMetadataStorage( - metadata_dir, base::ThreadTaskRunnerHandle::Get().get())); + metadata_storage_ = + std::unique_ptr<internal::ResourceMetadataStorage, DestroyHelper>( + new internal::ResourceMetadataStorage(metadata_dir, + task_runner_.get()), + DestroyHelper(task_runner_.get())); ASSERT_TRUE(metadata_storage_->Initialize()); const base::FilePath cache_dir = temp_dir_.GetPath().AppendASCII("files"); ASSERT_TRUE(base::CreateDirectory(cache_dir)); - cache_.reset(new internal::FileCache( - metadata_storage_.get(), - cache_dir, - base::ThreadTaskRunnerHandle::Get().get(), - fake_free_disk_space_getter_.get())); + cache_ = std::unique_ptr<internal::FileCache, DestroyHelper>( + new internal::FileCache(metadata_storage_.get(), cache_dir, + task_runner_.get(), + fake_free_disk_space_getter_.get()), + DestroyHelper(task_runner_.get())); ASSERT_TRUE(cache_->Initialize()); - resource_metadata_.reset(new internal::ResourceMetadata( - metadata_storage_.get(), cache_.get(), - base::ThreadTaskRunnerHandle::Get())); + resource_metadata_ = + std::unique_ptr<internal::ResourceMetadata, DestroyHelper>( + new internal::ResourceMetadata(metadata_storage_.get(), + cache_.get(), task_runner_.get()), + DestroyHelper(task_runner_.get())); ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->Initialize()); const base::FilePath temp_file_dir = temp_dir_.GetPath().AppendASCII("tmp"); ASSERT_TRUE(base::CreateDirectory(temp_file_dir)); file_system_ = std::make_unique<FileSystem>( logger_.get(), cache_.get(), scheduler_.get(), resource_metadata_.get(), - base::ThreadTaskRunnerHandle::Get().get(), temp_file_dir); + task_runner_.get(), temp_file_dir, task_runner_->GetMockClock()); file_system_->AddObserver(mock_directory_observer_.get()); // Disable delaying so that the sync starts immediately. @@ -181,7 +208,7 @@ FileError error = FILE_ERROR_FAILED; file_system_->change_list_loader_for_testing()->LoadIfNeeded( google_apis::test_util::CreateCopyResultCallback(&error)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); return error == FILE_ERROR_OK; } @@ -193,7 +220,7 @@ file_system_->GetResourceEntry( file_path, google_apis::test_util::CreateCopyResultCallback(&error, &entry)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); return entry; } @@ -207,7 +234,7 @@ file_path, base::Bind(&AccumulateReadDirectoryResult, entries.get()), google_apis::test_util::CreateCopyResultCallback(&error)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); if (error != FILE_ERROR_OK) entries.reset(); return entries; @@ -243,22 +270,23 @@ const base::FilePath metadata_dir = temp_dir_.GetPath().AppendASCII("meta"); ASSERT_TRUE(base::CreateDirectory(metadata_dir)); - std::unique_ptr<internal::ResourceMetadataStorage, - test_util::DestroyHelperForTests> + std::unique_ptr<internal::ResourceMetadataStorage, DestroyHelper> metadata_storage(new internal::ResourceMetadataStorage( - metadata_dir, base::ThreadTaskRunnerHandle::Get().get())); + metadata_dir, task_runner_.get()), + DestroyHelper(task_runner_.get())); const base::FilePath cache_dir = temp_dir_.GetPath().AppendASCII("files"); - std::unique_ptr<internal::FileCache, test_util::DestroyHelperForTests> - cache(new internal::FileCache(metadata_storage.get(), cache_dir, - base::ThreadTaskRunnerHandle::Get().get(), - fake_free_disk_space_getter_.get())); + std::unique_ptr<internal::FileCache, DestroyHelper> cache( + new internal::FileCache(metadata_storage.get(), cache_dir, + task_runner_.get(), + fake_free_disk_space_getter_.get()), + DestroyHelper(task_runner_.get())); - std::unique_ptr<internal::ResourceMetadata, - test_util::DestroyHelperForTests> - resource_metadata(new internal::ResourceMetadata( - metadata_storage_.get(), cache.get(), - base::ThreadTaskRunnerHandle::Get())); + std::unique_ptr<internal::ResourceMetadata, DestroyHelper> + resource_metadata( + new internal::ResourceMetadata(metadata_storage_.get(), cache.get(), + task_runner_.get()), + DestroyHelper(task_runner_.get())); ASSERT_EQ(FILE_ERROR_OK, resource_metadata->Initialize()); @@ -429,7 +457,7 @@ return true; } - content::TestBrowserThreadBundle thread_bundle_; + scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; base::ScopedTempDir temp_dir_; // We don't use TestingProfile::GetPrefs() in favor of having less // dependencies to Profile in general. @@ -441,12 +469,10 @@ std::unique_ptr<JobScheduler> scheduler_; std::unique_ptr<MockDirectoryChangeObserver> mock_directory_observer_; - std::unique_ptr<internal::ResourceMetadataStorage, - test_util::DestroyHelperForTests> + std::unique_ptr<internal::ResourceMetadataStorage, DestroyHelper> metadata_storage_; - std::unique_ptr<internal::FileCache, test_util::DestroyHelperForTests> cache_; - std::unique_ptr<internal::ResourceMetadata, test_util::DestroyHelperForTests> - resource_metadata_; + std::unique_ptr<internal::FileCache, DestroyHelper> cache_; + std::unique_ptr<internal::ResourceMetadata, DestroyHelper> resource_metadata_; std::unique_ptr<FileSystem> file_system_; }; @@ -461,7 +487,7 @@ file_system_->SearchByHashes( hashes, google_apis::test_util::CreateCopyResultCallback(&error, &results)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); ASSERT_EQ(1u, results.size()); EXPECT_EQ(FILE_PATH_LITERAL("drive/root/File1"), results[0].path.value()); @@ -471,7 +497,7 @@ file_system_->SearchByHashes( hashes, google_apis::test_util::CreateCopyResultCallback(&error, &results)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); ASSERT_EQ(2u, results.size()); std::sort(results.begin(), results.end(), &CompareHashAndFilePath); @@ -486,7 +512,7 @@ file_system_->SearchByHashes( hashes, google_apis::test_util::CreateCopyResultCallback(&error, &results)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); ASSERT_EQ(3u, results.size()); std::sort(results.begin(), results.end(), &CompareHashAndFilePath); @@ -508,7 +534,7 @@ dest_file_path, false, // preserve_last_modified, google_apis::test_util::CreateCopyResultCallback(&error)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); // Entry is added on the server. @@ -520,7 +546,7 @@ fake_drive_service_->GetFileResource( entry->resource_id(), google_apis::test_util::CreateCopyResultCallback(&status, &server_entry)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(google_apis::HTTP_SUCCESS, status); ASSERT_TRUE(server_entry); EXPECT_EQ(entry->title(), server_entry->title()); @@ -541,7 +567,7 @@ file_system_->Move(src_file_path, dest_file_path, google_apis::test_util::CreateCopyResultCallback(&error)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); // Entry is moved on the server. @@ -553,7 +579,7 @@ fake_drive_service_->GetFileResource( entry->resource_id(), google_apis::test_util::CreateCopyResultCallback(&status, &server_entry)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(google_apis::HTTP_SUCCESS, status); ASSERT_TRUE(server_entry); EXPECT_EQ(entry->title(), server_entry->title()); @@ -572,7 +598,7 @@ file_path, false, // is_resursive google_apis::test_util::CreateCopyResultCallback(&error)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); // Entry is removed on the server. @@ -581,7 +607,7 @@ fake_drive_service_->GetFileResource( entry->resource_id(), google_apis::test_util::CreateCopyResultCallback(&status, &server_entry)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(google_apis::HTTP_SUCCESS, status); ASSERT_TRUE(server_entry); EXPECT_TRUE(server_entry->labels().is_trashed()); @@ -597,7 +623,7 @@ true, // is_exclusive false, // is_recursive google_apis::test_util::CreateCopyResultCallback(&error)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); // Directory is created on the server. @@ -609,7 +635,7 @@ fake_drive_service_->GetFileResource( entry->resource_id(), google_apis::test_util::CreateCopyResultCallback(&status, &server_entry)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(google_apis::HTTP_SUCCESS, status); ASSERT_TRUE(server_entry); EXPECT_EQ(entry->title(), server_entry->title()); @@ -626,7 +652,7 @@ true, // is_exclusive "text/plain", google_apis::test_util::CreateCopyResultCallback(&error)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); // File is created on the server. @@ -638,7 +664,7 @@ fake_drive_service_->GetFileResource( entry->resource_id(), google_apis::test_util::CreateCopyResultCallback(&status, &server_entry)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(google_apis::HTTP_SUCCESS, status); ASSERT_TRUE(server_entry); EXPECT_EQ(entry->title(), server_entry->title()); @@ -663,7 +689,7 @@ last_accessed, last_modified, google_apis::test_util::CreateCopyResultCallback(&error)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); // File is touched on the server. @@ -672,7 +698,7 @@ fake_drive_service_->GetFileResource( entry->resource_id(), google_apis::test_util::CreateCopyResultCallback(&status, &server_entry)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(google_apis::HTTP_SUCCESS, status); ASSERT_TRUE(server_entry); EXPECT_EQ(last_accessed, server_entry->last_viewed_by_me_date()); @@ -692,7 +718,7 @@ file_path, kLength, google_apis::test_util::CreateCopyResultCallback(&error)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); // File is touched on the server. @@ -701,7 +727,7 @@ fake_drive_service_->GetFileResource( entry->resource_id(), google_apis::test_util::CreateCopyResultCallback(&status, &server_entry)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(google_apis::HTTP_SUCCESS, status); ASSERT_TRUE(server_entry); EXPECT_EQ(kLength, server_entry->file_size()); @@ -999,7 +1025,7 @@ const int start_page_toke_load_count_before = fake_drive_service_->start_page_token_load_count(); file_system_->CheckForUpdates(); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_LT(start_page_toke_load_count_before, fake_drive_service_->start_page_token_load_count()); } @@ -1041,7 +1067,7 @@ file_system_->CheckForUpdates(); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(1, fake_drive_service_->start_page_token_load_count()); EXPECT_EQ(1, fake_drive_service_->change_list_load_count()); @@ -1085,7 +1111,7 @@ true, // is_exclusive false, // is_recursive google_apis::test_util::CreateCopyResultCallback(&error)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); // It should fail because is_exclusive is set to true. EXPECT_EQ(FILE_ERROR_EXISTS, error); @@ -1103,7 +1129,7 @@ true, // is_exclusive true, // is_recursive google_apis::test_util::CreateCopyResultCallback(&error)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); @@ -1154,6 +1180,9 @@ // Notify the update to the file system. file_system_->CheckForUpdates(); + // Fast forward the clock, so that a new read of the directory is started. + task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(1)); + // Read the directory once again. Although the full feed fetching is not yet // finished, the "fast fetch" of the directory works and the refreshed content // is returned. @@ -1176,7 +1205,7 @@ FileError error = FILE_ERROR_FAILED; file_system_->Pin(file_path, google_apis::test_util::CreateCopyResultCallback(&error)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); entry = GetResourceEntrySync(file_path); @@ -1188,7 +1217,7 @@ error = FILE_ERROR_FAILED; file_system_->Unpin(file_path, google_apis::test_util::CreateCopyResultCallback(&error)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); entry = GetResourceEntrySync(file_path); @@ -1223,7 +1252,7 @@ file_path, google_apis::test_util::CreateCopyResultCallback(&error_unpin)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error_pin); EXPECT_EQ(FILE_ERROR_OK, error_unpin); @@ -1240,7 +1269,7 @@ file_system_->GetAvailableSpace( google_apis::test_util::CreateCopyResultCallback( &error, &bytes_total, &bytes_used)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(6789012345LL, bytes_used); EXPECT_EQ(9876543210LL, bytes_total); } @@ -1258,7 +1287,7 @@ file_in_root, google_apis::test_util::CreateCopyResultCallback( &error, &file_path, &entry)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); // Test for mounting. @@ -1267,7 +1296,7 @@ file_system_->MarkCacheFileAsMounted( file_in_root, google_apis::test_util::CreateCopyResultCallback(&error, &file_path)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); error = FILE_ERROR_FAILED; @@ -1275,7 +1304,7 @@ file_system_->IsCacheFileMarkedAsMounted( file_in_root, google_apis::test_util::CreateCopyResultCallback( &error, &is_marked_as_mounted)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); EXPECT_TRUE(is_marked_as_mounted); @@ -1287,7 +1316,7 @@ file_system_->MarkCacheFileAsUnmounted( file_path, google_apis::test_util::CreateCopyResultCallback(&error)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); error = FILE_ERROR_FAILED; @@ -1295,7 +1324,7 @@ file_system_->IsCacheFileMarkedAsMounted( file_in_root, google_apis::test_util::CreateCopyResultCallback( &error, &is_marked_as_mounted)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); EXPECT_FALSE(is_marked_as_mounted); @@ -1315,7 +1344,7 @@ file_system_->GetFile(file_in_root, google_apis::test_util::CreateCopyResultCallback( &error, &file_path, &entry)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); ASSERT_TRUE(entry); EXPECT_TRUE(entry->file_specific_info().cache_state().is_present()); @@ -1324,7 +1353,7 @@ file_system_->FreeDiskSpaceIfNeededFor( 512LL << 40, google_apis::test_util::CreateCopyResultCallback(&available)); - content::RunAllTasksUntilIdle(); + task_runner_->RunUntilIdle(); ASSERT_FALSE(available); entry = GetResourceEntrySync(file_in_root);
diff --git a/components/exo/keyboard.cc b/components/exo/keyboard.cc index 3efdfa27..335fb8e 100644 --- a/components/exo/keyboard.cc +++ b/components/exo/keyboard.cc
@@ -17,9 +17,8 @@ #include "ui/aura/window.h" #include "ui/base/ime/input_method.h" #include "ui/events/base_event_utils.h" -#include "ui/events/devices/input_device.h" -#include "ui/events/devices/input_device_manager.h" #include "ui/events/event.h" +#include "ui/keyboard/keyboard_util.h" #include "ui/views/widget/widget.h" namespace exo { @@ -112,17 +111,9 @@ return false; } -bool IsPhysicalKeyboardEnabled() { - // The internal keyboard is enabled if tablet mode is not enabled. - if (!WMHelper::GetInstance()->IsTabletModeWindowManagerEnabled()) - return true; - - for (auto& keyboard : - ui::InputDeviceManager::GetInstance()->GetKeyboardDevices()) { - if (keyboard.type != ui::InputDeviceType::INPUT_DEVICE_INTERNAL) - return true; - } - return false; +bool IsVirtualKeyboardEnabled() { + return WMHelper::GetInstance()->IsAccessibilityKeyboardEnabled() || + keyboard::GetTouchKeyboardEnabled(); } bool IsReservedAccelerator(const ui::KeyEvent* event) { @@ -168,8 +159,8 @@ auto* helper = WMHelper::GetInstance(); AddEventHandler(); seat_->AddObserver(this); - helper->AddTabletModeObserver(this); - helper->AddInputDeviceEventObserver(this); + helper->AddAccessibilityObserver(this); + helper->AddVirtualKeyboardControllerObserver(this); OnSurfaceFocused(seat_->GetFocusedSurface()); } @@ -181,8 +172,8 @@ auto* helper = WMHelper::GetInstance(); RemoveEventHandler(); seat_->RemoveObserver(this); - helper->RemoveTabletModeObserver(this); - helper->RemoveInputDeviceEventObserver(this); + helper->RemoveVirtualKeyboardControllerObserver(this); + helper->RemoveAccessibilityObserver(this); } bool Keyboard::HasDeviceConfigurationDelegate() const { @@ -192,7 +183,7 @@ void Keyboard::SetDeviceConfigurationDelegate( KeyboardDeviceConfigurationDelegate* delegate) { device_configuration_delegate_ = delegate; - OnKeyboardDeviceConfigurationChanged(); + OnAccessibilityStatusChanged(); } void Keyboard::AddObserver(KeyboardObserver* observer) { @@ -331,29 +322,6 @@ } //////////////////////////////////////////////////////////////////////////////// -// ui::InputDeviceEventObserver overrides: - -void Keyboard::OnKeyboardDeviceConfigurationChanged() { - if (device_configuration_delegate_) { - device_configuration_delegate_->OnKeyboardTypeChanged( - IsPhysicalKeyboardEnabled()); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// ash::TabletModeObserver overrides: - -void Keyboard::OnTabletModeStarted() { - OnKeyboardDeviceConfigurationChanged(); -} - -void Keyboard::OnTabletModeEnding() {} - -void Keyboard::OnTabletModeEnded() { - OnKeyboardDeviceConfigurationChanged(); -} - -//////////////////////////////////////////////////////////////////////////////// // SeatObserver overrides: void Keyboard::OnSurfaceFocusing(Surface* gaining_focus) {} @@ -368,6 +336,24 @@ } //////////////////////////////////////////////////////////////////////////////// +// AccessibilityObserver overrides: + +void Keyboard::OnAccessibilityStatusChanged() { + if (device_configuration_delegate_) { + device_configuration_delegate_->OnKeyboardTypeChanged( + !IsVirtualKeyboardEnabled()); + } +} + +//////////////////////////////////////////////////////////////////////////////// +// VirtualKeyboardController::Observer overrides: + +void Keyboard::OnVirtualKeyboardStateChanged(bool enabled) { + if (device_configuration_delegate_) + device_configuration_delegate_->OnKeyboardTypeChanged(!enabled); +} + +//////////////////////////////////////////////////////////////////////////////// // Keyboard, private: void Keyboard::SetFocus(Surface* surface) {
diff --git a/components/exo/keyboard.h b/components/exo/keyboard.h index d395b41c..e807dbe 100644 --- a/components/exo/keyboard.h +++ b/components/exo/keyboard.h
@@ -7,7 +7,8 @@ #include <vector> -#include "ash/wm/tablet_mode/tablet_mode_observer.h" +#include "ash/accessibility/accessibility_observer.h" +#include "ash/keyboard/virtual_keyboard_controller_observer.h" #include "base/containers/flat_map.h" #include "base/containers/flat_set.h" #include "base/macros.h" @@ -15,7 +16,6 @@ #include "components/exo/keyboard_observer.h" #include "components/exo/seat_observer.h" #include "components/exo/surface_observer.h" -#include "ui/events/devices/input_device_event_observer.h" #include "ui/events/event.h" #include "ui/events/event_handler.h" @@ -33,10 +33,10 @@ // This class implements a client keyboard that represents one or more keyboard // devices. class Keyboard : public ui::EventHandler, - public ui::InputDeviceEventObserver, - public ash::TabletModeObserver, public SurfaceObserver, - public SeatObserver { + public SeatObserver, + public ash::AccessibilityObserver, + public ash::VirtualKeyboardControllerObserver { public: Keyboard(KeyboardDelegate* delegate, Seat* seat); ~Keyboard() override; @@ -63,18 +63,16 @@ // Overridden from SurfaceObserver: void OnSurfaceDestroying(Surface* surface) override; - // Overridden from ui::InputDeviceEventObserver: - void OnKeyboardDeviceConfigurationChanged() override; - - // Overridden from ash::TabletModeObserver: - void OnTabletModeStarted() override; - void OnTabletModeEnding() override; - void OnTabletModeEnded() override; - // Overridden from SeatObserver: void OnSurfaceFocusing(Surface* gaining_focus) override; void OnSurfaceFocused(Surface* gained_focus) override; + // Overridden from AccessibilityObserver: + void OnAccessibilityStatusChanged() override; + + // Overridden from VirtualKeyboardController::Observer + void OnVirtualKeyboardStateChanged(bool enabled) override; + private: // Change keyboard focus to |surface|. void SetFocus(Surface* surface);
diff --git a/components/exo/keyboard_unittest.cc b/components/exo/keyboard_unittest.cc index 13627079..618987a 100644 --- a/components/exo/keyboard_unittest.cc +++ b/components/exo/keyboard_unittest.cc
@@ -4,6 +4,7 @@ #include "components/exo/keyboard.h" +#include "ash/accessibility/accessibility_controller.h" #include "ash/shell.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "base/macros.h" @@ -305,10 +306,15 @@ ui::DeviceHotplugEventObserver* device_data_manager = ui::DeviceDataManager::GetInstance(); ASSERT_TRUE(device_data_manager != nullptr); - // Make sure that DeviceDataManager has one external keyboard. + // Make sure that DeviceDataManager has one external keyboard... const std::vector<ui::InputDevice> keyboards{ ui::InputDevice(2, ui::InputDeviceType::INPUT_DEVICE_USB, "keyboard")}; device_data_manager->OnKeyboardDevicesUpdated(keyboards); + // and a touch screen. + const std::vector<ui::TouchscreenDevice> touch_screen{ + ui::TouchscreenDevice(3, ui::InputDeviceType::INPUT_DEVICE_INTERNAL, + "touch", gfx::Size(600, 400), 1)}; + device_data_manager->OnTouchscreenDevicesUpdated(touch_screen); ash::TabletModeController* tablet_mode_controller = ash::Shell::Get()->tablet_mode_controller(); @@ -329,7 +335,7 @@ device_data_manager->OnKeyboardDevicesUpdated( std::vector<ui::InputDevice>({})); - // Re-adding keyboards calls OnKeyboardTypeChanged() with true; + // Re-adding keyboards calls OnKeyboardTypeChanged() with true. EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(true)); device_data_manager->OnKeyboardDevicesUpdated(keyboards); @@ -338,6 +344,50 @@ tablet_mode_controller->EnableTabletModeWindowManager(false); } +TEST_F(KeyboardTest, OnKeyboardTypeChanged_AccessibilityKeyboard) { + std::unique_ptr<Surface> surface(new Surface); + std::unique_ptr<ShellSurface> shell_surface(new ShellSurface(surface.get())); + gfx::Size buffer_size(10, 10); + std::unique_ptr<Buffer> buffer( + new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size))); + surface->Attach(buffer.get()); + surface->Commit(); + + aura::client::FocusClient* focus_client = + aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow()); + focus_client->FocusWindow(nullptr); + + ui::DeviceHotplugEventObserver* device_data_manager = + ui::DeviceDataManager::GetInstance(); + ASSERT_TRUE(device_data_manager != nullptr); + // Make sure that DeviceDataManager has one external keyboard. + const std::vector<ui::InputDevice> keyboards{ + ui::InputDevice(2, ui::InputDeviceType::INPUT_DEVICE_USB, "keyboard")}; + device_data_manager->OnKeyboardDevicesUpdated(keyboards); + + MockKeyboardDelegate delegate; + Seat seat; + auto keyboard = std::make_unique<Keyboard>(&delegate, &seat); + MockKeyboardDeviceConfigurationDelegate configuration_delegate; + + EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(true)); + keyboard->SetDeviceConfigurationDelegate(&configuration_delegate); + EXPECT_TRUE(keyboard->HasDeviceConfigurationDelegate()); + + ash::AccessibilityController* accessibility_controller = + ash::Shell::Get()->accessibility_controller(); + + // Enable a11y keyboard calls OnKeyboardTypeChanged() with false. + EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(false)); + accessibility_controller->SetVirtualKeyboardEnabled(true); + + // Disable a11y keyboard calls OnKeyboardTypeChanged() with true. + EXPECT_CALL(configuration_delegate, OnKeyboardTypeChanged(true)); + accessibility_controller->SetVirtualKeyboardEnabled(false); + + keyboard.reset(); +} + TEST_F(KeyboardTest, KeyboardObserver) { MockKeyboardDelegate delegate; Seat seat;
diff --git a/components/exo/wm_helper.cc b/components/exo/wm_helper.cc index 63b7135..cae0a7f 100644 --- a/components/exo/wm_helper.cc +++ b/components/exo/wm_helper.cc
@@ -4,6 +4,8 @@ #include "components/exo/wm_helper.h" +#include "ash/accessibility/accessibility_controller.h" +#include "ash/keyboard/virtual_keyboard_controller.h" #include "ash/shell.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" #include "base/memory/singleton.h" @@ -13,7 +15,6 @@ #include "ui/display/manager/display_configurator.h" #include "ui/display/manager/display_manager.h" #include "ui/display/types/display_snapshot.h" -#include "ui/events/devices/input_device_manager.h" #include "ui/wm/public/activation_client.h" namespace exo { @@ -53,6 +54,15 @@ return !!g_instance; } +void WMHelper::AddAccessibilityObserver(ash::AccessibilityObserver* observer) { + ash::Shell::Get()->accessibility_controller()->AddObserver(observer); +} + +void WMHelper::RemoveAccessibilityObserver( + ash::AccessibilityObserver* observer) { + ash::Shell::Get()->accessibility_controller()->RemoveObserver(observer); +} + void WMHelper::AddActivationObserver(wm::ActivationChangeObserver* observer) { ash::Shell::Get()->activation_client()->AddObserver(observer); } @@ -79,14 +89,14 @@ ash::Shell::Get()->tablet_mode_controller()->RemoveObserver(observer); } -void WMHelper::AddInputDeviceEventObserver( - ui::InputDeviceEventObserver* observer) { - ui::InputDeviceManager::GetInstance()->AddObserver(observer); +void WMHelper::AddVirtualKeyboardControllerObserver( + ash::VirtualKeyboardControllerObserver* observer) { + ash::Shell::Get()->virtual_keyboard_controller()->AddObserver(observer); } -void WMHelper::RemoveInputDeviceEventObserver( - ui::InputDeviceEventObserver* observer) { - ui::InputDeviceManager::GetInstance()->RemoveObserver(observer); +void WMHelper::RemoveVirtualKeyboardControllerObserver( + ash::VirtualKeyboardControllerObserver* observer) { + ash::Shell::Get()->virtual_keyboard_controller()->RemoveObserver(observer); } void WMHelper::AddDisplayConfigurationObserver( @@ -231,4 +241,10 @@ return display_info.display_modes()[0].device_scale_factor(); } +bool WMHelper::IsAccessibilityKeyboardEnabled() const { + return ash::Shell::Get() + ->accessibility_controller() + ->IsVirtualKeyboardEnabled(); +} + } // namespace exo
diff --git a/components/exo/wm_helper.h b/components/exo/wm_helper.h index 5fc156b..7e3c833 100644 --- a/components/exo/wm_helper.h +++ b/components/exo/wm_helper.h
@@ -15,7 +15,9 @@ #include "ui/compositor/compositor_vsync_manager.h" namespace ash { +class AccessibilityObserver; class TabletModeObserver; +class VirtualKeyboardControllerObserver; } namespace aura { @@ -38,7 +40,6 @@ namespace ui { class EventHandler; class DropTargetEvent; -class InputDeviceEventObserver; } // namespace ui namespace wm { @@ -70,14 +71,18 @@ aura::Env* env() { return env_; } + void AddAccessibilityObserver(ash::AccessibilityObserver* observer); + void RemoveAccessibilityObserver(ash::AccessibilityObserver* observer); void AddActivationObserver(wm::ActivationChangeObserver* observer); void RemoveActivationObserver(wm::ActivationChangeObserver* observer); void AddFocusObserver(aura::client::FocusChangeObserver* observer); void RemoveFocusObserver(aura::client::FocusChangeObserver* observer); void AddTabletModeObserver(ash::TabletModeObserver* observer); void RemoveTabletModeObserver(ash::TabletModeObserver* observer); - void AddInputDeviceEventObserver(ui::InputDeviceEventObserver* observer); - void RemoveInputDeviceEventObserver(ui::InputDeviceEventObserver* observer); + void AddVirtualKeyboardControllerObserver( + ash::VirtualKeyboardControllerObserver* observer); + void RemoveVirtualKeyboardControllerObserver( + ash::VirtualKeyboardControllerObserver* observer); void AddDisplayConfigurationObserver( ash::WindowTreeHostManager::Observer* observer); @@ -105,6 +110,7 @@ void RemovePostTargetHandler(ui::EventHandler* handler); bool IsTabletModeWindowManagerEnabled() const; double GetDefaultDeviceScaleFactor() const; + bool IsAccessibilityKeyboardEnabled() const; // Overridden from aura::client::DragDropDelegate: void OnDragEntered(const ui::DropTargetEvent& event) override;
diff --git a/components/network_session_configurator/browser/network_session_configurator.cc b/components/network_session_configurator/browser/network_session_configurator.cc index 0832147..8c30849 100644 --- a/components/network_session_configurator/browser/network_session_configurator.cc +++ b/components/network_session_configurator/browser/network_session_configurator.cc
@@ -330,6 +330,13 @@ "true"); } +bool ShouldQuicRaceStaleDNSOnConnection( + const VariationParameters& quic_trial_params) { + return base::LowerCaseEqualsASCII( + GetVariationParam(quic_trial_params, "race_stale_dns_on_connection"), + "true"); +} + int GetQuicMaxTimeOnNonDefaultNetworkSeconds( const VariationParameters& quic_trial_params) { int value; @@ -473,6 +480,8 @@ ShouldQuicRetryOnAlternateNetworkBeforeHandshake(quic_trial_params); params->quic_go_away_on_path_degrading = ShouldQuicGoawayOnPathDegrading(quic_trial_params); + params->quic_race_stale_dns_on_connection = + ShouldQuicRaceStaleDNSOnConnection(quic_trial_params); int max_time_on_non_default_network_seconds = GetQuicMaxTimeOnNonDefaultNetworkSeconds(quic_trial_params); if (max_time_on_non_default_network_seconds > 0) {
diff --git a/components/network_session_configurator/browser/network_session_configurator_unittest.cc b/components/network_session_configurator/browser/network_session_configurator_unittest.cc index d2848e7f..0c8388a5 100644 --- a/components/network_session_configurator/browser/network_session_configurator_unittest.cc +++ b/components/network_session_configurator/browser/network_session_configurator_unittest.cc
@@ -118,6 +118,7 @@ EXPECT_FALSE(params_.quic_estimate_initial_rtt); EXPECT_FALSE(params_.quic_migrate_sessions_on_network_change_v2); EXPECT_FALSE(params_.quic_migrate_sessions_early_v2); + EXPECT_FALSE(params_.quic_race_stale_dns_on_connection); EXPECT_FALSE(params_.quic_retry_on_alternate_network_before_handshake); EXPECT_FALSE(params_.quic_go_away_on_path_degrading); EXPECT_FALSE(params_.quic_allow_server_migration); @@ -361,6 +362,18 @@ } TEST_F(NetworkSessionConfiguratorTest, + QuicRaceStaleDNSOnCOnnectionFromFieldTrialParams) { + std::map<std::string, std::string> field_trial_params; + field_trial_params["race_stale_dns_on_connection"] = "true"; + variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params); + base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled"); + + ParseFieldTrials(); + + EXPECT_TRUE(params_.quic_race_stale_dns_on_connection); +} + +TEST_F(NetworkSessionConfiguratorTest, QuicGoawayOnPathDegradingFromFieldTrialParams) { std::map<std::string, std::string> field_trial_params; field_trial_params["go_away_on_path_degrading"] = "true";
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc index cce20ad..cba8ae0 100644 --- a/components/omnibox/browser/omnibox_field_trial.cc +++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -811,6 +811,10 @@ omnibox::kUIExperimentVerticalMargin, kUIVerticalMarginParam, 10); } +bool OmniboxFieldTrial::IsExperimentalKeywordModeEnabled() { + return base::FeatureList::IsEnabled(omnibox::kExperimentalKeywordMode); +} + const char OmniboxFieldTrial::kBundledExperimentFieldTrialName[] = "OmniboxBundledExperimentV1"; const char OmniboxFieldTrial::kDisableProvidersRule[] = "DisableProviders";
diff --git a/components/omnibox/browser/omnibox_field_trial.h b/components/omnibox/browser/omnibox_field_trial.h index 8de5ab80..d0c98da 100644 --- a/components/omnibox/browser/omnibox_field_trial.h +++ b/components/omnibox/browser/omnibox_field_trial.h
@@ -454,6 +454,9 @@ // suggestion view. static int GetSuggestionVerticalMargin(); + // Returns true if the experimental keyword mode is enabled. + static bool IsExperimentalKeywordModeEnabled(); + // --------------------------------------------------------- // Clipboard URL suggestions:
diff --git a/components/printing/browser/print_manager.cc b/components/printing/browser/print_manager.cc index 6dbe709..c826ab67 100644 --- a/components/printing/browser/print_manager.cc +++ b/components/printing/browser/print_manager.cc
@@ -63,7 +63,7 @@ #if defined(OS_ANDROID) void PrintManager::PdfWritingDone(int page_count) { if (!pdf_writing_done_callback_.is_null()) - pdf_writing_done_callback_.Run(file_descriptor().fd, page_count); + pdf_writing_done_callback_.Run(page_count); // Invalidate the file descriptor so it doesn't get reused. file_descriptor_ = base::FileDescriptor(-1, false); }
diff --git a/components/printing/browser/print_manager.h b/components/printing/browser/print_manager.h index 1635d368..b8a23bc 100644 --- a/components/printing/browser/print_manager.h +++ b/components/printing/browser/print_manager.h
@@ -22,7 +22,7 @@ #if defined(OS_ANDROID) // TODO(timvolodine): consider introducing PrintManagerAndroid (crbug/500960) - using PdfWritingDoneCallback = base::Callback<void(int, int)>; + using PdfWritingDoneCallback = base::Callback<void(int /* page count */)>; void PdfWritingDone(int page_count);
diff --git a/components/variations/client_filterable_state.h b/components/variations/client_filterable_state.h index bd2f86d..a244f79 100644 --- a/components/variations/client_filterable_state.h +++ b/components/variations/client_filterable_state.h
@@ -47,11 +47,6 @@ // Based on base::SysInfo::IsLowEndDevice(). bool is_low_end_device = false; - // Whether this platform supports experiments which retain their group - // assignments across runs. - // TODO(paulmiller): Remove this once https://crbug.com/866722 is resolved. - bool supports_permanent_consistency = true; - // The country code to use for studies configured with session consistency. std::string session_consistency_country;
diff --git a/components/variations/service/BUILD.gn b/components/variations/service/BUILD.gn index c77020f..e3c0c1e 100644 --- a/components/variations/service/BUILD.gn +++ b/components/variations/service/BUILD.gn
@@ -12,7 +12,6 @@ "variations_field_trial_creator.h", "variations_service.cc", "variations_service.h", - "variations_service_client.cc", "variations_service_client.h", ]
diff --git a/components/variations/service/variations_field_trial_creator.cc b/components/variations/service/variations_field_trial_creator.cc index cd546bc..a4d3e74 100644 --- a/components/variations/service/variations_field_trial_creator.cc +++ b/components/variations/service/variations_field_trial_creator.cc
@@ -259,8 +259,6 @@ // evaluated, that field trial would not be able to apply for this case. state->is_low_end_device = base::SysInfo::IsLowEndDevice(); #endif - state->supports_permanent_consistency = - client_->GetSupportsPermanentConsistency(); state->session_consistency_country = GetLatestCountry(); state->permanent_consistency_country = LoadPermanentConsistencyCountry( version, state->session_consistency_country);
diff --git a/components/variations/service/variations_service_client.cc b/components/variations/service/variations_service_client.cc deleted file mode 100644 index c2baa85c..0000000 --- a/components/variations/service/variations_service_client.cc +++ /dev/null
@@ -1,13 +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 "components/variations/service/variations_service_client.h" - -namespace variations { - -bool VariationsServiceClient::GetSupportsPermanentConsistency() { - return true; -} - -} // namespace variations
diff --git a/components/variations/service/variations_service_client.h b/components/variations/service/variations_service_client.h index 4e2c644..2b466bb 100644 --- a/components/variations/service/variations_service_client.h +++ b/components/variations/service/variations_service_client.h
@@ -45,11 +45,6 @@ // Gets the channel of the embedder. virtual version_info::Channel GetChannel() = 0; - // Gets whether this platform supports experiments which retain their group - // assignments across runs. - // TODO(paulmiller): Remove this once https://crbug.com/866722 is resolved. - virtual bool GetSupportsPermanentConsistency(); - // Returns whether the embedder overrides the value of the restrict parameter. // |parameter| is an out-param that will contain the value of the restrict // parameter if true is returned.
diff --git a/components/variations/study_filtering.cc b/components/variations/study_filtering.cc index 6f1e2177..eaca58a 100644 --- a/components/variations/study_filtering.cc +++ b/components/variations/study_filtering.cc
@@ -12,7 +12,6 @@ #include "base/stl_util.h" #include "base/strings/string_util.h" #include "components/variations/client_filterable_state.h" -#include "components/variations/proto/study.pb.h" namespace variations { namespace { @@ -267,14 +266,6 @@ } } - // TODO(paulmiller): Remove this once https://crbug.com/866722 is resolved. - if (study.consistency() == Study_Consistency_PERMANENT && - !client_state.supports_permanent_consistency) { - DVLOG(1) << "Filtered out study " << study.name() - << " due to supports_permanent_consistency."; - return false; - } - DVLOG(1) << "Kept study " << study.name() << "."; return true; }
diff --git a/components/viz/common/features.cc b/components/viz/common/features.cc index 1d6ccb77..f9c2876 100644 --- a/components/viz/common/features.cc +++ b/components/viz/common/features.cc
@@ -30,8 +30,8 @@ base::FEATURE_DISABLED_BY_DEFAULT}; // Enables running the Viz-assisted hit-test logic. -const base::Feature kEnableVizHitTestDrawQuad{"VizHitTestDrawQuad", - base::FEATURE_ENABLED_BY_DEFAULT}; +const base::Feature kEnableVizHitTestDrawQuad{ + "VizHitTestDrawQuad", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kEnableVizHitTestSurfaceLayer{ "VizHitTestSurfaceLayer", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/components/viz/service/display/display.cc b/components/viz/service/display/display.cc index 78b35d2..eb754bb 100644 --- a/components/viz/service/display/display.cc +++ b/components/viz/service/display/display.cc
@@ -294,6 +294,18 @@ return false; } + // During aggregation, SurfaceAggregator marks all resources used for a draw + // in the resource provider. This has the side effect of deleting unused + // resources and their textures, generating sync tokens, and returning the + // resources to the client. This involves GL work which is issued before + // drawing commands, and gets prioritized by GPU scheduler because sync token + // dependencies aren't issued until the draw. + // + // Batch and defer returning resources in resource provider. This defers the + // GL commands for deleting resources to after the draw, and prevents context + // switching because the scheduler knows sync token dependencies at that time. + DisplayResourceProvider::ScopedBatchReturnResources returner( + resource_provider_.get()); base::ElapsedTimer aggregate_timer; CompositorFrame frame = aggregator_->Aggregate( current_surface_id_,
diff --git a/components/viz/service/display/display_resource_provider.cc b/components/viz/service/display/display_resource_provider.cc index 129624f..73e5787 100644 --- a/components/viz/service/display/display_resource_provider.cc +++ b/components/viz/service/display/display_resource_provider.cc
@@ -555,14 +555,8 @@ ChildResource* resource = &it->second; if (resource->marked_for_deletion && !resource->lock_for_read_count && !resource->locked_for_external_use) { - if (batch_return_resources_) { - batched_returning_resources_[resource->child_id].push_back(id); - } else { - auto child_it = children_.find(resource->child_id); - std::vector<ResourceId> unused; - unused.push_back(id); - DeleteAndReturnUnusedResourcesToChild(child_it, NORMAL, unused); - } + auto child_it = children_.find(resource->child_id); + DeleteAndReturnUnusedResourcesToChild(child_it, NORMAL, {id}); } } @@ -617,9 +611,23 @@ DCHECK(child_it != children_.end()); Child* child_info = &child_it->second; + // No work is done in this case. if (unused.empty() && !child_info->marked_for_deletion) return; + // Store unused resources while batching is enabled. + if (batch_return_resources_lock_count_ > 0) { + int child_id = child_it->first; + // Ensure that we have an entry in |batched_returning_resources_| for child + // even if |unused| is empty, in case child is marked for deletion. + // Note: emplace() does not overwrite an entry if already present. + batched_returning_resources_.emplace(child_id, std::vector<ResourceId>()); + auto& child_resources = batched_returning_resources_[child_id]; + child_resources.reserve(child_resources.size() + unused.size()); + child_resources.insert(child_resources.end(), unused.begin(), unused.end()); + return; + } + std::vector<ReturnedResource> to_return; to_return.reserve(unused.size()); std::vector<ReturnedResource*> need_synchronization_resources; @@ -750,15 +758,32 @@ } void DisplayResourceProvider::SetBatchReturnResources(bool batch) { - DCHECK_NE(batch_return_resources_, batch); - batch_return_resources_ = batch; - if (!batch) { - for (const auto& resources : batched_returning_resources_) { - auto child_it = children_.find(resources.first); - DCHECK(child_it != children_.end()); - DeleteAndReturnUnusedResourcesToChild(child_it, NORMAL, resources.second); + if (batch) { + DCHECK_GE(batch_return_resources_lock_count_, 0); + batch_return_resources_lock_count_++; + } else { + DCHECK_GT(batch_return_resources_lock_count_, 0); + batch_return_resources_lock_count_--; + if (batch_return_resources_lock_count_ == 0) { + for (auto& child_resources_kv : batched_returning_resources_) { + auto child_it = children_.find(child_resources_kv.first); + + // Remove duplicates from child's unused resources. Duplicates are + // possible when batching is enabled because resources are saved in + // |batched_returning_resources_| for removal, and not removed from the + // child's |child_to_parent_map|, so the same set of resources can be + // saved again using DeclareUsedResourcesForChild() or DestroyChild(). + auto& unused_resources = child_resources_kv.second; + std::sort(unused_resources.begin(), unused_resources.end()); + auto last = + std::unique(unused_resources.begin(), unused_resources.end()); + unused_resources.erase(last, unused_resources.end()); + + DeleteAndReturnUnusedResourcesToChild(child_it, NORMAL, + unused_resources); + } + batched_returning_resources_.clear(); } - batched_returning_resources_.clear(); } }
diff --git a/components/viz/service/display/display_resource_provider.h b/components/viz/service/display/display_resource_provider.h index 1e22a807..ccdc7ea3 100644 --- a/components/viz/service/display/display_resource_provider.h +++ b/components/viz/service/display/display_resource_provider.h
@@ -461,13 +461,11 @@ ResourceMap resources_; ChildMap children_; base::flat_map<ResourceId, sk_sp<SkImage>> resource_sk_image_; - // Maps from a child id to the set of resources to be returned to it. - base::small_map<std::map<int, std::vector<ResourceId>>> - batched_returning_resources_; + base::flat_map<int, std::vector<ResourceId>> batched_returning_resources_; scoped_refptr<ResourceFence> current_read_lock_fence_; // Keep track of whether deleted resources should be batched up or returned // immediately. - bool batch_return_resources_ = false; + int batch_return_resources_lock_count_ = 0; // Set to true when the ContextProvider becomes lost, to inform that resources // modified by this class are now in an indeterminate state. bool lost_context_provider_ = false;
diff --git a/components/viz/service/display/display_resource_provider_unittest.cc b/components/viz/service/display/display_resource_provider_unittest.cc index bfbc68e..596d49db 100644 --- a/components/viz/service/display/display_resource_provider_unittest.cc +++ b/components/viz/service/display/display_resource_provider_unittest.cc
@@ -819,58 +819,89 @@ GetReturnCallback(&returned_to_child), true); // Transfer some resources to the parent. - std::vector<ResourceId> resource_ids_to_transfer; - ResourceId ids[2]; - for (size_t i = 0; i < base::size(ids); i++) { + constexpr size_t kTotalResources = 5; + constexpr size_t kLockedResources = 3; + constexpr size_t kUsedResources = 4; + ResourceId ids[kTotalResources]; + for (size_t i = 0; i < kTotalResources; i++) { TransferableResource tran = CreateResource(RGBA_8888); ids[i] = child_resource_provider_->ImportResource( tran, SingleReleaseCallback::Create(base::BindOnce( &MockReleaseCallback::Released, base::Unretained(&release)))); - resource_ids_to_transfer.push_back(ids[i]); } + std::vector<ResourceId> resource_ids_to_transfer(ids, ids + kTotalResources); std::vector<TransferableResource> list; child_resource_provider_->PrepareSendToParent(resource_ids_to_transfer, &list, child_context_provider_.get()); - ASSERT_EQ(2u, list.size()); - EXPECT_TRUE(child_resource_provider_->InUseByConsumer(ids[0])); - EXPECT_TRUE(child_resource_provider_->InUseByConsumer(ids[1])); + ASSERT_EQ(kTotalResources, list.size()); + for (const auto& id : ids) + EXPECT_TRUE(child_resource_provider_->InUseByConsumer(id)); resource_provider_->ReceiveFromChild(child_id, list); // In DisplayResourceProvider's namespace, use the mapped resource id. std::unordered_map<ResourceId, ResourceId> resource_map = resource_provider_->GetChildToParentMap(child_id); - std::vector<std::unique_ptr<DisplayResourceProvider::ScopedReadLockGL>> read_locks; - for (auto& resource_id : list) { - unsigned int mapped_resource_id = resource_map[resource_id.id]; + for (size_t i = 0; i < kLockedResources; i++) { + unsigned int mapped_resource_id = resource_map[ids[i]]; resource_provider_->WaitSyncToken(mapped_resource_id); read_locks.push_back( std::make_unique<DisplayResourceProvider::ScopedReadLockGL>( resource_provider_.get(), mapped_resource_id)); } - resource_provider_->DeclareUsedResourcesFromChild(child_id, ResourceIdSet()); - std::unique_ptr<DisplayResourceProvider::ScopedBatchReturnResources> - returner = - std::make_unique<DisplayResourceProvider::ScopedBatchReturnResources>( - resource_provider_.get()); - EXPECT_EQ(0u, returned_to_child.size()); + // Mark all locked resources, and one unlocked resource as used for first + // batch. + { + DisplayResourceProvider::ScopedBatchReturnResources returner( + resource_provider_.get()); + resource_provider_->DeclareUsedResourcesFromChild( + child_id, ResourceIdSet(ids, ids + kUsedResources)); + EXPECT_EQ(0u, returned_to_child.size()); + } + EXPECT_EQ(1u, returned_to_child.size()); + child_resource_provider_->ReceiveReturnsFromParent(returned_to_child); + returned_to_child.clear(); - read_locks.clear(); - EXPECT_EQ(0u, returned_to_child.size()); - - returner.reset(); - EXPECT_EQ(2u, returned_to_child.size()); - // All resources in a batch should share a sync token. - EXPECT_EQ(returned_to_child[0].sync_token, returned_to_child[1].sync_token); + // Return all locked resources. + { + DisplayResourceProvider::ScopedBatchReturnResources returner( + resource_provider_.get()); + resource_provider_->DeclareUsedResourcesFromChild( + child_id, ResourceIdSet(ids + kLockedResources, ids + kUsedResources)); + // Can be called multiple times while batching is enabled. This happens in + // practice when the same surface is visited using different paths during + // surface aggregation. + resource_provider_->DeclareUsedResourcesFromChild( + child_id, ResourceIdSet(ids + kLockedResources, ids + kUsedResources)); + read_locks.clear(); + EXPECT_EQ(0u, returned_to_child.size()); + } + EXPECT_EQ(kLockedResources, returned_to_child.size()); + // Returned resources that were locked share the same sync token. + for (const auto& resource : returned_to_child) + EXPECT_EQ(resource.sync_token, returned_to_child[0].sync_token); child_resource_provider_->ReceiveReturnsFromParent(returned_to_child); - EXPECT_CALL(release, Released(_, _)).Times(2); - child_resource_provider_->RemoveImportedResource(ids[0]); - child_resource_provider_->RemoveImportedResource(ids[1]); + returned_to_child.clear(); + + // Returns from destroying the child is also batched. + { + DisplayResourceProvider::ScopedBatchReturnResources returner( + resource_provider_.get()); + resource_provider_->DestroyChild(child_id); + EXPECT_EQ(0u, returned_to_child.size()); + } + EXPECT_EQ(1u, returned_to_child.size()); + child_resource_provider_->ReceiveReturnsFromParent(returned_to_child); + returned_to_child.clear(); + + EXPECT_CALL(release, Released(_, _)).Times(kTotalResources); + for (const auto& id : ids) + child_resource_provider_->RemoveImportedResource(id); } TEST_P(DisplayResourceProviderTest, LostMailboxInParent) {
diff --git a/components/viz/service/gl/gpu_service_impl.cc b/components/viz/service/gl/gpu_service_impl.cc index 40a6b345..8ef41f3 100644 --- a/components/viz/service/gl/gpu_service_impl.cc +++ b/components/viz/service/gl/gpu_service_impl.cc
@@ -537,8 +537,9 @@ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); DCHECK(command_line->HasSwitch("disable-gpu-sandbox") || in_host_process()); - gpu::RecordGpuSupportedRuntimeVersionHistograms(&gpu_info_); - std::move(callback).Run(gpu_info_); + gpu::RecordGpuSupportedRuntimeVersionHistograms( + &gpu_info_.dx12_vulkan_version_info); + std::move(callback).Run(gpu_info_.dx12_vulkan_version_info); if (!in_host_process()) { // The unsandboxed GPU process fulfilled its duty. Bye bye. ExitProcess();
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc index 444e29e..df186ce 100644 --- a/content/browser/devtools/protocol/network_handler.cc +++ b/content/browser/devtools/protocol/network_handler.cc
@@ -102,7 +102,7 @@ case net::ct::CTPolicyCompliance:: CT_POLICY_COMPLIANCE_DETAILS_NOT_AVAILABLE: return Network::CertificateTransparencyComplianceEnum::Unknown; - case net::ct::CTPolicyCompliance::CT_POLICY_MAX: + case net::ct::CTPolicyCompliance::CT_POLICY_COUNT: NOTREACHED(); return Network::CertificateTransparencyComplianceEnum::Unknown; }
diff --git a/content/browser/devtools/protocol/system_info_handler.cc b/content/browser/devtools/protocol/system_info_handler.cc index 68492e4..def5f6b 100644 --- a/content/browser/devtools/protocol/system_info_handler.cc +++ b/content/browser/devtools/protocol/system_info_handler.cc
@@ -90,6 +90,10 @@ void EndOverlayCapability() override {} + void BeginDx12VulkanVersionInfo() override {} + + void EndDx12VulkanVersionInfo() override {} + void BeginAuxAttributes() override { in_aux_attributes_ = true; }
diff --git a/content/browser/fileapi/file_system_manager_impl.cc b/content/browser/fileapi/file_system_manager_impl.cc index 29f1d2d..9a9d1839 100644 --- a/content/browser/fileapi/file_system_manager_impl.cc +++ b/content/browser/fileapi/file_system_manager_impl.cc
@@ -123,11 +123,9 @@ FileSystemManagerImpl::FileSystemManagerImpl( int process_id, - int frame_id, storage::FileSystemContext* file_system_context, scoped_refptr<ChromeBlobStorageContext> blob_storage_context) : process_id_(process_id), - frame_id_(frame_id), context_(file_system_context), security_policy_(ChildProcessSecurityPolicyImpl::GetInstance()), blob_storage_context_(blob_storage_context), @@ -592,7 +590,8 @@ std::move(callback).Run(base::File::FILE_OK, std::move(writer)); } -void FileSystemManagerImpl::ChooseEntry(ChooseEntryCallback callback) { +void FileSystemManagerImpl::ChooseEntry(int32_t render_frame_id, + ChooseEntryCallback callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); if (!base::FeatureList::IsEnabled(blink::features::kWritableFilesAPI)) { bindings_.ReportBadMessage("FSMI_WRITABLE_FILES_DISABLED"); @@ -602,7 +601,7 @@ base::PostTaskWithTraits( FROM_HERE, {BrowserThread::UI}, base::BindOnce( - &FileSystemChooser::CreateAndShow, process_id_, frame_id_, + &FileSystemChooser::CreateAndShow, process_id_, render_frame_id, std::move(callback), base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO}))); }
diff --git a/content/browser/fileapi/file_system_manager_impl.h b/content/browser/fileapi/file_system_manager_impl.h index e92c5e46..f5e4cbf 100644 --- a/content/browser/fileapi/file_system_manager_impl.h +++ b/content/browser/fileapi/file_system_manager_impl.h
@@ -57,12 +57,9 @@ class CONTENT_EXPORT FileSystemManagerImpl : public blink::mojom::FileSystemManager { public: - // Constructed and held by the render frame host and render process host on - // the UI thread. Used by render frames (via the render frame host), workers - // and pepper (via the render process host). + // Used by the renderer process host on the UI thread. FileSystemManagerImpl( int process_id, - int frame_id, storage::FileSystemContext* file_system_context, scoped_refptr<ChromeBlobStorageContext> blob_storage_context); ~FileSystemManagerImpl() override; @@ -125,7 +122,8 @@ GetPlatformPathCallback callback) override; void CreateWriter(const GURL& file_path, CreateWriterCallback callback) override; - void ChooseEntry(ChooseEntryCallback callback) override; + void ChooseEntry(int32_t render_frame_id, + ChooseEntryCallback callback) override; private: class FileSystemCancellableOperationImpl; @@ -208,7 +206,6 @@ void OnConnectionErrorForOpListeners(OperationListenerID listener_id); const int process_id_; - const int frame_id_; storage::FileSystemContext* const context_; ChildProcessSecurityPolicyImpl* const security_policy_; const scoped_refptr<ChromeBlobStorageContext> blob_storage_context_;
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 93efefee..a187e2df 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -40,7 +40,6 @@ #include "content/browser/dom_storage/dom_storage_context_wrapper.h" #include "content/browser/download/mhtml_generation_manager.h" #include "content/browser/file_url_loader_factory.h" -#include "content/browser/fileapi/file_system_manager_impl.h" #include "content/browser/fileapi/file_system_url_loader_factory.h" #include "content/browser/frame_host/cross_process_frame_connector.h" #include "content/browser/frame_host/debug_urls.h" @@ -3595,15 +3594,6 @@ GetProcess()->GetID(), routing_id_), base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})); - file_system_manager_.reset(new FileSystemManagerImpl( - GetProcess()->GetID(), routing_id_, - GetProcess()->GetStoragePartition()->GetFileSystemContext(), - ChromeBlobStorageContext::GetFor(GetProcess()->GetBrowserContext()))); - registry_->AddInterface( - base::BindRepeating(&FileSystemManagerImpl::BindRequest, - base::Unretained(file_system_manager_.get())), - base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})); - if (Portal::IsEnabled()) { registry_->AddInterface(base::BindRepeating(IgnoreResult(&Portal::Create), base::Unretained(this)));
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index baf6df3..894ab5f2 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -1617,10 +1617,6 @@ // Hosts blink::mojom::PresentationService for the RenderFrame. std::unique_ptr<PresentationServiceImpl> presentation_service_; - // Hosts blink::mojom::FileSystemManager for the RenderFrame. - std::unique_ptr<FileSystemManagerImpl, BrowserThread::DeleteOnIOThread> - file_system_manager_; - #if !defined(OS_ANDROID) std::unique_ptr<AuthenticatorImpl> authenticator_impl_; #endif
diff --git a/content/browser/gpu/gpu_data_manager_impl.cc b/content/browser/gpu/gpu_data_manager_impl.cc index abe9475..976bfcd0 100644 --- a/content/browser/gpu/gpu_data_manager_impl.cc +++ b/content/browser/gpu/gpu_data_manager_impl.cc
@@ -109,9 +109,10 @@ private_->UpdateDxDiagNode(dx_diagnostics); } -void GpuDataManagerImpl::UpdateDX12VulkanInfo(const gpu::GPUInfo& gpu_info) { +void GpuDataManagerImpl::UpdateDx12VulkanInfo( + const gpu::Dx12VulkanVersionInfo& dx12_vulkan_version_info) { base::AutoLock auto_lock(lock_); - private_->UpdateDX12VulkanInfo(gpu_info); + private_->UpdateDx12VulkanInfo(dx12_vulkan_version_info); } #endif
diff --git a/content/browser/gpu/gpu_data_manager_impl.h b/content/browser/gpu/gpu_data_manager_impl.h index 1aa0fa3..2a18cf5 100644 --- a/content/browser/gpu/gpu_data_manager_impl.h +++ b/content/browser/gpu/gpu_data_manager_impl.h
@@ -78,7 +78,8 @@ const gpu::GPUInfo& gpu_info, const base::Optional<gpu::GPUInfo>& gpu_info_for_hardware_gpu); #if defined(OS_WIN) - void UpdateDX12VulkanInfo(const gpu::GPUInfo& gpu_info); + void UpdateDx12VulkanInfo( + const gpu::Dx12VulkanVersionInfo& dx12_vulkan_version_info); void UpdateDxDiagNode(const gpu::DxDiagNode& dx_diagnostics); #endif // Update the GPU feature info. This updates the blacklist and enabled status
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.cc b/content/browser/gpu/gpu_data_manager_impl_private.cc index 0876e96..67b5a059 100644 --- a/content/browser/gpu/gpu_data_manager_impl_private.cc +++ b/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -265,17 +265,19 @@ dx_diagnostics)); } -void UpdateDX12VulkanInfoOnIO(const gpu::GPUInfo& gpu_info) { +void UpdateDx12VulkanInfoOnIO( + const gpu::Dx12VulkanVersionInfo& dx12_vulkan_version_info) { // This function is called on the IO thread, but GPUInfo on GpuDataManagerImpl // should be updated on the UI thread since it can call into functions that // expect to run in the UI thread. base::PostTaskWithTraits( FROM_HERE, {BrowserThread::UI}, base::BindOnce( - [](const gpu::GPUInfo& gpu_info) { - GpuDataManagerImpl::GetInstance()->UpdateDX12VulkanInfo(gpu_info); + [](const gpu::Dx12VulkanVersionInfo& dx12_vulkan_version_info) { + GpuDataManagerImpl::GetInstance()->UpdateDx12VulkanInfo( + dx12_vulkan_version_info); }, - gpu_info)); + dx12_vulkan_version_info)); } #endif } // anonymous namespace @@ -417,7 +419,7 @@ if (!host) return; host->gpu_service()->GetGpuSupportedRuntimeVersion( - base::BindOnce(&UpdateDX12VulkanInfoOnIO)); + base::BindOnce(&UpdateDx12VulkanInfoOnIO)); }); base::PostDelayedTaskWithTraits(FROM_HERE, {BrowserThread::IO}, @@ -494,23 +496,18 @@ // If GPU process crashes and launches again, GPUInfo will be sent back from // the new GPU process again, and may overwrite the DX12, Vulkan, DxDiagNode // info we already collected. This is to make sure it doesn't happen. - uint32_t d3d12_feature_level = gpu_info_.d3d12_feature_level; - uint32_t vulkan_version = gpu_info_.vulkan_version; gpu::DxDiagNode dx_diagnostics = gpu_info_.dx_diagnostics; + gpu::Dx12VulkanVersionInfo dx12_vulkan_version_info = + gpu_info_.dx12_vulkan_version_info; #endif gpu_info_ = gpu_info; #if defined(OS_WIN) - if (d3d12_feature_level) { - gpu_info_.d3d12_feature_level = d3d12_feature_level; - gpu_info_.supports_dx12 = true; - } - if (vulkan_version) { - gpu_info_.vulkan_version = vulkan_version; - gpu_info_.supports_vulkan = true; - } if (!dx_diagnostics.IsEmpty()) { gpu_info_.dx_diagnostics = dx_diagnostics; } + if (!dx12_vulkan_version_info.IsEmpty()) { + gpu_info_.dx12_vulkan_version_info = dx12_vulkan_version_info; + } #endif // OS_WIN if (!gpu_info_for_hardware_gpu_.IsInitialized()) { @@ -536,16 +533,9 @@ NotifyGpuInfoUpdate(); } -void GpuDataManagerImplPrivate::UpdateDX12VulkanInfo( - const gpu::GPUInfo& gpu_info) { - if (gpu_info.d3d12_feature_level) { - gpu_info_.d3d12_feature_level = gpu_info.d3d12_feature_level; - gpu_info_.supports_dx12 = true; - } - if (gpu_info.vulkan_version) { - gpu_info_.vulkan_version = gpu_info.vulkan_version; - gpu_info_.supports_vulkan = true; - } +void GpuDataManagerImplPrivate::UpdateDx12VulkanInfo( + const gpu::Dx12VulkanVersionInfo& dx12_vulkan_version_info) { + gpu_info_.dx12_vulkan_version_info = dx12_vulkan_version_info; // No need to call GetContentClient()->SetGpuInfo(). NotifyGpuInfoUpdate(); }
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.h b/content/browser/gpu/gpu_data_manager_impl_private.h index 140c5f7..96346d5 100644 --- a/content/browser/gpu/gpu_data_manager_impl_private.h +++ b/content/browser/gpu/gpu_data_manager_impl_private.h
@@ -65,7 +65,8 @@ const base::Optional<gpu::GPUInfo>& optional_gpu_info_for_hardware_gpu); #if defined(OS_WIN) void UpdateDxDiagNode(const gpu::DxDiagNode& dx_diagnostics); - void UpdateDX12VulkanInfo(const gpu::GPUInfo& gpu_info); + void UpdateDx12VulkanInfo( + const gpu::Dx12VulkanVersionInfo& dx12_vulkan_version_info); #endif void UpdateGpuFeatureInfo(const gpu::GpuFeatureInfo& gpu_feature_info, const base::Optional<gpu::GpuFeatureInfo>&
diff --git a/content/browser/gpu/gpu_internals_ui.cc b/content/browser/gpu/gpu_internals_ui.cc index 0277986..abfcc0c3 100644 --- a/content/browser/gpu/gpu_internals_ui.cc +++ b/content/browser/gpu/gpu_internals_ui.cc
@@ -213,11 +213,12 @@ basic_info->Append(NewDescriptionValuePair( "Driver D3D12 feature level", - D3dFeaturelevelToString(gpu_info.d3d12_feature_level))); + D3dFeaturelevelToString( + gpu_info.dx12_vulkan_version_info.d3d12_feature_level))); - basic_info->Append( - NewDescriptionValuePair("Driver Vulkan API version", - VulkanVersionToString(gpu_info.vulkan_version))); + basic_info->Append(NewDescriptionValuePair( + "Driver Vulkan API version", + VulkanVersionToString(gpu_info.dx12_vulkan_version_info.vulkan_version))); #endif basic_info->Append(
diff --git a/content/browser/keyboard_lock/keyboard_lock_service_impl.cc b/content/browser/keyboard_lock/keyboard_lock_service_impl.cc index f783d535..b0aa160 100644 --- a/content/browser/keyboard_lock/keyboard_lock_service_impl.cc +++ b/content/browser/keyboard_lock/keyboard_lock_service_impl.cc
@@ -38,20 +38,22 @@ } // namespace KeyboardLockServiceImpl::KeyboardLockServiceImpl( - RenderFrameHost* render_frame_host) - : render_frame_host_(static_cast<RenderFrameHostImpl*>(render_frame_host)) { + RenderFrameHost* render_frame_host, + blink::mojom::KeyboardLockServiceRequest request) + : FrameServiceBase(render_frame_host, std::move(request)), + render_frame_host_(static_cast<RenderFrameHostImpl*>(render_frame_host)) { DCHECK(render_frame_host_); } -KeyboardLockServiceImpl::~KeyboardLockServiceImpl() = default; - // static void KeyboardLockServiceImpl::CreateMojoService( RenderFrameHost* render_frame_host, blink::mojom::KeyboardLockServiceRequest request) { - mojo::MakeStrongBinding( - std::make_unique<KeyboardLockServiceImpl>(render_frame_host), - std::move(request)); + DCHECK(render_frame_host); + + // The object is bound to the lifetime of |render_frame_host| and the mojo + // connection. See FrameServiceBase for details. + new KeyboardLockServiceImpl(render_frame_host, std::move(request)); } void KeyboardLockServiceImpl::RequestKeyboardLock( @@ -131,4 +133,6 @@ std::move(callback).Run(std::move(response)); } +KeyboardLockServiceImpl::~KeyboardLockServiceImpl() = default; + } // namespace content
diff --git a/content/browser/keyboard_lock/keyboard_lock_service_impl.h b/content/browser/keyboard_lock/keyboard_lock_service_impl.h index 19c2f99..eecefd2 100644 --- a/content/browser/keyboard_lock/keyboard_lock_service_impl.h +++ b/content/browser/keyboard_lock/keyboard_lock_service_impl.h
@@ -9,6 +9,7 @@ #include <vector> #include "content/common/content_export.h" +#include "content/public/browser/frame_service_base.h" #include "mojo/public/cpp/bindings/strong_binding.h" #include "third_party/blink/public/platform/modules/keyboard_lock/keyboard_lock.mojom.h" @@ -17,11 +18,11 @@ class RenderFrameHost; class RenderFrameHostImpl; -class CONTENT_EXPORT KeyboardLockServiceImpl - : public blink::mojom::KeyboardLockService { +class CONTENT_EXPORT KeyboardLockServiceImpl final + : public FrameServiceBase<blink::mojom::KeyboardLockService> { public: - explicit KeyboardLockServiceImpl(RenderFrameHost* render_frame_host); - ~KeyboardLockServiceImpl() override; + KeyboardLockServiceImpl(RenderFrameHost* render_frame_host, + blink::mojom::KeyboardLockServiceRequest request); static void CreateMojoService( RenderFrameHost* render_frame_host, @@ -34,6 +35,9 @@ void GetKeyboardLayoutMap(GetKeyboardLayoutMapCallback callback) override; private: + // |this| can only be destroyed by FrameServiceBase. + ~KeyboardLockServiceImpl() override; + RenderFrameHostImpl* const render_frame_host_; };
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 295511e..46b6d8c4 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -2045,16 +2045,6 @@ origin)); } -void RenderProcessHostImpl::BindFileSystemManager( - blink::mojom::FileSystemManagerRequest request) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - base::PostTaskWithTraits( - FROM_HERE, {BrowserThread::IO}, - base::BindOnce(&FileSystemManagerImpl::BindRequest, - base::Unretained(file_system_manager_impl_.get()), - std::move(request))); -} - void RenderProcessHostImpl::CancelProcessShutdownDelayForUnload() { if (IsKeepAliveRefCountDisabled()) return; @@ -2171,14 +2161,8 @@ base::Unretained(push_messaging_manager_.get()))); file_system_manager_impl_.reset(new FileSystemManagerImpl( - GetID(), MSG_ROUTING_NONE, - storage_partition_impl_->GetFileSystemContext(), + GetID(), storage_partition_impl_->GetFileSystemContext(), ChromeBlobStorageContext::GetFor(GetBrowserContext()))); - // This interface is still exposed by the RenderProcessHost's registry so - // that it can be accessed by PepperFileSystemHost. Blink accesses this - // interface through RenderFrameHost/RendererInterfaceBinders. - // TODO(https://crbug.com/873661): Make PepperFileSystemHost access this with - // the RenderFrameHost's registry, and remove this registration. registry->AddInterface( base::BindRepeating(&FileSystemManagerImpl::BindRequest, base::Unretained(file_system_manager_impl_.get())));
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h index 5778c10..f49cb41 100644 --- a/content/browser/renderer_host/render_process_host_impl.h +++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -59,7 +59,6 @@ #include "third_party/blink/public/common/associated_interfaces/associated_interface_registry.h" #include "third_party/blink/public/mojom/associated_interfaces/associated_interfaces.mojom.h" #include "third_party/blink/public/mojom/dom_storage/storage_partition_service.mojom.h" -#include "third_party/blink/public/mojom/filesystem/file_system.mojom.h" #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom.h" #include "ui/gfx/gpu_memory_buffer.h" #include "ui/gl/gpu_switching_observer.h" @@ -449,9 +448,6 @@ // before the process shuts down. void DelayProcessShutdownForUnload(const base::TimeDelta& timeout); - // Binds request to the FileSystemManager instance owned by the render process - // host, and is used by workers via RendererInterfaceBinders. - void BindFileSystemManager(blink::mojom::FileSystemManagerRequest request); FileSystemManagerImpl* GetFileSystemManagerForTesting() { return file_system_manager_impl_.get(); }
diff --git a/content/browser/renderer_interface_binders.cc b/content/browser/renderer_interface_binders.cc index f017a37..c3a8bdc 100644 --- a/content/browser/renderer_interface_binders.cc +++ b/content/browser/renderer_interface_binders.cc
@@ -149,13 +149,6 @@ static_cast<RenderProcessHostImpl*>(host)->BindCacheStorage( std::move(request), origin); })); - // TODO(https://crbug.com/873661): Pass origin to FileSystemMananger. - parameterized_binder_registry_.AddInterface(base::BindRepeating( - [](blink::mojom::FileSystemManagerRequest request, - RenderProcessHost* host, const url::Origin& origin) { - static_cast<RenderProcessHostImpl*>(host)->BindFileSystemManager( - std::move(request)); - })); parameterized_binder_registry_.AddInterface( base::Bind([](blink::mojom::PermissionServiceRequest request, RenderProcessHost* host, const url::Origin& origin) {
diff --git a/content/browser/web_package/signed_exchange_handler.cc b/content/browser/web_package/signed_exchange_handler.cc index 0d3150c..f927098 100644 --- a/content/browser/web_package/signed_exchange_handler.cc +++ b/content/browser/web_package/signed_exchange_handler.cc
@@ -524,7 +524,7 @@ base::UmaHistogramSparse(kHistogramCertVerificationResult, -error_code); UMA_HISTOGRAM_ENUMERATION(kHistogramCTVerificationResult, ct_result.policy_compliance, - net::ct::CTPolicyCompliance::CT_POLICY_MAX); + net::ct::CTPolicyCompliance::CT_POLICY_COUNT); if (error_code != net::OK) { SignedExchangeLoadResult result;
diff --git a/content/browser/web_package/signed_exchange_utils.cc b/content/browser/web_package/signed_exchange_utils.cc index b5b611c..ed020c6d 100644 --- a/content/browser/web_package/signed_exchange_utils.cc +++ b/content/browser/web_package/signed_exchange_utils.cc
@@ -5,9 +5,13 @@ #include "content/browser/web_package/signed_exchange_utils.h" #include "base/feature_list.h" +#include "base/metrics/field_trial_params.h" +#include "base/no_destructor.h" +#include "base/strings/string_piece.h" #include "base/strings/string_util.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" +#include "content/browser/web_package/origins_list.h" #include "content/browser/web_package/signed_exchange_devtools_proxy.h" #include "content/browser/web_package/signed_exchange_error.h" #include "content/browser/web_package/signed_exchange_request_handler.h" @@ -30,6 +34,31 @@ devtools_proxy->ReportError(error_message, std::move(error_field)); } +namespace { + +OriginsList CreateAdvertiseAcceptHeaderOriginsList() { + std::string param = base::GetFieldTrialParamValueByFeature( + features::kSignedHTTPExchangeAcceptHeader, + features::kSignedHTTPExchangeAcceptHeaderFieldTrialParamName); + if (param.empty()) + DLOG(ERROR) << "The Accept-SXG origins list param is empty."; + + return OriginsList(param); +} + +} // namespace + +bool ShouldAdvertiseAcceptHeader(const url::Origin& origin) { + if (!base::FeatureList::IsEnabled(features::kSignedHTTPExchangeAcceptHeader)) + return false; + + // |origins_list| is initialized in a thread-safe manner. + // Querying OriginsList::Match() should be safe since it's read-only access. + static base::NoDestructor<OriginsList> origins_list( + CreateAdvertiseAcceptHeaderOriginsList()); + return origins_list->Match(origin); +} + bool IsSignedExchangeHandlingEnabled() { return base::FeatureList::IsEnabled(features::kSignedHTTPExchange) || base::FeatureList::IsEnabled(features::kSignedHTTPExchangeOriginTrial);
diff --git a/content/browser/web_package/signed_exchange_utils.h b/content/browser/web_package/signed_exchange_utils.h index 359dc02..80c5171 100644 --- a/content/browser/web_package/signed_exchange_utils.h +++ b/content/browser/web_package/signed_exchange_utils.h
@@ -8,12 +8,17 @@ #include <string> #include "base/optional.h" +#include "content/browser/web_package/origins_list.h" #include "content/browser/web_package/signed_exchange_consts.h" #include "content/browser/web_package/signed_exchange_error.h" #include "content/common/content_export.h" class GURL; +namespace url { +class Origin; +} // namespace url + namespace network { struct ResourceResponseHead; } // namespace network @@ -33,6 +38,10 @@ base::Optional<SignedExchangeError::FieldIndexPair> error_field = base::nullopt); +// Returns true if Accept headers should be sent with +// "application/signed-exchange". +bool ShouldAdvertiseAcceptHeader(const url::Origin& origin); + // Returns true when SignedHTTPExchange feature or SignedHTTPExchangeOriginTrial // feature is enabled. bool IsSignedExchangeHandlingEnabled();
diff --git a/content/public/app/mojo/content_browser_manifest.json b/content/public/app/mojo/content_browser_manifest.json index 03d96205..cd88afca 100644 --- a/content/public/app/mojo/content_browser_manifest.json +++ b/content/public/app/mojo/content_browser_manifest.json
@@ -163,7 +163,6 @@ "blink.mojom.CredentialManager", "blink.mojom.DisplayCutoutHost", "blink.mojom.DedicatedWorkerFactory", - "blink.mojom.FileSystemManager", "blink.mojom.LockManager", "blink.mojom.GeolocationService", "blink.mojom.InsecureInputService", @@ -229,7 +228,6 @@ "renderer": [ "blink.mojom.CacheStorage", "blink.mojom.DedicatedWorkerFactory", - "blink.mojom.FileSystemManager", "blink.mojom.LockManager", "blink.mojom.NotificationService", "blink.mojom.PermissionService", @@ -266,7 +264,6 @@ "provides": { "renderer": [ "blink.mojom.CacheStorage", - "blink.mojom.FileSystemManager", "blink.mojom.LockManager", "blink.mojom.NotificationService", "blink.mojom.PermissionService",
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index cef428ca..81c67a33 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -413,6 +413,13 @@ const base::Feature kSignedHTTPExchange{"SignedHTTPExchange", base::FEATURE_DISABLED_BY_DEFAULT}; +// Send "Accept: application/signed-exchange" header to origins who opt-in. +const base::Feature kSignedHTTPExchangeAcceptHeader{ + "SignedHTTPExchangeAcceptHeader", base::FEATURE_DISABLED_BY_DEFAULT}; +// Field trial parameter containing the list of origins that opted-in to receive +// "Accept: application/signed-exchange" header. +const char kSignedHTTPExchangeAcceptHeaderFieldTrialParamName[] = "OriginsList"; + // Origin Trial of Origin-Signed HTTP Exchanges (for WebPackage Loading) const base::Feature kSignedHTTPExchangeOriginTrial{ "SignedHTTPExchangeOriginTrial", base::FEATURE_DISABLED_BY_DEFAULT}; @@ -599,7 +606,13 @@ // Controls whether the orientation sensor based device is enabled. const base::Feature kWebXrOrientationSensorDevice{ - "WebXROrientationSensorDevice", base::FEATURE_DISABLED_BY_DEFAULT}; + "WebXROrientationSensorDevice", +#if defined(OS_ANDROID) + base::FEATURE_ENABLED_BY_DEFAULT +#else + base::FEATURE_DISABLED_BY_DEFAULT +#endif +}; // Wipe corrupt v2 IndexedDB databases. const base::Feature kWipeCorruptV2IDBDatabases{
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index c9b84cc..96d8a25b 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -98,6 +98,9 @@ CONTENT_EXPORT extern const base::Feature kServiceWorkerScriptFullCodeCache; CONTENT_EXPORT extern const base::Feature kSharedArrayBuffer; CONTENT_EXPORT extern const base::Feature kSignedHTTPExchange; +CONTENT_EXPORT extern const base::Feature kSignedHTTPExchangeAcceptHeader; +CONTENT_EXPORT extern const char + kSignedHTTPExchangeAcceptHeaderFieldTrialParamName[]; CONTENT_EXPORT extern const base::Feature kSignedHTTPExchangeOriginTrial; CONTENT_EXPORT extern const base::Feature kSpareRendererForSitePerProcess; CONTENT_EXPORT extern const base::Feature kTimerThrottlingForHiddenFrames;
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 2a06cc4..7baa128 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -109,6 +109,10 @@ "fetchers/multi_resolution_image_resource_fetcher.h", "fetchers/resource_fetcher_impl.cc", "fetchers/resource_fetcher_impl.h", + "fileapi/file_system_dispatcher.cc", + "fileapi/file_system_dispatcher.h", + "fileapi/webfilesystem_impl.cc", + "fileapi/webfilesystem_impl.h", "frame_blame_context.cc", "frame_blame_context.h", "frame_owner_properties.cc",
diff --git a/content/renderer/child_frame_compositing_helper.cc b/content/renderer/child_frame_compositing_helper.cc index 8be3470..331e095 100644 --- a/content/renderer/child_frame_compositing_helper.cc +++ b/content/renderer/child_frame_compositing_helper.cc
@@ -39,7 +39,7 @@ scoped_refptr<cc::SolidColorLayer> crashed_layer = cc::SolidColorLayer::Create(); crashed_layer->SetMasksToBounds(true); - crashed_layer->SetBackgroundColor(SK_ColorBLACK); + crashed_layer->SetBackgroundColor(SK_ColorGRAY); if (child_frame_compositor_->GetLayer()) { SkBitmap* sad_bitmap = child_frame_compositor_->GetSadPageBitmap();
diff --git a/content/renderer/fileapi/OWNERS b/content/renderer/fileapi/OWNERS new file mode 100644 index 0000000..6269c8b3 --- /dev/null +++ b/content/renderer/fileapi/OWNERS
@@ -0,0 +1,4 @@ +file://content/browser/fileapi/OWNERS + +# TEAM: storage-dev@chromium.org +# COMPONENT: Blink>Storage>FileSystem
diff --git a/content/renderer/fileapi/file_system_dispatcher.cc b/content/renderer/fileapi/file_system_dispatcher.cc new file mode 100644 index 0000000..d8cd6a7 --- /dev/null +++ b/content/renderer/fileapi/file_system_dispatcher.cc
@@ -0,0 +1,79 @@ +// 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 "content/renderer/fileapi/file_system_dispatcher.h" + +#include <memory> +#include <utility> + +#include "base/callback.h" +#include "base/files/file_util.h" +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/no_destructor.h" +#include "base/process/process.h" +#include "components/services/filesystem/public/interfaces/types.mojom.h" +#include "content/child/child_thread_impl.h" +#include "content/public/common/service_names.mojom.h" +#include "content/public/renderer/worker_thread.h" +#include "services/service_manager/public/cpp/connector.h" +#include "storage/common/fileapi/file_system_info.h" +#include "storage/common/fileapi/file_system_type_converters.h" + +namespace content { + +FileSystemDispatcher::FileSystemDispatcher( + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner) + : main_thread_task_runner_(std::move(main_thread_task_runner)) {} + +FileSystemDispatcher::~FileSystemDispatcher() = default; + +blink::mojom::FileSystemManager& FileSystemDispatcher::GetFileSystemManager() { + auto BindInterfaceOnMainThread = + [](blink::mojom::FileSystemManagerRequest request) { + DCHECK(ChildThreadImpl::current()); + ChildThreadImpl::current()->GetConnector()->BindInterface( + mojom::kBrowserServiceName, std::move(request)); + }; + if (!file_system_manager_ptr_) { + if (WorkerThread::GetCurrentId()) { + blink::mojom::FileSystemManagerRequest request = + mojo::MakeRequest(&file_system_manager_ptr_); + main_thread_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(BindInterfaceOnMainThread, std::move(request))); + } else { + BindInterfaceOnMainThread(mojo::MakeRequest(&file_system_manager_ptr_)); + } + } + return *file_system_manager_ptr_; +} + +void FileSystemDispatcher::ChooseEntry( + int render_frame_id, + std::unique_ptr<ChooseEntryCallbacks> callbacks) { + GetFileSystemManager().ChooseEntry( + render_frame_id, + base::BindOnce( + [](std::unique_ptr<ChooseEntryCallbacks> callbacks, + base::File::Error result, + std::vector<blink::mojom::FileSystemEntryPtr> entries) { + if (result != base::File::FILE_OK) { + callbacks->OnError(result); + } else { + blink::WebVector<blink::WebFileSystem::FileSystemEntry> + web_entries(entries.size()); + for (size_t i = 0; i < entries.size(); ++i) { + web_entries[i].file_system_id = + blink::WebString::FromASCII(entries[i]->file_system_id); + web_entries[i].base_name = + blink::WebString::FromASCII(entries[i]->base_name); + } + callbacks->OnSuccess(std::move(web_entries)); + } + }, + std::move(callbacks))); +} + +} // namespace content
diff --git a/content/renderer/fileapi/file_system_dispatcher.h b/content/renderer/fileapi/file_system_dispatcher.h new file mode 100644 index 0000000..b5df614 --- /dev/null +++ b/content/renderer/fileapi/file_system_dispatcher.h
@@ -0,0 +1,44 @@ +// 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. + +#ifndef CONTENT_RENDERER_FILEAPI_FILE_SYSTEM_DISPATCHER_H_ +#define CONTENT_RENDERER_FILEAPI_FILE_SYSTEM_DISPATCHER_H_ + +#include "base/memory/scoped_refptr.h" +#include "third_party/blink/public/mojom/filesystem/file_system.mojom.h" +#include "third_party/blink/public/platform/web_file_system.h" + +namespace base { +class SingleThreadTaskRunner; +} // namespace base + +namespace content { + +// Dispatches and sends file system related messages sent to/from a child +// process from/to the main browser process. There is an instance held by +// each WebFileSystemImpl object. +// TODO(adithyas): Move functionality to blink::FileSystemDispatcher and +// remove this class. +class FileSystemDispatcher { + public: + explicit FileSystemDispatcher( + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner); + ~FileSystemDispatcher(); + + using ChooseEntryCallbacks = blink::WebFileSystem::ChooseEntryCallbacks; + void ChooseEntry(int render_frame_id, + std::unique_ptr<ChooseEntryCallbacks> callbacks); + + private: + blink::mojom::FileSystemManager& GetFileSystemManager(); + + blink::mojom::FileSystemManagerPtr file_system_manager_ptr_; + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; + + DISALLOW_COPY_AND_ASSIGN(FileSystemDispatcher); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_FILEAPI_FILE_SYSTEM_DISPATCHER_H_
diff --git a/content/renderer/fileapi/webfilesystem_impl.cc b/content/renderer/fileapi/webfilesystem_impl.cc new file mode 100644 index 0000000..b471ad4 --- /dev/null +++ b/content/renderer/fileapi/webfilesystem_impl.cc
@@ -0,0 +1,72 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/fileapi/webfilesystem_impl.h" + +#include "base/lazy_instance.h" +#include "base/threading/thread_local.h" +#include "base/threading/thread_task_runner_handle.h" +#include "content/public/renderer/render_frame.h" +#include "content/renderer/fileapi/file_system_dispatcher.h" +#include "content/renderer/render_thread_impl.h" +#include "third_party/blink/public/web/web_frame.h" + +namespace content { + +namespace { + +base::LazyInstance<base::ThreadLocalPointer<WebFileSystemImpl>>::Leaky + g_webfilesystem_tls = LAZY_INSTANCE_INITIALIZER; + +enum CallbacksUnregisterMode { + UNREGISTER_CALLBACKS, + DO_NOT_UNREGISTER_CALLBACKS, +}; + +} // namespace + +//----------------------------------------------------------------------------- +// WebFileSystemImpl + +WebFileSystemImpl* WebFileSystemImpl::ThreadSpecificInstance( + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner) { + if (g_webfilesystem_tls.Pointer()->Get() || !main_thread_task_runner) + return g_webfilesystem_tls.Pointer()->Get(); + WebFileSystemImpl* filesystem = + new WebFileSystemImpl(std::move(main_thread_task_runner)); + if (WorkerThread::GetCurrentId()) + WorkerThread::AddObserver(filesystem); + return filesystem; +} + +void WebFileSystemImpl::DeleteThreadSpecificInstance() { + DCHECK(!WorkerThread::GetCurrentId()); + if (g_webfilesystem_tls.Pointer()->Get()) + delete g_webfilesystem_tls.Pointer()->Get(); +} + +WebFileSystemImpl::WebFileSystemImpl( + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner) + : main_thread_task_runner_(main_thread_task_runner), + file_system_dispatcher_(std::move(main_thread_task_runner)) { + g_webfilesystem_tls.Pointer()->Set(this); +} + +WebFileSystemImpl::~WebFileSystemImpl() { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + g_webfilesystem_tls.Pointer()->Set(nullptr); +} + +void WebFileSystemImpl::WillStopCurrentWorkerThread() { + delete this; +} + +void WebFileSystemImpl::ChooseEntry( + blink::WebFrame* frame, + std::unique_ptr<ChooseEntryCallbacks> callbacks) { + file_system_dispatcher_.ChooseEntry( + RenderFrame::GetRoutingIdForWebFrame(frame), std::move(callbacks)); +} + +} // namespace content
diff --git a/content/renderer/fileapi/webfilesystem_impl.h b/content/renderer/fileapi/webfilesystem_impl.h new file mode 100644 index 0000000..a3c2ecf86 --- /dev/null +++ b/content/renderer/fileapi/webfilesystem_impl.h
@@ -0,0 +1,58 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_FILEAPI_WEBFILESYSTEM_IMPL_H_ +#define CONTENT_RENDERER_FILEAPI_WEBFILESYSTEM_IMPL_H_ + +#include "base/memory/ref_counted.h" +#include "base/threading/thread_checker.h" +#include "content/public/renderer/worker_thread.h" +#include "content/renderer/fileapi/file_system_dispatcher.h" +#include "third_party/blink/public/platform/web_file_system.h" + +namespace base { +class SingleThreadTaskRunner; +} + +namespace content { + +// TODO(adithyas): Move functionality to blink::FileSystemDispatcher and remove +// this class. +class WebFileSystemImpl : public blink::WebFileSystem, + public WorkerThread::Observer { + public: + // Returns thread-specific instance. If non-null |main_thread_loop| + // is given and no thread-specific instance has been created it may + // create a new instance. + static WebFileSystemImpl* ThreadSpecificInstance( + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner); + + // Deletes thread-specific instance (if exists). For workers it deletes + // itself in WillStopCurrentWorkerThread(), but for an instance created on the + // main thread this method must be called. + static void DeleteThreadSpecificInstance(); + + explicit WebFileSystemImpl( + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner); + ~WebFileSystemImpl() override; + + // WorkerThread::Observer implementation. + void WillStopCurrentWorkerThread() override; + + void ChooseEntry(blink::WebFrame* frame, + std::unique_ptr<ChooseEntryCallbacks>) override; + + private: + scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_; + FileSystemDispatcher file_system_dispatcher_; + + // Thread-affine per use of TLS in impl. + THREAD_CHECKER(thread_checker_); + + DISALLOW_COPY_AND_ASSIGN(WebFileSystemImpl); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_FILEAPI_WEBFILESYSTEM_IMPL_H_
diff --git a/content/renderer/pepper/pepper_file_system_host.cc b/content/renderer/pepper/pepper_file_system_host.cc index 2622490..53915df 100644 --- a/content/renderer/pepper/pepper_file_system_host.cc +++ b/content/renderer/pepper/pepper_file_system_host.cc
@@ -10,6 +10,7 @@ #include "content/public/common/service_names.mojom.h" #include "content/public/renderer/render_view.h" #include "content/public/renderer/renderer_ppapi_host.h" +#include "content/renderer/fileapi/file_system_dispatcher.h" #include "content/renderer/pepper/pepper_plugin_instance_impl.h" #include "content/renderer/render_thread_impl.h" #include "ppapi/c/pp_errors.h"
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index 381b4a9..8b92412 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc
@@ -1000,11 +1000,9 @@ scoped_refptr<network::SharedURLLoaderFactory> loader_factory = frame_->GetLoaderFactoryBundle(); if (request.GetRequestContext() == WebURLRequest::kRequestContextPrefetch && - frame_->prefetch_loader_factory_) { + frame_->prefetch_shared_loader_factory_) { // The frame should be alive when this factory is used. - loader_factory = - base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( - frame_->prefetch_loader_factory_.get()); + loader_factory = frame_->prefetch_shared_loader_factory_; } return std::make_unique<WebURLLoaderImpl>( RenderThreadImpl::current()->resource_dispatcher(), @@ -1699,6 +1697,9 @@ } RenderFrameImpl::~RenderFrameImpl() { + if (prefetch_shared_loader_factory_) + prefetch_shared_loader_factory_->Detach(); + // If file chooser is still waiting for answer, dispatch empty answer. if (file_chooser_completion_) { file_chooser_completion_->DidChooseFile(WebVector<WebString>()); @@ -3234,7 +3235,14 @@ return; } + if (prefetch_shared_loader_factory_) + prefetch_shared_loader_factory_->Detach(); prefetch_loader_factory_ = std::move(prefetch_loader_factory); + if (prefetch_loader_factory_) { + prefetch_shared_loader_factory_ = + base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( + prefetch_loader_factory_.get()); + } // If the request was initiated in the context of a user gesture then make // sure that the navigation also executes in the context of a user gesture.
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index 67a3f40d..d0eccf4 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -145,6 +145,7 @@ } namespace network { +class WeakWrapperSharedURLLoaderFactory; struct ResourceResponseHead; } @@ -1620,6 +1621,8 @@ // Set on CommitNavigation when Network Service is enabled, and used // by FrameURLLoaderFactory for prefetch requests. network::mojom::URLLoaderFactoryPtr prefetch_loader_factory_; + scoped_refptr<network::WeakWrapperSharedURLLoaderFactory> + prefetch_shared_loader_factory_; // URLLoaderFactory instances used for subresource loading. // Depending on how the frame was created, |loader_factories_| could be:
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 8f1d4b61..db1cf76 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -88,6 +88,8 @@ #include "content/renderer/dom_storage/webstoragearea_impl.h" #include "content/renderer/dom_storage/webstoragenamespace_impl.h" #include "content/renderer/effective_connection_type_helper.h" +#include "content/renderer/fileapi/file_system_dispatcher.h" +#include "content/renderer/fileapi/webfilesystem_impl.h" #include "content/renderer/gpu/frame_swap_message_queue.h" #include "content/renderer/indexed_db/indexed_db_dispatcher.h" #include "content/renderer/input/widget_input_handler_manager.h" @@ -1009,6 +1011,7 @@ void RenderThreadImpl::Shutdown() { ChildThreadImpl::Shutdown(); + WebFileSystemImpl::DeleteThreadSpecificInstance(); // In a multi-process mode, we immediately exit the renderer. // Historically we had a graceful shutdown sequence here but it was // 1) a waste of performance and 2) a source of lots of complicated
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index 5584066..4c03b63 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -46,6 +46,7 @@ #include "content/renderer/dom_storage/local_storage_namespace.h" #include "content/renderer/dom_storage/session_web_storage_namespace_impl.h" #include "content/renderer/dom_storage/webstoragenamespace_impl.h" +#include "content/renderer/fileapi/webfilesystem_impl.h" #include "content/renderer/image_capture/image_capture_frame_grabber.h" #include "content/renderer/indexed_db/webidbfactory_impl.h" #include "content/renderer/loader/child_url_loader_factory_bundle.h" @@ -142,6 +143,7 @@ using blink::WebBlobRegistry; using blink::WebCanvasCaptureHandler; using blink::WebDatabaseObserver; +using blink::WebFileSystem; using blink::WebIDBFactory; using blink::WebImageCaptureFrameGrabber; using blink::WebMediaPlayer; @@ -296,6 +298,7 @@ } RendererBlinkPlatformImpl::~RendererBlinkPlatformImpl() { + WebFileSystemImpl::DeleteThreadSpecificInstance(); main_thread_scheduler_->SetTopLevelBlameContext(nullptr); } @@ -571,6 +574,10 @@ //------------------------------------------------------------------------------ +WebFileSystem* RendererBlinkPlatformImpl::FileSystem() { + return WebFileSystemImpl::ThreadSpecificInstance(default_task_runner_.get()); +} + WebString RendererBlinkPlatformImpl::FileSystemCreateOriginIdentifier( const blink::WebSecurityOrigin& origin) { return WebString::FromUTF8(
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h index 5660036..5b62c65 100644 --- a/content/renderer/renderer_blink_platform_impl.h +++ b/content/renderer/renderer_blink_platform_impl.h
@@ -125,6 +125,7 @@ bool IsLockedToSite() const override; std::unique_ptr<blink::WebIDBFactory> CreateIdbFactory() override; + blink::WebFileSystem* FileSystem() override; blink::WebString FileSystemCreateOriginIdentifier( const blink::WebSecurityOrigin& origin) override;
diff --git a/device/gamepad/dualshock4_controller_base.cc b/device/gamepad/dualshock4_controller_base.cc index a385813..9edfad9 100644 --- a/device/gamepad/dualshock4_controller_base.cc +++ b/device/gamepad/dualshock4_controller_base.cc
@@ -5,9 +5,9 @@ #include "device/gamepad/dualshock4_controller_base.h" namespace { -const uint32_t kVendorSony = 0x054c; -const uint32_t kProductDualshock4 = 0x05c4; -const uint32_t kProductDualshock4Slim = 0x9cc; +const uint16_t kVendorSony = 0x054c; +const uint16_t kProductDualshock4 = 0x05c4; +const uint16_t kProductDualshock4Slim = 0x9cc; const uint8_t kRumbleMagnitudeMax = 0xff; enum ControllerType { @@ -16,7 +16,8 @@ DUALSHOCK4_SLIM_CONTROLLER }; -ControllerType ControllerTypeFromDeviceIds(int vendor_id, int product_id) { +ControllerType ControllerTypeFromDeviceIds(uint16_t vendor_id, + uint16_t product_id) { if (vendor_id == kVendorSony) { switch (product_id) { case kProductDualshock4: @@ -37,7 +38,8 @@ Dualshock4ControllerBase::~Dualshock4ControllerBase() = default; // static -bool Dualshock4ControllerBase::IsDualshock4(int vendor_id, int product_id) { +bool Dualshock4ControllerBase::IsDualshock4(uint16_t vendor_id, + uint16_t product_id) { return ControllerTypeFromDeviceIds(vendor_id, product_id) != UNKNOWN_CONTROLLER; }
diff --git a/device/gamepad/dualshock4_controller_base.h b/device/gamepad/dualshock4_controller_base.h index f8b4e0e..229989b 100644 --- a/device/gamepad/dualshock4_controller_base.h +++ b/device/gamepad/dualshock4_controller_base.h
@@ -14,7 +14,7 @@ Dualshock4ControllerBase() = default; ~Dualshock4ControllerBase() override; - static bool IsDualshock4(int vendor_id, int product_id); + static bool IsDualshock4(uint16_t vendor_id, uint16_t product_id); void SetVibration(double strong_magnitude, double weak_magnitude) override;
diff --git a/device/gamepad/gamepad_device_linux.cc b/device/gamepad/gamepad_device_linux.cc index 8392313..84dc0ac 100644 --- a/device/gamepad/gamepad_device_linux.cc +++ b/device/gamepad/gamepad_device_linux.cc
@@ -164,6 +164,16 @@ return nbytes == sizeof(start_stop); } +uint16_t HexStringToUInt16WithDefault(base::StringPiece input, + uint16_t default_value) { + uint32_t out = 0; + if (!base::HexStringToUInt(input, &out) || + out > std::numeric_limits<uint16_t>::max()) { + return default_value; + } + return static_cast<uint16_t>(out); +} + } // namespace GamepadDeviceLinux::GamepadDeviceLinux(const std::string& syspath_prefix) @@ -338,9 +348,8 @@ } GamepadStandardMappingFunction GamepadDeviceLinux::GetMappingFunction() const { - return GetGamepadStandardMappingFunction(vendor_id_.c_str(), - product_id_.c_str(), - version_number_.c_str(), bus_type_); + return GetGamepadStandardMappingFunction(vendor_id_, product_id_, + version_number_, bus_type_); } bool GamepadDeviceLinux::IsSameDevice(const UdevGamepadLinux& pad_info) { @@ -370,10 +379,9 @@ const char* name = udev_device_get_sysattr_value(parent_device, "name"); std::string name_string(name ? name : ""); - int vendor_id_int = 0; - int product_id_int = 0; - base::HexStringToInt(vendor_id, &vendor_id_int); - base::HexStringToInt(product_id, &product_id_int); + uint16_t vendor_id_int = HexStringToUInt16WithDefault(vendor_id, 0); + uint16_t product_id_int = HexStringToUInt16WithDefault(product_id, 0); + uint16_t version_number_int = HexStringToUInt16WithDefault(version_number, 0); // In many cases the information the input subsystem contains isn't // as good as the information that the device bus has, walk up further @@ -402,9 +410,9 @@ } joydev_index_ = pad_info.index; - vendor_id_ = vendor_id ? vendor_id : ""; - product_id_ = product_id ? product_id : ""; - version_number_ = version_number ? version_number : ""; + vendor_id_ = vendor_id_int; + product_id_ = product_id_int; + version_number_ = version_number_int; name_ = name_string; return true; @@ -416,9 +424,9 @@ joydev_fd_ = -1; } joydev_index_ = -1; - vendor_id_.clear(); - product_id_.clear(); - version_number_.clear(); + vendor_id_ = 0; + product_id_ = 0; + version_number_ = 0; name_.clear(); // Button indices must be recomputed once the joydev node is closed.
diff --git a/device/gamepad/gamepad_device_linux.h b/device/gamepad/gamepad_device_linux.h index f34df9ef..2f926e6 100644 --- a/device/gamepad/gamepad_device_linux.h +++ b/device/gamepad/gamepad_device_linux.h
@@ -41,9 +41,9 @@ bool IsEmpty() const; int GetJoydevIndex() const { return joydev_index_; } - std::string GetVendorId() const { return vendor_id_; } - std::string GetProductId() const { return product_id_; } - std::string GetVersionNumber() const { return version_number_; } + uint16_t GetVendorId() const { return vendor_id_; } + uint16_t GetProductId() const { return product_id_; } + uint16_t GetVersionNumber() const { return version_number_; } std::string GetName() const { return name_; } std::string GetSyspathPrefix() const { return syspath_prefix_; } GamepadBusType GetBusType() const { return bus_type_; } @@ -119,13 +119,13 @@ std::vector<bool> button_indices_used_; // The vendor ID of the device. - std::string vendor_id_; + uint16_t vendor_id_; // The product ID of the device. - std::string product_id_; + uint16_t product_id_; // The version number of the device. - std::string version_number_; + uint16_t version_number_; // A string identifying the manufacturer and model of the device. std::string name_;
diff --git a/device/gamepad/gamepad_platform_data_fetcher_linux.cc b/device/gamepad/gamepad_platform_data_fetcher_linux.cc index f3ad3a00..8931817 100644 --- a/device/gamepad/gamepad_platform_data_fetcher_linux.cc +++ b/device/gamepad/gamepad_platform_data_fetcher_linux.cc
@@ -63,16 +63,15 @@ // static void GamepadPlatformDataFetcherLinux::UpdateGamepadStrings( const std::string& name, - const std::string& vendor_id, - const std::string& product_id, + uint16_t vendor_id, + uint16_t product_id, bool has_standard_mapping, Gamepad* pad) { // Set the ID string. The ID contains the device name, vendor and product IDs, // and an indication of whether the standard mapping is in use. - std::string id = - base::StringPrintf("%s (%sVendor: %s Product: %s)", name.c_str(), - has_standard_mapping ? "STANDARD GAMEPAD " : "", - vendor_id.c_str(), product_id.c_str()); + std::string id = base::StringPrintf( + "%s (%sVendor: %04x Product: %04x)", name.c_str(), + has_standard_mapping ? "STANDARD GAMEPAD " : "", vendor_id, product_id); base::TruncateUTF8ToByteSize(id, Gamepad::kIdLengthCap - 1, &id); base::string16 tmp16 = base::UTF8ToUTF16(id); memset(pad->id, 0, sizeof(pad->id));
diff --git a/device/gamepad/gamepad_platform_data_fetcher_linux.h b/device/gamepad/gamepad_platform_data_fetcher_linux.h index 94afd00..db09233 100644 --- a/device/gamepad/gamepad_platform_data_fetcher_linux.h +++ b/device/gamepad/gamepad_platform_data_fetcher_linux.h
@@ -54,8 +54,8 @@ private: // Updates the ID and mapper strings in |pad| with new device info. static void UpdateGamepadStrings(const std::string& name, - const std::string& vendor_id, - const std::string& product_id, + uint16_t vendor_id, + uint16_t product_id, bool has_standard_mapping, Gamepad* pad);
diff --git a/device/gamepad/gamepad_platform_data_fetcher_mac.mm b/device/gamepad/gamepad_platform_data_fetcher_mac.mm index 5529998..5776b51 100644 --- a/device/gamepad/gamepad_platform_data_fetcher_mac.mm +++ b/device/gamepad/gamepad_platform_data_fetcher_mac.mm
@@ -19,13 +19,13 @@ namespace { // http://www.usb.org/developers/hidpage -const uint32_t kGenericDesktopUsagePage = 0x01; -const uint32_t kJoystickUsageNumber = 0x04; -const uint32_t kGameUsageNumber = 0x05; -const uint32_t kMultiAxisUsageNumber = 0x08; +const uint16_t kGenericDesktopUsagePage = 0x01; +const uint16_t kJoystickUsageNumber = 0x04; +const uint16_t kGameUsageNumber = 0x05; +const uint16_t kMultiAxisUsageNumber = 0x08; -const int kVendorSteelSeries = 0x1038; -const int kProductNimbus = 0x1420; +const uint16_t kVendorSteelSeries = 0x1038; +const uint16_t kProductNimbus = 0x1420; void CopyNSStringAsUTF16LittleEndian(NSString* src, UChar* dest, @@ -192,9 +192,9 @@ IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVersionNumberKey)))); NSString* product = CFToNSCast(CFCastStrict<CFStringRef>( IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)))); - int vendor_int = [vendor_id intValue]; - int product_int = [product_id intValue]; - int version_int = [version_number intValue]; + uint16_t vendor_int = [vendor_id intValue]; + uint16_t product_int = [product_id intValue]; + uint16_t version_int = [version_number intValue]; // The SteelSeries Nimbus and other Made for iOS gamepads should be handled // through the GameController interface. Blacklist it here so it doesn't @@ -206,12 +206,8 @@ if (!state) return; // No available slot for this device - char vendor_as_str[5], product_as_str[5], version_as_str[5]; - snprintf(vendor_as_str, sizeof(vendor_as_str), "%04x", vendor_int); - snprintf(product_as_str, sizeof(product_as_str), "%04x", product_int); - snprintf(version_as_str, sizeof(version_as_str), "%04x", version_int); state->mapper = GetGamepadStandardMappingFunction( - vendor_as_str, product_as_str, version_as_str, GAMEPAD_BUS_UNKNOWN); + vendor_int, product_int, version_int, GAMEPAD_BUS_UNKNOWN); NSString* ident = [NSString stringWithFormat:@"%@ (%sVendor: %04x Product: %04x)", product,
diff --git a/device/gamepad/gamepad_standard_mappings.h b/device/gamepad/gamepad_standard_mappings.h index 17aec2b..a85956c 100644 --- a/device/gamepad/gamepad_standard_mappings.h +++ b/device/gamepad/gamepad_standard_mappings.h
@@ -24,9 +24,9 @@ Gamepad* mapped); GamepadStandardMappingFunction GetGamepadStandardMappingFunction( - const base::StringPiece& vendor_id, - const base::StringPiece& product_id, - const base::StringPiece& version_number, + const uint16_t vendor_id, + const uint16_t product_id, + const uint16_t version_number, GamepadBusType bus_type); // This defines our canonical mapping order for gamepad-like devices. If these
diff --git a/device/gamepad/gamepad_standard_mappings_linux.cc b/device/gamepad/gamepad_standard_mappings_linux.cc index 552f790..d43c149 100644 --- a/device/gamepad/gamepad_standard_mappings_linux.cc +++ b/device/gamepad/gamepad_standard_mappings_linux.cc
@@ -5,6 +5,7 @@ #include <stddef.h> #include "base/macros.h" +#include "base/stl_util.h" #include "device/gamepad/gamepad_standard_mappings.h" namespace device { @@ -20,10 +21,20 @@ // axes are capable of, and as a result the received axis values only use about // 70% of the total range. We renormalize the axis values to cover the full // range. The axis extents were determined experimentally. -const static float kSwitchProAxisXMin = -0.7f; -const static float kSwitchProAxisXMax = 0.7f; -const static float kSwitchProAxisYMin = -0.65f; -const static float kSwitchProAxisYMax = 0.75f; +const float kSwitchProAxisXMin = -0.7f; +const float kSwitchProAxisXMax = 0.7f; +const float kSwitchProAxisYMin = -0.65f; +const float kSwitchProAxisYMax = 0.75f; + +// The hid-sony driver in newer kernels uses an alternate mapping for Sony +// Playstation 3 and Playstation 4 gamepads than in older kernels. To allow +// applications to distinguish between the old mapping and the new mapping, +// hid-sony sets the high bit of the device's version number. +// Dualshock 4 devices are patched in 4.10: +// https://github.com/torvalds/linux/commit/9131f8cc2b4eaf7c08d402243429e0bfba9aa0d6 +// Dualshock 3 and SIXAXIS devices are patched in 4.12: +// https://github.com/torvalds/linux/commit/e19a267b9987135c00155a51e683e434b9abb56b +const uint16_t kDualshockPatchedVersion = 0x8111; void MapperXInputStyleGamepad(const Gamepad& input, Gamepad* mapped) { *mapped = input; @@ -535,61 +546,62 @@ } struct MappingData { - const char* const vendor_id; - const char* const product_id; + const uint16_t vendor_id; + const uint16_t product_id; GamepadStandardMappingFunction function; } AvailableMappings[] = { // http://www.linux-usb.org/usb.ids - {"0079", "0006", MapperDragonRiseGeneric}, // DragonRise Generic USB - {"045e", "028e", MapperXInputStyleGamepad}, // Xbox 360 Wired - {"045e", "028f", MapperXInputStyleGamepad}, // Xbox 360 Wireless - {"045e", "02a1", MapperXInputStyleGamepad}, // Xbox 360 Wireless - {"045e", "0291", MapperXInputStyleGamepad}, // Xbox 360 Wireless - {"045e", "02d1", MapperXInputStyleGamepad}, // Xbox One Wired - {"045e", "02dd", MapperXInputStyleGamepad}, // Xbox One Wired (2015 FW) - {"045e", "02e0", MapperXboxOneS}, // Xbox One S (Bluetooth) - {"045e", "02e3", MapperXInputStyleGamepad}, // Xbox One Elite Wired - {"045e", "02ea", MapperXInputStyleGamepad}, // Xbox One S (USB) - {"045e", "02fd", MapperXboxOneS2016Firmware}, // Xbox One S (Bluetooth) - {"045e", "0719", MapperXInputStyleGamepad}, // Xbox 360 Wireless - {"046d", "c216", MapperLogitechDInput}, // Logitech F310 D-mode - {"046d", "c218", MapperLogitechDInput}, // Logitech F510 D-mode - {"046d", "c219", MapperLogitechDInput}, // Logitech F710 D-mode - {"046d", "c21d", MapperXInputStyleGamepad}, // Logitech F310 X-mode - {"046d", "c21e", MapperXInputStyleGamepad}, // Logitech F510 X-mode - {"046d", "c21f", MapperXInputStyleGamepad}, // Logitech F710 X-mode - {"04e8", "a000", MapperSamsung_EI_GP20}, // Samsung Gamepad EI-GP20 - {"054c", "0268", MapperDualshock3SixAxis}, // Dualshock 3 / SIXAXIS - {"054c", "05c4", MapperDualshock4}, // Playstation Dualshock 4 - {"054c", "09cc", MapperDualshock4}, // Dualshock 4 (PS4 Slim) - {"054c", "0ba0", MapperDualshock4}, // Dualshock 4 USB receiver - {"057e", "2009", MapperSwitchProUsb}, // Switch Pro Controller - {"0583", "2060", MapperIBuffalo}, // iBuffalo Classic - {"0925", "0005", MapperLakeviewResearch}, // SmartJoy PLUS Adapter - {"0925", "8866", MapperLakeviewResearch}, // WiseGroup MP-8866 - {"0955", "7210", MapperNvShield}, // Nvidia Shield gamepad (2015) - {"0955", "7214", MapperNvShield2017}, // Nvidia Shield gamepad (2017) - {"0b05", "4500", MapperADT1}, // Nexus Player Controller - {"0e8f", "0003", MapperXGEAR}, // XFXforce XGEAR PS2 Controller - {"1038", "1412", MapperSteelSeries}, // Zeemote: SteelSeries FREE - {"1532", "0900", MapperRazerServal}, // Razer Serval Controller - {"18d1", "2c40", MapperADT1}, // ADT-1 Controller - {"20d6", "6271", MapperMoga}, // Moga Pro Controller (HID mode) - {"20d6", "89e5", MapperMoga}, // Moga 2 HID - {"2378", "1008", MapperOnLiveWireless}, // OnLive Controller (Bluetooth) - {"2378", "100a", MapperOnLiveWireless}, // OnLive Controller (Wired) - {"2836", "0001", MapperOUYA}, // OUYA Controller + {0x0079, 0x0006, MapperDragonRiseGeneric}, // DragonRise Generic USB + {0x045e, 0x028e, MapperXInputStyleGamepad}, // Xbox 360 Wired + {0x045e, 0x028f, MapperXInputStyleGamepad}, // Xbox 360 Wireless + {0x045e, 0x02a1, MapperXInputStyleGamepad}, // Xbox 360 Wireless + {0x045e, 0x0291, MapperXInputStyleGamepad}, // Xbox 360 Wireless + {0x045e, 0x02d1, MapperXInputStyleGamepad}, // Xbox One Wired + {0x045e, 0x02dd, MapperXInputStyleGamepad}, // Xbox One Wired (2015 FW) + {0x045e, 0x02e0, MapperXboxOneS}, // Xbox One S (Bluetooth) + {0x045e, 0x02e3, MapperXInputStyleGamepad}, // Xbox One Elite Wired + {0x045e, 0x02ea, MapperXInputStyleGamepad}, // Xbox One S (USB) + {0x045e, 0x02fd, MapperXboxOneS2016Firmware}, // Xbox One S (Bluetooth) + {0x045e, 0x0719, MapperXInputStyleGamepad}, // Xbox 360 Wireless + {0x046d, 0xc216, MapperLogitechDInput}, // Logitech F310 D-mode + {0x046d, 0xc218, MapperLogitechDInput}, // Logitech F510 D-mode + {0x046d, 0xc219, MapperLogitechDInput}, // Logitech F710 D-mode + {0x046d, 0xc21d, MapperXInputStyleGamepad}, // Logitech F310 X-mode + {0x046d, 0xc21e, MapperXInputStyleGamepad}, // Logitech F510 X-mode + {0x046d, 0xc21f, MapperXInputStyleGamepad}, // Logitech F710 X-mode + {0x04e8, 0xa000, MapperSamsung_EI_GP20}, // Samsung Gamepad EI-GP20 + {0x054c, 0x0268, MapperDualshock3SixAxis}, // Dualshock 3 / SIXAXIS + {0x054c, 0x05c4, MapperDualshock4}, // Playstation Dualshock 4 + {0x054c, 0x09cc, MapperDualshock4}, // Dualshock 4 (PS4 Slim) + {0x054c, 0x0ba0, MapperDualshock4}, // Dualshock 4 USB receiver + {0x057e, 0x2009, MapperSwitchProUsb}, // Switch Pro Controller + {0x0583, 0x2060, MapperIBuffalo}, // iBuffalo Classic + {0x0925, 0x0005, MapperLakeviewResearch}, // SmartJoy PLUS Adapter + {0x0925, 0x8866, MapperLakeviewResearch}, // WiseGroup MP-8866 + {0x0955, 0x7210, MapperNvShield}, // Nvidia Shield gamepad (2015) + {0x0955, 0x7214, MapperNvShield2017}, // Nvidia Shield gamepad (2017) + {0x0b05, 0x4500, MapperADT1}, // Nexus Player Controller + {0x0e8f, 0x0003, MapperXGEAR}, // XFXforce XGEAR PS2 Controller + {0x1038, 0x1412, MapperSteelSeries}, // Zeemote: SteelSeries FREE + {0x1532, 0x0900, MapperRazerServal}, // Razer Serval Controller + {0x18d1, 0x2c40, MapperADT1}, // ADT-1 Controller + {0x20d6, 0x6271, MapperMoga}, // Moga Pro Controller (HID mode) + {0x20d6, 0x89e5, MapperMoga}, // Moga 2 HID + {0x2378, 0x1008, MapperOnLiveWireless}, // OnLive Controller (Bluetooth) + {0x2378, 0x100a, MapperOnLiveWireless}, // OnLive Controller (Wired) + {0x2836, 0x0001, MapperOUYA}, // OUYA Controller }; +const size_t kAvailableMappingsLen = base::size(AvailableMappings); } // namespace GamepadStandardMappingFunction GetGamepadStandardMappingFunction( - const base::StringPiece& vendor_id, - const base::StringPiece& product_id, - const base::StringPiece& version_number, + const uint16_t vendor_id, + const uint16_t product_id, + const uint16_t version_number, GamepadBusType bus_type) { GamepadStandardMappingFunction mapper = nullptr; - for (size_t i = 0; i < arraysize(AvailableMappings); ++i) { + for (size_t i = 0; i < kAvailableMappingsLen; ++i) { MappingData& item = AvailableMappings[i]; if (vendor_id == item.vendor_id && product_id == item.product_id) { mapper = item.function; @@ -600,9 +612,11 @@ // The Linux kernel was updated in version 4.10 to better support Dualshock 4 // and Dualshock 3/SIXAXIS gamepads. The driver patches the hardware version // when using the new mapping to allow downstream users to distinguish them. - if (mapper == MapperDualshock4 && version_number == "8111") { + if (mapper == MapperDualshock4 && + version_number == kDualshockPatchedVersion) { mapper = MapperDualshock4New; - } else if (mapper == MapperDualshock3SixAxis && version_number == "8111") { + } else if (mapper == MapperDualshock3SixAxis && + version_number == kDualshockPatchedVersion) { mapper = MapperDualshock3SixAxisNew; }
diff --git a/device/gamepad/gamepad_standard_mappings_mac.mm b/device/gamepad/gamepad_standard_mappings_mac.mm index aa7d290..d183ea24 100644 --- a/device/gamepad/gamepad_standard_mappings_mac.mm +++ b/device/gamepad/gamepad_standard_mappings_mac.mm
@@ -5,6 +5,7 @@ #include <stddef.h> #include "base/macros.h" +#include "base/stl_util.h" #include "device/gamepad/gamepad_standard_mappings.h" namespace device { @@ -393,56 +394,57 @@ } struct MappingData { - const char* const vendor_id; - const char* const product_id; + const uint16_t vendor_id; + const uint16_t product_id; GamepadStandardMappingFunction function; } AvailableMappings[] = { // http://www.linux-usb.org/usb.ids - {"0079", "0006", MapperDragonRiseGeneric}, // DragonRise Generic USB - {"045e", "028e", MapperXbox360Gamepad}, // Xbox 360 Wired - {"045e", "028f", MapperXbox360Gamepad}, // Xbox 360 Wireless - {"045e", "02d1", MapperXbox360Gamepad}, // Xbox One Wired - {"045e", "02dd", MapperXbox360Gamepad}, // Xbox One Wired (2015 FW) - {"045e", "02e0", MapperXboxOneS}, // Xbox One S (Bluetooth) - {"045e", "02e3", MapperXbox360Gamepad}, // Xbox One Elite Wired - {"045e", "02ea", MapperXbox360Gamepad}, // Xbox One S (USB) - {"045e", "02fd", MapperXboxOneS2016Firmware}, // Xbox One S (Bluetooth) - {"045e", "0719", MapperXbox360Gamepad}, // Xbox 360 Wireless - {"046d", "c216", MapperDirectInputStyle}, // Logitech F310, D mode - {"046d", "c218", MapperDirectInputStyle}, // Logitech F510, D mode - {"046d", "c219", MapperDirectInputStyle}, // Logitech F710, D mode - {"054c", "0268", MapperPlaystationSixAxis}, // Playstation SIXAXIS - {"054c", "05c4", MapperDualshock4}, // Playstation Dualshock 4 - {"054c", "09cc", MapperDualshock4}, // Dualshock 4 (PS4 Slim) - {"054c", "0ba0", MapperDualshock4}, // Dualshock 4 USB receiver - {"0583", "2060", MapperIBuffalo}, // iBuffalo Classic - {"0925", "0005", MapperSmartJoyPLUS}, // SmartJoy PLUS Adapter - {"0955", "7210", MapperNvShield}, // Nvidia Shield gamepad (2015) - {"0b05", "4500", MapperADT1}, // Nexus Player Controller - {"0e8f", "0003", MapperXGEAR}, // XFXforce XGEAR PS2 Controller - {"1532", "0900", MapperRazerServal}, // Razer Serval Controller - {"18d1", "2c40", MapperADT1}, // ADT-1 Controller - {"20d6", "6271", MapperMogaPro}, // Moga Pro Controller (HID mode) - {"2222", "0060", MapperDirectInputStyle}, // Macally iShockX, analog mode - {"2222", "4010", MapperMacallyIShock}, // Macally iShock - {"2378", "1008", MapperOnLiveWireless}, // OnLive Controller (Bluetooth) - {"2378", "100a", MapperOnLiveWireless}, // OnLive Controller (Wired) - {"2836", "0001", MapperOUYA}, // OUYA Controller + {0x0079, 0x0006, MapperDragonRiseGeneric}, // DragonRise Generic USB + {0x045e, 0x028e, MapperXbox360Gamepad}, // Xbox 360 Wired + {0x045e, 0x028f, MapperXbox360Gamepad}, // Xbox 360 Wireless + {0x045e, 0x02d1, MapperXbox360Gamepad}, // Xbox One Wired + {0x045e, 0x02dd, MapperXbox360Gamepad}, // Xbox One Wired (2015 FW) + {0x045e, 0x02e0, MapperXboxOneS}, // Xbox One S (Bluetooth) + {0x045e, 0x02e3, MapperXbox360Gamepad}, // Xbox One Elite Wired + {0x045e, 0x02ea, MapperXbox360Gamepad}, // Xbox One S (USB) + {0x045e, 0x02fd, MapperXboxOneS2016Firmware}, // Xbox One S (Bluetooth) + {0x045e, 0x0719, MapperXbox360Gamepad}, // Xbox 360 Wireless + {0x046d, 0xc216, MapperDirectInputStyle}, // Logitech F310, D mode + {0x046d, 0xc218, MapperDirectInputStyle}, // Logitech F510, D mode + {0x046d, 0xc219, MapperDirectInputStyle}, // Logitech F710, D mode + {0x054c, 0x0268, MapperPlaystationSixAxis}, // Playstation SIXAXIS + {0x054c, 0x05c4, MapperDualshock4}, // Playstation Dualshock 4 + {0x054c, 0x09cc, MapperDualshock4}, // Dualshock 4 (PS4 Slim) + {0x054c, 0x0ba0, MapperDualshock4}, // Dualshock 4 USB receiver + {0x0583, 0x2060, MapperIBuffalo}, // iBuffalo Classic + {0x0925, 0x0005, MapperSmartJoyPLUS}, // SmartJoy PLUS Adapter + {0x0955, 0x7210, MapperNvShield}, // Nvidia Shield gamepad (2015) + {0x0b05, 0x4500, MapperADT1}, // Nexus Player Controller + {0x0e8f, 0x0003, MapperXGEAR}, // XFXforce XGEAR PS2 Controller + {0x1532, 0x0900, MapperRazerServal}, // Razer Serval Controller + {0x18d1, 0x2c40, MapperADT1}, // ADT-1 Controller + {0x20d6, 0x6271, MapperMogaPro}, // Moga Pro Controller (HID mode) + {0x2222, 0x0060, MapperDirectInputStyle}, // Macally iShockX, analog mode + {0x2222, 0x4010, MapperMacallyIShock}, // Macally iShock + {0x2378, 0x1008, MapperOnLiveWireless}, // OnLive Controller (Bluetooth) + {0x2378, 0x100a, MapperOnLiveWireless}, // OnLive Controller (Wired) + {0x2836, 0x0001, MapperOUYA}, // OUYA Controller }; +const size_t kAvailableMappingsLen = base::size(AvailableMappings); } // namespace GamepadStandardMappingFunction GetGamepadStandardMappingFunction( - const base::StringPiece& vendor_id, - const base::StringPiece& product_id, - const base::StringPiece& version_number, + const uint16_t vendor_id, + const uint16_t product_id, + const uint16_t version_number, GamepadBusType bus_type) { - for (size_t i = 0; i < arraysize(AvailableMappings); ++i) { + for (size_t i = 0; i < kAvailableMappingsLen; ++i) { MappingData& item = AvailableMappings[i]; if (vendor_id == item.vendor_id && product_id == item.product_id) return item.function; } - return NULL; + return nullptr; } } // namespace device
diff --git a/device/gamepad/gamepad_standard_mappings_win.cc b/device/gamepad/gamepad_standard_mappings_win.cc index c265ca86..3d7630a 100644 --- a/device/gamepad/gamepad_standard_mappings_win.cc +++ b/device/gamepad/gamepad_standard_mappings_win.cc
@@ -5,6 +5,7 @@ #include <stddef.h> #include "base/macros.h" +#include "base/stl_util.h" #include "device/gamepad/gamepad_standard_mappings.h" namespace device { @@ -261,43 +262,44 @@ } struct MappingData { - const char* const vendor_id; - const char* const product_id; + const uint16_t vendor_id; + const uint16_t product_id; GamepadStandardMappingFunction function; } AvailableMappings[] = { // http://www.linux-usb.org/usb.ids - {"0079", "0011", Mapper2Axes8Keys}, // 2Axes 8Keys Game Pad - {"046d", "c216", MapperLogitechDInput}, // Logitech F310, D-mode - {"046d", "c218", MapperLogitechDInput}, // Logitech F510, D-mode - {"046d", "c219", MapperLogitechDInput}, // Logitech F710, D-mode - {"054c", "05c4", MapperDualshock4}, // Playstation Dualshock 4 - {"054c", "09cc", MapperDualshock4}, // Dualshock 4 (PS4 Slim) - {"054c", "0ba0", MapperDualshock4}, // Dualshock 4 USB receiver - {"0583", "2060", MapperIBuffalo}, // iBuffalo Classic - {"0955", "7210", MapperNvShield}, // Nvidia Shield gamepad (2015) - {"0955", "7214", MapperNvShield2017}, // Nvidia Shield gamepad (2017) - {"0b05", "4500", MapperADT1}, // Nexus Player Controller - {"1532", "0900", MapperRazerServal}, // Razer Serval Controller - {"18d1", "2c40", MapperADT1}, // ADT-1 Controller - {"20d6", "6271", MapperMogaPro}, // Moga Pro Controller (HID mode) - {"2378", "1008", MapperOnLiveWireless}, // OnLive Controller (Bluetooth) - {"2378", "100a", MapperOnLiveWireless}, // OnLive Controller (Wired) - {"2836", "0001", MapperOUYA}, // OUYA Controller + {0x0079, 0x0011, Mapper2Axes8Keys}, // 2Axes 8Keys Game Pad + {0x046d, 0xc216, MapperLogitechDInput}, // Logitech F310, D-mode + {0x046d, 0xc218, MapperLogitechDInput}, // Logitech F510, D-mode + {0x046d, 0xc219, MapperLogitechDInput}, // Logitech F710, D-mode + {0x054c, 0x05c4, MapperDualshock4}, // Playstation Dualshock 4 + {0x054c, 0x09cc, MapperDualshock4}, // Dualshock 4 (PS4 Slim) + {0x054c, 0x0ba0, MapperDualshock4}, // Dualshock 4 USB receiver + {0x0583, 0x2060, MapperIBuffalo}, // iBuffalo Classic + {0x0955, 0x7210, MapperNvShield}, // Nvidia Shield gamepad (2015) + {0x0955, 0x7214, MapperNvShield2017}, // Nvidia Shield gamepad (2017) + {0x0b05, 0x4500, MapperADT1}, // Nexus Player Controller + {0x1532, 0x0900, MapperRazerServal}, // Razer Serval Controller + {0x18d1, 0x2c40, MapperADT1}, // ADT-1 Controller + {0x20d6, 0x6271, MapperMogaPro}, // Moga Pro Controller (HID mode) + {0x2378, 0x1008, MapperOnLiveWireless}, // OnLive Controller (Bluetooth) + {0x2378, 0x100a, MapperOnLiveWireless}, // OnLive Controller (Wired) + {0x2836, 0x0001, MapperOUYA}, // OUYA Controller }; +const size_t kAvailableMappingsLen = base::size(AvailableMappings); } // namespace GamepadStandardMappingFunction GetGamepadStandardMappingFunction( - const base::StringPiece& vendor_id, - const base::StringPiece& product_id, - const base::StringPiece& version_number, + const uint16_t vendor_id, + const uint16_t product_id, + const uint16_t version_number, GamepadBusType bus_type) { - for (size_t i = 0; i < arraysize(AvailableMappings); ++i) { + for (size_t i = 0; i < kAvailableMappingsLen; ++i) { MappingData& item = AvailableMappings[i]; if (vendor_id == item.vendor_id && product_id == item.product_id) return item.function; } - return NULL; + return nullptr; } } // namespace device
diff --git a/device/gamepad/raw_input_data_fetcher_win.cc b/device/gamepad/raw_input_data_fetcher_win.cc index c85f865..f4c2a2c 100644 --- a/device/gamepad/raw_input_data_fetcher_win.cc +++ b/device/gamepad/raw_input_data_fetcher_win.cc
@@ -196,11 +196,8 @@ const int version_number = device->GetVersionNumber(); const std::wstring product_string = device->GetProductString(); - const std::string vendor = base::StringPrintf("%04x", vendor_int); - const std::string product = base::StringPrintf("%04x", product_int); - const std::string version = base::StringPrintf("%04x", version_number); state->mapper = GetGamepadStandardMappingFunction( - vendor, product, version, GAMEPAD_BUS_UNKNOWN); + vendor_int, product_int, version_number, GAMEPAD_BUS_UNKNOWN); state->axis_mask = 0; state->button_mask = 0;
diff --git a/device/gamepad/raw_input_gamepad_device_win.cc b/device/gamepad/raw_input_gamepad_device_win.cc index c124bfe..171e4bb 100644 --- a/device/gamepad/raw_input_gamepad_device_win.cc +++ b/device/gamepad/raw_input_gamepad_device_win.cc
@@ -109,8 +109,6 @@ DCHECK(hid_functions_->IsValid()); NTSTATUS status; - report_id_++; - // Query button state. if (buttons_length_ > 0) { // Clear the button state @@ -291,9 +289,9 @@ reinterpret_cast<RID_DEVICE_INFO*>(buffer.get()); DCHECK_EQ(device_info->dwType, static_cast<DWORD>(RIM_TYPEHID)); - vendor_id_ = device_info->hid.dwVendorId; - product_id_ = device_info->hid.dwProductId; - version_number_ = device_info->hid.dwVersionNumber; + vendor_id_ = static_cast<uint16_t>(device_info->hid.dwVendorId); + product_id_ = static_cast<uint16_t>(device_info->hid.dwProductId); + version_number_ = static_cast<uint16_t>(device_info->hid.dwVersionNumber); usage_ = device_info->hid.usUsage; return true;
diff --git a/device/gamepad/raw_input_gamepad_device_win.h b/device/gamepad/raw_input_gamepad_device_win.h index a23b232..72cf57b 100644 --- a/device/gamepad/raw_input_gamepad_device_win.h +++ b/device/gamepad/raw_input_gamepad_device_win.h
@@ -38,9 +38,9 @@ static bool IsGamepadUsageId(uint16_t usage); int GetSourceId() const { return source_id_; } - int GetVendorId() const { return vendor_id_; } - int GetVersionNumber() const { return version_number_; } - int GetProductId() const { return product_id_; } + uint16_t GetVendorId() const { return vendor_id_; } + uint16_t GetVersionNumber() const { return version_number_; } + uint16_t GetProductId() const { return product_id_; } std::wstring GetDeviceName() const { return name_; } std::wstring GetProductString() const { return product_string_; } @@ -111,13 +111,9 @@ // Functions loaded from hid.dll. Not owned. HidDllFunctionsWin* hid_functions_ = nullptr; - // The report ID incremented each time an input message is received for this - // device. It is included in the pad info in place of a timestamp. - uint32_t report_id_ = 0; - - uint32_t vendor_id_ = 0; - uint32_t product_id_ = 0; - uint32_t version_number_ = 0; + uint16_t vendor_id_ = 0; + uint16_t product_id_ = 0; + uint16_t version_number_ = 0; uint16_t usage_ = 0; std::wstring name_; std::wstring product_string_;
diff --git a/device/gamepad/switch_pro_controller_base.cc b/device/gamepad/switch_pro_controller_base.cc index 7cc5096b..2179673 100644 --- a/device/gamepad/switch_pro_controller_base.cc +++ b/device/gamepad/switch_pro_controller_base.cc
@@ -10,8 +10,8 @@ #include "device/gamepad/gamepad_standard_mappings.h" namespace { -const uint32_t kVendorNintendo = 0x057e; -const uint32_t kProductSwitchProController = 0x2009; +const uint16_t kVendorNintendo = 0x057e; +const uint16_t kProductSwitchProController = 0x2009; const uint8_t kRumbleMagnitudeMax = 0xff; @@ -59,7 +59,8 @@ }; #pragma pack(pop) -ControllerType ControllerTypeFromDeviceIds(int vendor_id, int product_id) { +ControllerType ControllerTypeFromDeviceIds(uint16_t vendor_id, + uint16_t product_id) { if (vendor_id == kVendorNintendo) { switch (product_id) { case kProductSwitchProController: @@ -178,7 +179,8 @@ SwitchProControllerBase::~SwitchProControllerBase() = default; // static -bool SwitchProControllerBase::IsSwitchPro(int vendor_id, int product_id) { +bool SwitchProControllerBase::IsSwitchPro(uint16_t vendor_id, + uint16_t product_id) { return ControllerTypeFromDeviceIds(vendor_id, product_id) != UNKNOWN_CONTROLLER; }
diff --git a/device/gamepad/switch_pro_controller_base.h b/device/gamepad/switch_pro_controller_base.h index 535a6875..35290d3 100644 --- a/device/gamepad/switch_pro_controller_base.h +++ b/device/gamepad/switch_pro_controller_base.h
@@ -18,7 +18,7 @@ SwitchProControllerBase() = default; ~SwitchProControllerBase() override; - static bool IsSwitchPro(int vendor_id, int product_id); + static bool IsSwitchPro(uint16_t vendor_id, uint16_t product_id); void DoShutdown() override;
diff --git a/device/gamepad/xbox_controller_mac.h b/device/gamepad/xbox_controller_mac.h index edc1344..9fb312e 100644 --- a/device/gamepad/xbox_controller_mac.h +++ b/device/gamepad/xbox_controller_mac.h
@@ -25,12 +25,12 @@ class XboxControllerMac { public: - static const int kVendorMicrosoft = 0x045e; - static const int kProductXbox360Controller = 0x028e; - static const int kProductXboxOneController2013 = 0x02d1; - static const int kProductXboxOneController2015 = 0x02dd; - static const int kProductXboxOneEliteController = 0x02e3; - static const int kProductXboxOneSController = 0x02ea; + static const uint16_t kVendorMicrosoft = 0x045e; + static const uint16_t kProductXbox360Controller = 0x028e; + static const uint16_t kProductXboxOneController2013 = 0x02d1; + static const uint16_t kProductXboxOneController2015 = 0x02dd; + static const uint16_t kProductXboxOneEliteController = 0x02e3; + static const uint16_t kProductXboxOneSController = 0x02ea; enum ControllerType { UNKNOWN_CONTROLLER, @@ -114,8 +114,8 @@ mojom::GamepadHapticsManager::ResetVibrationActuatorCallback callback); UInt32 location_id() { return location_id_; } - int GetVendorId() const; - int GetProductId() const; + uint16_t GetVendorId() const; + uint16_t GetProductId() const; ControllerType GetControllerType() const; std::string GetControllerTypeString() const; std::string GetIdString() const;
diff --git a/device/gamepad/xbox_controller_mac.mm b/device/gamepad/xbox_controller_mac.mm index 89745ffb..89670b4 100644 --- a/device/gamepad/xbox_controller_mac.mm +++ b/device/gamepad/xbox_controller_mac.mm
@@ -277,8 +277,8 @@ &normalized_data->axes[2], &normalized_data->axes[3]); } -XboxControllerMac::ControllerType ControllerTypeFromIds(int vendor_id, - int product_id) { +XboxControllerMac::ControllerType ControllerTypeFromIds(uint16_t vendor_id, + uint16_t product_id) { if (vendor_id == XboxControllerMac::kVendorMicrosoft) { switch (product_id) { case XboxControllerMac::kProductXbox360Controller: @@ -438,12 +438,12 @@ if (!SUCCEEDED(res) || !device_) return OPEN_FAILED; - UInt16 vendor_id; + uint16_t vendor_id; kr = (*device_)->GetDeviceVendor(device_, &vendor_id); if (kr != KERN_SUCCESS || vendor_id != kVendorMicrosoft) return OPEN_FAILED; - UInt16 product_id; + uint16_t product_id; kr = (*device_)->GetDeviceProduct(device_, &product_id); if (kr != KERN_SUCCESS) return OPEN_FAILED; @@ -633,7 +633,7 @@ } } -int XboxControllerMac::GetVendorId() const { +uint16_t XboxControllerMac::GetVendorId() const { switch (controller_type_) { case XBOX_360_CONTROLLER: case XBOX_ONE_CONTROLLER_2013: @@ -646,7 +646,7 @@ } } -int XboxControllerMac::GetProductId() const { +uint16_t XboxControllerMac::GetProductId() const { switch (controller_type_) { case XBOX_360_CONTROLLER: return kProductXbox360Controller;
diff --git a/extensions/common/permissions/permissions_info.h b/extensions/common/permissions/permissions_info.h index a66da3b..dbc25b1 100644 --- a/extensions/common/permissions/permissions_info.h +++ b/extensions/common/permissions/permissions_info.h
@@ -11,6 +11,7 @@ #include <memory> #include <set> #include <string> +#include <unordered_map> #include <vector> #include "base/callback.h" @@ -71,7 +72,9 @@ void RegisterPermission(std::unique_ptr<APIPermissionInfo> permission); // Maps permission ids to permissions. Owns the permissions. - typedef std::map<APIPermission::ID, std::unique_ptr<APIPermissionInfo>> IDMap; + typedef std::unordered_map<APIPermission::ID, + std::unique_ptr<APIPermissionInfo>> + IDMap; // Maps names and aliases to permissions. Doesn't own the permissions. typedef std::map<std::string, APIPermissionInfo*> NameMap;
diff --git a/gpu/config/gpu_info.cc b/gpu/config/gpu_info.cc index 2167245..9c44106 100644 --- a/gpu/config/gpu_info.cc +++ b/gpu/config/gpu_info.cc
@@ -58,6 +58,17 @@ enumerator->AddInt("isScalingSupported", cap.is_scaling_supported); enumerator->EndOverlayCapability(); } + +void EnumerateDx12VulkanVersionInfo(const gpu::Dx12VulkanVersionInfo& info, + gpu::GPUInfo::Enumerator* enumerator) { + enumerator->BeginDx12VulkanVersionInfo(); + enumerator->AddBool("supportsDx12", info.supports_dx12); + enumerator->AddBool("supportsVulkan", info.supports_vulkan); + enumerator->AddInt("dx12FeatureLevel", + static_cast<int>(info.d3d12_feature_level)); + enumerator->AddInt("vulkanVersion", static_cast<int>(info.vulkan_version)); + enumerator->EndDx12VulkanVersionInfo(); +} #endif } // namespace @@ -179,10 +190,7 @@ bool supports_overlays; OverlayCapabilities overlay_capabilities; DxDiagNode dx_diagnostics; - bool supports_dx12; - bool supports_vulkan; - uint32_t d3d12_feature_level; - uint32_t vulkan_version; + Dx12VulkanVersionInfo dx12_vulkan_version_info; #endif VideoDecodeAcceleratorCapabilities video_decode_accelerator_capabilities; @@ -242,10 +250,7 @@ enumerator->AddBool("supportsOverlays", supports_overlays); for (const auto& cap : overlay_capabilities) EnumerateOverlayCapability(cap, enumerator); - enumerator->AddBool("supportsDX12", supports_dx12); - enumerator->AddBool("supportsVulkan", supports_vulkan); - enumerator->AddInt("d3dFeatureLevel", d3d12_feature_level); - enumerator->AddInt("vulkanVersion", vulkan_version); + EnumerateDx12VulkanVersionInfo(dx12_vulkan_version_info, enumerator); #endif enumerator->AddInt("videoDecodeAcceleratorFlags", video_decode_accelerator_capabilities.flags);
diff --git a/gpu/config/gpu_info.h b/gpu/config/gpu_info.h index 651800a..8457870 100644 --- a/gpu/config/gpu_info.h +++ b/gpu/config/gpu_info.h
@@ -104,6 +104,22 @@ }; using OverlayCapabilities = std::vector<OverlayCapability>; +struct GPU_EXPORT Dx12VulkanVersionInfo { + bool IsEmpty() const { return !d3d12_feature_level && !vulkan_version; } + + // True if the GPU driver supports DX12. + bool supports_dx12 = false; + + // True if the GPU driver supports Vulkan. + bool supports_vulkan = false; + + // The supported d3d feature level in the gpu driver; + uint32_t d3d12_feature_level = 0; + + // The support Vulkan API version in the gpu driver; + uint32_t vulkan_version = 0; +}; + struct GPU_EXPORT GPUInfo { struct GPU_EXPORT GPUDevice { GPUDevice(); @@ -245,17 +261,7 @@ // The information returned by the DirectX Diagnostics Tool. DxDiagNode dx_diagnostics; - // True if the GPU driver supports DX12. - bool supports_dx12 = false; - - // True if the GPU driver supports Vulkan. - bool supports_vulkan = false; - - // The supported d3d feature level in the gpu driver; - uint32_t d3d12_feature_level = 0; - - // The support Vulkan API version in the gpu driver; - uint32_t vulkan_version = 0; + Dx12VulkanVersionInfo dx12_vulkan_version_info; #endif VideoDecodeAcceleratorCapabilities video_decode_accelerator_capabilities; @@ -312,6 +318,9 @@ virtual void BeginOverlayCapability() = 0; virtual void EndOverlayCapability() = 0; + virtual void BeginDx12VulkanVersionInfo() = 0; + virtual void EndDx12VulkanVersionInfo() = 0; + protected: virtual ~Enumerator() = default; };
diff --git a/gpu/config/gpu_info_collector.h b/gpu/config/gpu_info_collector.h index a0d0c6f..9421bab 100644 --- a/gpu/config/gpu_info_collector.h +++ b/gpu/config/gpu_info_collector.h
@@ -42,7 +42,8 @@ #if defined(OS_WIN) // Collect the DirectX Disagnostics information about the attached displays. GPU_EXPORT bool GetDxDiagnostics(DxDiagNode* output); -GPU_EXPORT void RecordGpuSupportedRuntimeVersionHistograms(GPUInfo* gpu_info); +GPU_EXPORT void RecordGpuSupportedRuntimeVersionHistograms( + Dx12VulkanVersionInfo* dx12_vulkan_version_info); #endif // OS_WIN // Create a GL context and collect GL strings and versions.
diff --git a/gpu/config/gpu_info_collector_win.cc b/gpu/config/gpu_info_collector_win.cc index 05169e6..bde5ff34 100644 --- a/gpu/config/gpu_info_collector_win.cc +++ b/gpu/config/gpu_info_collector_win.cc
@@ -280,10 +280,10 @@ } // DirectX 12 are included with Windows 10 and Server 2016. -void GetGpuSupportedD3D12Version(GPUInfo* gpu_info) { +void GetGpuSupportedD3D12Version(Dx12VulkanVersionInfo* info) { TRACE_EVENT0("gpu", "GetGpuSupportedD3D12Version"); - gpu_info->supports_dx12 = false; - gpu_info->d3d12_feature_level = 0; + info->supports_dx12 = false; + info->d3d12_feature_level = 0; base::NativeLibrary d3d12_library = base::LoadNativeLibrary(base::FilePath(L"d3d12.dll"), nullptr); @@ -305,8 +305,8 @@ for (auto level : feature_levels) { if (SUCCEEDED(D3D12CreateDevice(nullptr, level, _uuidof(ID3D12Device), nullptr))) { - gpu_info->d3d12_feature_level = level; - gpu_info->supports_dx12 = true; + info->d3d12_feature_level = level; + info->supports_dx12 = true; break; } } @@ -315,7 +315,7 @@ base::UnloadNativeLibrary(d3d12_library); } -bool BadAMDVulkanDriverVersion(GPUInfo* gpu_info) { +bool BadAMDVulkanDriverVersion() { // Both 32-bit and 64-bit dll are broken. If 64-bit doesn't exist, // 32-bit dll will be used to detect the AMD Vulkan driver. const base::FilePath kAmdDriver64(FILE_PATH_LITERAL("amdvlk64.dll")); @@ -347,7 +347,7 @@ return false; } -bool BadVulkanDllVersion(GPUInfo* gpu_info) { +bool BadVulkanDllVersion() { std::unique_ptr<FileVersionInfoWin> file_version_info( static_cast<FileVersionInfoWin*>( FileVersionInfoWin::CreateFileVersionInfo( @@ -437,7 +437,7 @@ } void GetGpuSupportedVulkanVersionAndExtensions( - GPUInfo* gpu_info, + Dx12VulkanVersionInfo* info, const std::vector<const char*>& requested_vulkan_extensions, std::vector<bool>* extension_support) { TRACE_EVENT0("gpu", "GetGpuSupportedVulkanVersionAndExtensions"); @@ -450,18 +450,18 @@ PFN_vkDestroyInstance vkDestroyInstance; VkInstance vk_instance = VK_NULL_HANDLE; uint32_t physical_device_count = 0; - gpu_info->supports_vulkan = false; - gpu_info->vulkan_version = 0; + info->supports_vulkan = false; + info->vulkan_version = 0; // Skip if the system has an older AMD Vulkan driver amdvlk64.dll or // amdvlk32.dll which crashes when vkCreateInstance() is called. This bug has // been fixed in the latest AMD driver. - if (BadAMDVulkanDriverVersion(gpu_info)) { + if (BadAMDVulkanDriverVersion()) { return; } // Some early versions of vulkan-1.dll might crash - if (BadVulkanDllVersion(gpu_info)) { + if (BadVulkanDllVersion()) { return; } @@ -487,8 +487,8 @@ result = vkEnumeratePhysicalDevices(vk_instance, &physical_device_count, nullptr); if (result == VK_SUCCESS && physical_device_count > 0) { - gpu_info->supports_vulkan = true; - gpu_info->vulkan_version = app_info.apiVersion; + info->supports_vulkan = true; + info->vulkan_version = app_info.apiVersion; break; } else { vkDestroyInstance(vk_instance, nullptr); @@ -498,7 +498,7 @@ } // Check whether the requested_vulkan_extensions are supported - if (gpu_info->supports_vulkan) { + if (info->supports_vulkan) { std::vector<VkPhysicalDevice> physical_devices(physical_device_count); vkEnumeratePhysicalDevices(vk_instance, &physical_device_count, physical_devices.data()); @@ -533,26 +533,26 @@ base::UnloadNativeLibrary(vulkan_library); } -void RecordGpuSupportedRuntimeVersionHistograms(GPUInfo* gpu_info) { +void RecordGpuSupportedRuntimeVersionHistograms(Dx12VulkanVersionInfo* info) { // D3D - GetGpuSupportedD3D12Version(gpu_info); - UMA_HISTOGRAM_BOOLEAN("GPU.SupportsDX12", gpu_info->supports_dx12); + GetGpuSupportedD3D12Version(info); + UMA_HISTOGRAM_BOOLEAN("GPU.SupportsDX12", info->supports_dx12); UMA_HISTOGRAM_ENUMERATION( "GPU.D3D12FeatureLevel", - ConvertToHistogramFeatureLevel(gpu_info->d3d12_feature_level)); + ConvertToHistogramFeatureLevel(info->d3d12_feature_level)); // Vulkan const std::vector<const char*> vulkan_extensions = { "VK_KHR_external_memory_win32", "VK_KHR_external_semaphore_win32", "VK_KHR_win32_keyed_mutex"}; std::vector<bool> extension_support(vulkan_extensions.size(), false); - GetGpuSupportedVulkanVersionAndExtensions(gpu_info, vulkan_extensions, + GetGpuSupportedVulkanVersionAndExtensions(info, vulkan_extensions, &extension_support); - UMA_HISTOGRAM_BOOLEAN("GPU.SupportsVulkan", gpu_info->supports_vulkan); + UMA_HISTOGRAM_BOOLEAN("GPU.SupportsVulkan", info->supports_vulkan); UMA_HISTOGRAM_ENUMERATION( "GPU.VulkanVersion", - ConvertToHistogramVulkanVersion(gpu_info->vulkan_version)); + ConvertToHistogramVulkanVersion(info->vulkan_version)); for (size_t i = 0; i < vulkan_extensions.size(); ++i) { std::string name = "GPU.VulkanExtSupport.";
diff --git a/gpu/ipc/common/gpu_info.mojom b/gpu/ipc/common/gpu_info.mojom index cad864d4..d29b09c0 100644 --- a/gpu/ipc/common/gpu_info.mojom +++ b/gpu/ipc/common/gpu_info.mojom
@@ -89,6 +89,14 @@ bool is_scaling_supported; }; +// gpu::Dx12VulkanVersionInfo +struct Dx12VulkanVersionInfo { + bool supports_dx12; + bool supports_vulkan; + uint32 d3d12_feature_level; + uint32 vulkan_version; +}; + // Corresponds to |gpu::GPUInfo| in gpu/config/gpu_info.h struct GpuInfo { mojo_base.mojom.TimeDelta initialization_time; @@ -124,13 +132,7 @@ [EnableIf=is_win] DxDiagNode dx_diagnostics; [EnableIf=is_win] - bool supports_dx12; - [EnableIf=is_win] - bool supports_vulkan; - [EnableIf=is_win] - uint32 d3d12_feature_level; - [EnableIf=is_win] - uint32 vulkan_version; + Dx12VulkanVersionInfo dx12_vulkan_version_info; VideoDecodeAcceleratorCapabilities video_decode_accelerator_capabilities; array<VideoEncodeAcceleratorSupportedProfile> video_encode_accelerator_supported_profiles;
diff --git a/gpu/ipc/common/gpu_info.typemap b/gpu/ipc/common/gpu_info.typemap index 3e74664..946138f 100644 --- a/gpu/ipc/common/gpu_info.typemap +++ b/gpu/ipc/common/gpu_info.typemap
@@ -14,6 +14,7 @@ ] type_mappings = [ "gpu.mojom.CollectInfoResult=gpu::CollectInfoResult", + "gpu.mojom.Dx12VulkanVersionInfo=gpu::Dx12VulkanVersionInfo", "gpu.mojom.GpuDevice=gpu::GPUInfo::GPUDevice", "gpu.mojom.GpuInfo=gpu::GPUInfo", "gpu.mojom.VideoCodecProfile=gpu::VideoCodecProfile",
diff --git a/gpu/ipc/common/gpu_info_struct_traits.cc b/gpu/ipc/common/gpu_info_struct_traits.cc index 80ebc5f..117dd3e7 100644 --- a/gpu/ipc/common/gpu_info_struct_traits.cc +++ b/gpu/ipc/common/gpu_info_struct_traits.cc
@@ -258,6 +258,18 @@ out->is_scaling_supported = data.is_scaling_supported(); return data.ReadFormat(&out->format); } + +// static +bool StructTraits<gpu::mojom::Dx12VulkanVersionInfoDataView, + gpu::Dx12VulkanVersionInfo>:: + Read(gpu::mojom::Dx12VulkanVersionInfoDataView data, + gpu::Dx12VulkanVersionInfo* out) { + out->supports_dx12 = data.supports_dx12(); + out->supports_vulkan = data.supports_vulkan(); + out->d3d12_feature_level = data.d3d12_feature_level(); + out->vulkan_version = data.vulkan_version(); + return true; +} #endif bool StructTraits<gpu::mojom::GpuInfoDataView, gpu::GPUInfo>::Read( @@ -285,10 +297,6 @@ #if defined(OS_WIN) out->direct_composition = data.direct_composition(); out->supports_overlays = data.supports_overlays(); - out->supports_dx12 = data.supports_dx12(); - out->supports_vulkan = data.supports_vulkan(); - out->d3d12_feature_level = data.d3d12_feature_level(); - out->vulkan_version = data.vulkan_version(); #endif return data.ReadInitializationTime(&out->initialization_time) && @@ -309,6 +317,7 @@ #if defined(OS_WIN) data.ReadOverlayCapabilities(&out->overlay_capabilities) && data.ReadDxDiagnostics(&out->dx_diagnostics) && + data.ReadDx12VulkanVersionInfo(&out->dx12_vulkan_version_info) && #endif data.ReadVideoDecodeAcceleratorCapabilities( &out->video_decode_accelerator_capabilities) &&
diff --git a/gpu/ipc/common/gpu_info_struct_traits.h b/gpu/ipc/common/gpu_info_struct_traits.h index 2af4721..2fd7bc9 100644 --- a/gpu/ipc/common/gpu_info_struct_traits.h +++ b/gpu/ipc/common/gpu_info_struct_traits.h
@@ -164,6 +164,29 @@ }; template <> +struct StructTraits<gpu::mojom::Dx12VulkanVersionInfoDataView, + gpu::Dx12VulkanVersionInfo> { + static bool Read(gpu::mojom::Dx12VulkanVersionInfoDataView data, + gpu::Dx12VulkanVersionInfo* out); + + static bool supports_dx12(const gpu::Dx12VulkanVersionInfo& input) { + return input.supports_dx12; + } + + static bool supports_vulkan(const gpu::Dx12VulkanVersionInfo& input) { + return input.supports_vulkan; + } + + static uint32_t d3d12_feature_level(const gpu::Dx12VulkanVersionInfo& input) { + return input.d3d12_feature_level; + } + + static uint32_t vulkan_version(const gpu::Dx12VulkanVersionInfo& input) { + return input.vulkan_version; + } +}; + +template <> struct StructTraits<gpu::mojom::GpuInfoDataView, gpu::GPUInfo> { static bool Read(gpu::mojom::GpuInfoDataView data, gpu::GPUInfo* out); @@ -278,20 +301,9 @@ return input.dx_diagnostics; } - static bool supports_dx12(const gpu::GPUInfo& input) { - return input.supports_dx12; - } - - static bool supports_vulkan(const gpu::GPUInfo& input) { - return input.supports_vulkan; - } - - static uint32_t d3d12_feature_level(const gpu::GPUInfo& input) { - return input.d3d12_feature_level; - } - - static uint32_t vulkan_version(const gpu::GPUInfo& input) { - return input.vulkan_version; + static const gpu::Dx12VulkanVersionInfo& dx12_vulkan_version_info( + const gpu::GPUInfo& input) { + return input.dx12_vulkan_version_info; } #endif
diff --git a/headless/lib/browser/headless_browser_context_impl.cc b/headless/lib/browser/headless_browser_context_impl.cc index cf034d3..4a19349 100644 --- a/headless/lib/browser/headless_browser_context_impl.cc +++ b/headless/lib/browser/headless_browser_context_impl.cc
@@ -22,6 +22,7 @@ #include "headless/lib/browser/headless_browser_main_parts.h" #include "headless/lib/browser/headless_permission_manager.h" #include "headless/lib/browser/headless_url_request_context_getter.h" +#include "headless/lib/browser/headless_web_contents_impl.h" #include "net/url_request/url_request_context.h" #include "ui/base/resource/resource_bundle.h"
diff --git a/headless/lib/browser/headless_browser_impl.cc b/headless/lib/browser/headless_browser_impl.cc index 94cba00..87e476d 100644 --- a/headless/lib/browser/headless_browser_impl.cc +++ b/headless/lib/browser/headless_browser_impl.cc
@@ -18,7 +18,6 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/devtools_agent_host.h" -#include "content/public/browser/web_contents.h" #include "content/public/common/content_switches.h" #include "headless/app/headless_shell_switches.h" #include "headless/lib/browser/headless_browser_context_impl.h" @@ -26,23 +25,14 @@ #include "headless/lib/browser/headless_devtools_agent_host_client.h" #include "headless/lib/browser/headless_web_contents_impl.h" #include "headless/lib/headless_content_main_delegate.h" -#include "headless/public/internal/headless_devtools_client_impl.h" #include "net/http/http_util.h" #include "services/network/public/cpp/network_switches.h" -#include "ui/aura/client/focus_client.h" -#include "ui/aura/env.h" -#include "ui/aura/window.h" #include "ui/events/devices/device_data_manager.h" -#include "ui/gfx/geometry/size.h" #if defined(USE_NSS_CERTS) #include "net/cert_net/nss_ocsp.h" #endif -namespace content { -class DevToolsAgentHost; -} - namespace headless { namespace {
diff --git a/headless/lib/browser/headless_browser_impl.h b/headless/lib/browser/headless_browser_impl.h index 5ab8851..8fffb43 100644 --- a/headless/lib/browser/headless_browser_impl.h +++ b/headless/lib/browser/headless_browser_impl.h
@@ -14,20 +14,24 @@ #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" -#include "content/public/browser/web_contents.h" #include "headless/lib/browser/headless_devtools_manager_delegate.h" -#include "headless/lib/browser/headless_web_contents_impl.h" +#include "headless/public/headless_devtools_target.h" #include "headless/public/headless_export.h" namespace ui { class Compositor; } // namespace ui +namespace gfx { +class Rect; +} // namespace gfx + namespace headless { class HeadlessBrowserContextImpl; class HeadlessBrowserMainParts; class HeadlessURLRequestContextGetter; +class HeadlessWebContentsImpl; extern const base::FilePath::CharType kDefaultProfileName[];
diff --git a/headless/lib/browser/headless_browser_impl_aura.cc b/headless/lib/browser/headless_browser_impl_aura.cc index 56d8d51..58617e0 100644 --- a/headless/lib/browser/headless_browser_impl_aura.cc +++ b/headless/lib/browser/headless_browser_impl_aura.cc
@@ -10,6 +10,8 @@ #include "content/public/browser/web_contents.h" #include "headless/lib/browser/headless_clipboard.h" #include "headless/lib/browser/headless_screen.h" +#include "headless/lib/browser/headless_web_contents_impl.h" +#include "headless/lib/browser/headless_window_tree_host.h" #include "ui/aura/env.h" #include "ui/aura/window.h" #include "ui/base/clipboard/clipboard.h"
diff --git a/headless/lib/browser/headless_browser_impl_mac.mm b/headless/lib/browser/headless_browser_impl_mac.mm index beb30b8..fef6a41 100644 --- a/headless/lib/browser/headless_browser_impl_mac.mm +++ b/headless/lib/browser/headless_browser_impl_mac.mm
@@ -6,6 +6,7 @@ #import "base/mac/scoped_objc_class_swizzler.h" #include "content/public/browser/web_contents.h" +#include "headless/lib/browser/headless_web_contents_impl.h" #import "ui/base/cocoa/base_view.h" #import "ui/gfx/mac/coordinate_conversion.h"
diff --git a/headless/lib/browser/protocol/browser_handler.cc b/headless/lib/browser/protocol/browser_handler.cc index a0aac1ab..06719795 100644 --- a/headless/lib/browser/protocol/browser_handler.cc +++ b/headless/lib/browser/protocol/browser_handler.cc
@@ -7,7 +7,9 @@ #include "base/task/post_task.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/web_contents.h" #include "headless/lib/browser/headless_browser_impl.h" +#include "headless/lib/browser/headless_web_contents_impl.h" namespace headless { namespace protocol {
diff --git a/headless/lib/browser/protocol/target_handler.cc b/headless/lib/browser/protocol/target_handler.cc index b1865d56..15da7d7e 100644 --- a/headless/lib/browser/protocol/target_handler.cc +++ b/headless/lib/browser/protocol/target_handler.cc
@@ -7,6 +7,7 @@ #include "build/build_config.h" #include "headless/lib/browser/headless_browser_context_impl.h" #include "headless/lib/browser/headless_browser_impl.h" +#include "headless/lib/browser/headless_web_contents_impl.h" #include "ui/gfx/geometry/size.h" namespace headless {
diff --git a/infra/config/global/cr-buildbucket-dev.cfg b/infra/config/global/cr-buildbucket-dev.cfg index f41bc5f..99093ae57 100644 --- a/infra/config/global/cr-buildbucket-dev.cfg +++ b/infra/config/global/cr-buildbucket-dev.cfg
@@ -105,7 +105,7 @@ recipe { cipd_package: "infra/recipe_bundles/chromium.googlesource.com/infra/infra" cipd_version: "refs/heads/master" - name: "snapshot" + name: "snapshots/builder" } } }
diff --git a/media/BUILD.gn b/media/BUILD.gn index b4485e87..85a892d 100644 --- a/media/BUILD.gn +++ b/media/BUILD.gn
@@ -78,7 +78,10 @@ visibility += [ "//media/base/mac" ] } defines = [ "MEDIA_IMPLEMENTATION" ] - configs = [ ":media_config" ] + configs = [ + ":media_config", + "//build/config/compiler:wexit_time_destructors", + ] } component("media") {
diff --git a/media/base/android/media_codec_util.cc b/media/base/android/media_codec_util.cc index d5bdb55..41572909 100644 --- a/media/base/android/media_codec_util.cc +++ b/media/base/android/media_codec_util.cc
@@ -157,7 +157,7 @@ return model == other.model; } }; - static const std::vector<BlacklistEntry> blacklist = { + static const BlacklistEntry blacklist[] = { // crbug.com/653905 {"LGMS330", SDK_VERSION_LOLLIPOP_MR1}, @@ -192,9 +192,9 @@ {"GT-I8262B", SDK_VERSION_JELLY_BEAN_MR2}, }; - const auto iter = - std::find(blacklist.begin(), blacklist.end(), BlacklistEntry(model, 0)); - return iter == blacklist.end() || sdk > iter->last_bad_sdk; + const BlacklistEntry* iter = std::find( + std::begin(blacklist), std::end(blacklist), BlacklistEntry(model, 0)); + return iter == std::end(blacklist) || sdk > iter->last_bad_sdk; } // static
diff --git a/media/base/decode_status.cc b/media/base/decode_status.cc index b0156643..2315e256 100644 --- a/media/base/decode_status.cc +++ b/media/base/decode_status.cc
@@ -8,18 +8,19 @@ namespace media { -std::ostream& operator<<(std::ostream& os, const DecodeStatus& status) { +const char* GetDecodeStatusString(DecodeStatus status) { switch (status) { case DecodeStatus::OK: - os << "DecodeStatus::OK"; - break; + return "DecodeStatus::OK"; case DecodeStatus::ABORTED: - os << "DecodeStatus::ABORTED"; - break; + return "DecodeStatus::ABORTED"; case DecodeStatus::DECODE_ERROR: - os << "DecodeStatus::DECODE_ERROR"; - break; + return "DecodeStatus::DECODE_ERROR"; } +} + +std::ostream& operator<<(std::ostream& os, const DecodeStatus& status) { + os << GetDecodeStatusString(status); return os; }
diff --git a/media/base/decode_status.h b/media/base/decode_status.h index 665a9bd5..51c0c54b 100644 --- a/media/base/decode_status.h +++ b/media/base/decode_status.h
@@ -19,6 +19,8 @@ DECODE_STATUS_MAX = DECODE_ERROR }; +const char* GetDecodeStatusString(DecodeStatus status); + // Helper function so that DecodeStatus can be printed easily. MEDIA_EXPORT std::ostream& operator<<(std::ostream& os, const DecodeStatus& status);
diff --git a/media/base/media_tracks.cc b/media/base/media_tracks.cc index e257f92..13bfa102 100644 --- a/media/base/media_tracks.cc +++ b/media/base/media_tracks.cc
@@ -7,6 +7,7 @@ #include <memory> #include "base/bind.h" +#include "base/no_destructor.h" #include "media/base/audio_decoder_config.h" #include "media/base/video_decoder_config.h" @@ -53,8 +54,8 @@ auto it = audio_configs_.find(bytestream_track_id); if (it != audio_configs_.end()) return it->second; - static AudioDecoderConfig invalidConfig; - return invalidConfig; + static base::NoDestructor<AudioDecoderConfig> invalidConfig; + return *invalidConfig; } const VideoDecoderConfig& MediaTracks::getVideoConfig( @@ -62,8 +63,8 @@ auto it = video_configs_.find(bytestream_track_id); if (it != video_configs_.end()) return it->second; - static VideoDecoderConfig invalidConfig; - return invalidConfig; + static base::NoDestructor<VideoDecoderConfig> invalidConfig; + return *invalidConfig; } } // namespace media
diff --git a/media/base/media_util.h b/media/base/media_util.h index 0c45901..89ee5493 100644 --- a/media/base/media_util.h +++ b/media/base/media_util.h
@@ -8,8 +8,10 @@ #include <stdint.h> #include <vector> +#include "base/macros.h" #include "media/base/encryption_scheme.h" #include "media/base/media_export.h" +#include "media/base/media_log.h" namespace media { @@ -22,6 +24,17 @@ MEDIA_EXPORT EncryptionScheme Unencrypted(); MEDIA_EXPORT EncryptionScheme AesCtrEncryptionScheme(); +class MEDIA_EXPORT NullMediaLog : public media::MediaLog { + public: + NullMediaLog() = default; + ~NullMediaLog() override = default; + + void AddEventLocked(std::unique_ptr<media::MediaLogEvent> event) override {} + + private: + DISALLOW_COPY_AND_ASSIGN(NullMediaLog); +}; + } // namespace media #endif // MEDIA_BASE_MEDIA_UTIL_H_
diff --git a/media/base/mime_util_internal.cc b/media/base/mime_util_internal.cc index 91bfc8a..a1bba5f 100644 --- a/media/base/mime_util_internal.cc +++ b/media/base/mime_util_internal.cc
@@ -5,6 +5,7 @@ #include "media/base/mime_util_internal.h" #include "base/command_line.h" +#include "base/no_destructor.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" @@ -31,53 +32,58 @@ // Wrapped to avoid static initializer startup cost. const base::flat_map<std::string, MimeUtil::Codec>& GetStringToCodecMap() { - static const base::flat_map<std::string, MimeUtil::Codec> kStringToCodecMap( - { - // We only allow this for WAV so it isn't ambiguous. - {"1", MimeUtil::PCM}, - // avc1/avc3.XXXXXX may be unambiguous; handled by - // ParseAVCCodecId(). hev1/hvc1.XXXXXX may be unambiguous; handled - // by ParseHEVCCodecID(). vp9, vp9.0, vp09.xx.xx.xx.xx.xx.xx.xx may - // be unambiguous; handled by ParseVp9CodecID(). - {"mp3", MimeUtil::MP3}, - // Following is the list of RFC 6381 compliant audio codec strings: - // mp4a.66 - MPEG-2 AAC MAIN - // mp4a.67 - MPEG-2 AAC LC - // mp4a.68 - MPEG-2 AAC SSR - // mp4a.69 - MPEG-2 extension to MPEG-1 (MP3) - // mp4a.6B - MPEG-1 audio (MP3) - // mp4a.40.2 - MPEG-4 AAC LC - // mp4a.40.02 - MPEG-4 AAC LC (leading 0 in aud-oti for - // compatibility) mp4a.40.5 - MPEG-4 HE-AAC v1 (AAC LC + SBR) - // mp4a.40.05 - MPEG-4 HE-AAC v1 (AAC LC + SBR) (leading 0 in - // aud-oti - // for compatibility) - // mp4a.40.29 - MPEG-4 HE-AAC v2 (AAC LC + SBR + PS) - {"mp4a.66", MimeUtil::MPEG2_AAC}, {"mp4a.67", MimeUtil::MPEG2_AAC}, - {"mp4a.68", MimeUtil::MPEG2_AAC}, {"mp4a.69", MimeUtil::MP3}, - {"mp4a.6B", MimeUtil::MP3}, {"mp4a.40.2", MimeUtil::MPEG4_AAC}, - {"mp4a.40.02", MimeUtil::MPEG4_AAC}, - {"mp4a.40.5", MimeUtil::MPEG4_AAC}, - {"mp4a.40.05", MimeUtil::MPEG4_AAC}, - {"mp4a.40.29", MimeUtil::MPEG4_AAC}, + static const base::NoDestructor<base::flat_map<std::string, MimeUtil::Codec>> + kStringToCodecMap(base::flat_map<std::string, MimeUtil::Codec>( + { + // We only allow this for WAV so it isn't ambiguous. + {"1", MimeUtil::PCM}, + // avc1/avc3.XXXXXX may be unambiguous; handled by + // ParseAVCCodecId(). hev1/hvc1.XXXXXX may be unambiguous; + // handled by ParseHEVCCodecID(). vp9, vp9.0, + // vp09.xx.xx.xx.xx.xx.xx.xx may be unambiguous; handled by + // ParseVp9CodecID(). + {"mp3", MimeUtil::MP3}, + // Following is the list of RFC 6381 compliant audio codec + // strings: + // mp4a.66 - MPEG-2 AAC MAIN + // mp4a.67 - MPEG-2 AAC LC + // mp4a.68 - MPEG-2 AAC SSR + // mp4a.69 - MPEG-2 extension to MPEG-1 (MP3) + // mp4a.6B - MPEG-1 audio (MP3) + // mp4a.40.2 - MPEG-4 AAC LC + // mp4a.40.02 - MPEG-4 AAC LC (leading 0 in aud-oti for + // compatibility) + // mp4a.40.5 - MPEG-4 HE-AAC v1 (AAC LC + SBR) + // mp4a.40.05 - MPEG-4 HE-AAC v1 (AAC LC + SBR) (leading 0 + // in aud-oti for compatibility) + // mp4a.40.29 - MPEG-4 HE-AAC v2 (AAC LC + SBR + PS) + {"mp4a.66", MimeUtil::MPEG2_AAC}, + {"mp4a.67", MimeUtil::MPEG2_AAC}, + {"mp4a.68", MimeUtil::MPEG2_AAC}, {"mp4a.69", MimeUtil::MP3}, + {"mp4a.6B", MimeUtil::MP3}, {"mp4a.40.2", MimeUtil::MPEG4_AAC}, + {"mp4a.40.02", MimeUtil::MPEG4_AAC}, + {"mp4a.40.5", MimeUtil::MPEG4_AAC}, + {"mp4a.40.05", MimeUtil::MPEG4_AAC}, + {"mp4a.40.29", MimeUtil::MPEG4_AAC}, #if BUILDFLAG(ENABLE_AC3_EAC3_AUDIO_DEMUXING) - // TODO(servolk): Strictly speaking only mp4a.A5 and mp4a.A6 codec - // ids are valid according to RFC 6381 section 3.3, 3.4. Lower-case - // oti (mp4a.a5 and mp4a.a6) should be rejected. But we used to - // allow those in older versions of Chromecast firmware and some - // apps (notably MPL) depend on those codec types being supported, - // so they should be allowed for now (crbug.com/564960). - {"ac-3", MimeUtil::AC3}, {"mp4a.a5", MimeUtil::AC3}, - {"mp4a.A5", MimeUtil::AC3}, {"ec-3", MimeUtil::EAC3}, - {"mp4a.a6", MimeUtil::EAC3}, {"mp4a.A6", MimeUtil::EAC3}, + // TODO(servolk): Strictly speaking only mp4a.A5 and mp4a.A6 + // codec ids are valid according to RFC 6381 section 3.3, 3.4. + // Lower-case oti (mp4a.a5 and mp4a.a6) should be rejected. But + // we used to allow those in older versions of Chromecast + // firmware and some apps (notably MPL) depend on those codec + // types being supported, so they should be allowed for now + // (crbug.com/564960). + {"ac-3", MimeUtil::AC3}, {"mp4a.a5", MimeUtil::AC3}, + {"mp4a.A5", MimeUtil::AC3}, {"ec-3", MimeUtil::EAC3}, + {"mp4a.a6", MimeUtil::EAC3}, {"mp4a.A6", MimeUtil::EAC3}, #endif - {"vorbis", MimeUtil::VORBIS}, {"opus", MimeUtil::OPUS}, - {"flac", MimeUtil::FLAC}, {"vp8", MimeUtil::VP8}, - {"vp8.0", MimeUtil::VP8}, {"theora", MimeUtil::THEORA}, - }, - base::KEEP_FIRST_OF_DUPES); + {"vorbis", MimeUtil::VORBIS}, {"opus", MimeUtil::OPUS}, + {"flac", MimeUtil::FLAC}, {"vp8", MimeUtil::VP8}, + {"vp8.0", MimeUtil::VP8}, {"theora", MimeUtil::THEORA}, + }, + base::KEEP_FIRST_OF_DUPES)); - return kStringToCodecMap; + return *kStringToCodecMap; } static bool ParseVp9CodecID(const std::string& mime_type_lower_case,
diff --git a/media/filters/decoder_stream.cc b/media/filters/decoder_stream.cc index bd8d0c3..9fc3bac 100644 --- a/media/filters/decoder_stream.cc +++ b/media/filters/decoder_stream.cc
@@ -24,6 +24,40 @@ namespace media { +// Helper class for ensuring that Decode() traces are properly unique and closed +// if the Decode is aborted via a WeakPtr invalidation. We use the |this| +// pointer of the ScopedDecodeTrace object itself as the id. Since the callback +// owns the class it's guaranteed to be unique. +class ScopedDecodeTrace { + public: + ScopedDecodeTrace(const char* trace_name, const DecoderBuffer& buffer) + : trace_name_(trace_name) { + DCHECK(trace_name_); + TRACE_EVENT_ASYNC_BEGIN2( + "media", trace_name_, this, "is_key_frame", + !buffer.end_of_stream() && buffer.is_key_frame(), "timestamp_us", + !buffer.end_of_stream() ? buffer.timestamp().InMicroseconds() : 0); + } + + void EndTrace(DecodeStatus status) { + DCHECK(!closed_); + closed_ = true; + TRACE_EVENT_ASYNC_END1("media", trace_name_, this, "status", + GetDecodeStatusString(status)); + } + + ~ScopedDecodeTrace() { + if (!closed_) + EndTrace(DecodeStatus::ABORTED); + } + + private: + const char* trace_name_; + bool closed_ = false; + + DISALLOW_COPY_AND_ASSIGN(ScopedDecodeTrace); +}; + #define FUNCTION_DVLOG(level) \ DVLOG(level) << __func__ << "<" << GetStreamTypeString() << ">" @@ -446,25 +480,34 @@ DCHECK(!reset_cb_); DCHECK(buffer); + std::unique_ptr<ScopedDecodeTrace> trace_event; + + bool enable_decode_traces = false; + TRACE_EVENT_CATEGORY_GROUP_ENABLED("media", &enable_decode_traces); + if (enable_decode_traces) { + // Because multiple Decode() calls may be in flight, each call needs a + // unique trace event class to identify it. This scoped event is bound + // into the OnDecodeDone callback to ensure the trace is always closed. + trace_event = std::make_unique<ScopedDecodeTrace>( + GetDecodeTraceString<StreamType>(), *buffer); + } + traits_->OnDecode(*buffer); - int buffer_size = buffer->end_of_stream() ? 0 : buffer->data_size(); - - TRACE_EVENT_ASYNC_BEGIN2( - "media", GetDecodeTraceString<StreamType>(), this, "is_key_frame", - !buffer->end_of_stream() && buffer->is_key_frame(), "timestamp_us", - !buffer->end_of_stream() ? buffer->timestamp().InMicroseconds() : 0); - - if (buffer->end_of_stream()) + const bool is_eos = buffer->end_of_stream(); + if (is_eos) decoding_eos_ = true; else if (buffer->duration() != kNoTimestamp) duration_tracker_.AddSample(buffer->duration()); ++pending_decode_requests_; - decoder_->Decode(std::move(buffer), - base::BindRepeating(&DecoderStream<StreamType>::OnDecodeDone, - fallback_weak_factory_.GetWeakPtr(), - buffer_size, decoding_eos_)); + + const int buffer_size = is_eos ? 0 : buffer->data_size(); + decoder_->Decode( + std::move(buffer), + base::BindRepeating(&DecoderStream<StreamType>::OnDecodeDone, + fallback_weak_factory_.GetWeakPtr(), buffer_size, + decoding_eos_, base::Passed(&trace_event))); } template <DemuxerStream::Type StreamType> @@ -475,9 +518,11 @@ } template <DemuxerStream::Type StreamType> -void DecoderStream<StreamType>::OnDecodeDone(int buffer_size, - bool end_of_stream, - DecodeStatus status) { +void DecoderStream<StreamType>::OnDecodeDone( + int buffer_size, + bool end_of_stream, + std::unique_ptr<ScopedDecodeTrace> trace_event, + DecodeStatus status) { FUNCTION_DVLOG(3) << ": " << status; DCHECK(state_ == STATE_NORMAL || state_ == STATE_FLUSHING_DECODER || state_ == STATE_ERROR) @@ -485,8 +530,8 @@ DCHECK_GT(pending_decode_requests_, 0); --pending_decode_requests_; - - TRACE_EVENT_ASYNC_END0("media", GetDecodeTraceString<StreamType>(), this); + if (trace_event) + trace_event->EndTrace(status); if (end_of_stream) { DCHECK(!pending_decode_requests_);
diff --git a/media/filters/decoder_stream.h b/media/filters/decoder_stream.h index bf4a250..e641f0e8 100644 --- a/media/filters/decoder_stream.h +++ b/media/filters/decoder_stream.h
@@ -33,6 +33,7 @@ class CdmContext; class DecryptingDemuxerStream; +class ScopedDecodeTrace; // Wraps a DemuxerStream and a list of Decoders and provides decoded // output to its client (e.g. Audio/VideoRendererImpl). @@ -188,7 +189,10 @@ void FlushDecoder(); // Callback for Decoder::Decode(). - void OnDecodeDone(int buffer_size, bool end_of_stream, DecodeStatus status); + void OnDecodeDone(int buffer_size, + bool end_of_stream, + std::unique_ptr<ScopedDecodeTrace> trace_event, + DecodeStatus status); // Output callback passed to Decoder::Initialize(). void OnDecodeOutputReady(const scoped_refptr<Output>& output);
diff --git a/media/formats/mp2t/es_parser_mpeg1audio_fuzzer.cc b/media/formats/mp2t/es_parser_mpeg1audio_fuzzer.cc index 7883826..5f295820b6 100644 --- a/media/formats/mp2t/es_parser_mpeg1audio_fuzzer.cc +++ b/media/formats/mp2t/es_parser_mpeg1audio_fuzzer.cc
@@ -8,26 +8,15 @@ #include <memory> #include "base/bind.h" -#include "media/base/media_log.h" +#include "media/base/media_util.h" #include "media/formats/mp2t/es_parser_mpeg1audio.h" -class NullMediaLog : public media::MediaLog { - public: - NullMediaLog() {} - ~NullMediaLog() override {} - - void AddEventLocked(std::unique_ptr<media::MediaLogEvent> event) override {} - - private: - DISALLOW_COPY_AND_ASSIGN(NullMediaLog); -}; - static void NewAudioConfig(const media::AudioDecoderConfig& config) {} static void EmitBuffer(scoped_refptr<media::StreamParserBuffer> buffer) {} // Entry point for LibFuzzer. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - NullMediaLog media_log; + media::NullMediaLog media_log; media::mp2t::EsParserMpeg1Audio es_parser( base::Bind(&NewAudioConfig), base::Bind(&EmitBuffer), &media_log); if (es_parser.Parse(data, size, media::kNoTimestamp,
diff --git a/media/formats/mp4/mp4_box_reader_fuzzer.cc b/media/formats/mp4/mp4_box_reader_fuzzer.cc index 3e87354..30ae9eb 100644 --- a/media/formats/mp4/mp4_box_reader_fuzzer.cc +++ b/media/formats/mp4/mp4_box_reader_fuzzer.cc
@@ -8,24 +8,12 @@ #include <memory> #include "base/logging.h" -#include "base/macros.h" -#include "media/base/media_log.h" +#include "media/base/media_util.h" #include "media/formats/mp4/box_reader.h" -class NullMediaLog : public media::MediaLog { - public: - NullMediaLog() = default; - ~NullMediaLog() override = default; - - void AddEventLocked(std::unique_ptr<media::MediaLogEvent> event) override {} - - private: - DISALLOW_COPY_AND_ASSIGN(NullMediaLog); -}; - // Entry point for LibFuzzer. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - NullMediaLog media_log; + media::NullMediaLog media_log; std::unique_ptr<media::mp4::BoxReader> reader; if (media::mp4::BoxReader::ReadTopLevelBox(data, size, &media_log, &reader) == media::mp4::ParseResult::kOk) {
diff --git a/media/gpu/windows/d3d11_video_decoder.cc b/media/gpu/windows/d3d11_video_decoder.cc index 29e42f2..1894ca4 100644 --- a/media/gpu/windows/d3d11_video_decoder.cc +++ b/media/gpu/windows/d3d11_video_decoder.cc
@@ -587,6 +587,7 @@ for (auto& queue_pair : input_buffer_queue_) queue_pair.second.Run(DecodeStatus::DECODE_ERROR); + input_buffer_queue_.clear(); } void D3D11VideoDecoder::SetCreateDeviceCallbackForTesting(
diff --git a/net/BUILD.gn b/net/BUILD.gn index a4eb9bd..3a2683b 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -5873,13 +5873,13 @@ fuzzer_test("net_ntlm_ntlm_client_fuzzer") { sources = [ "ntlm/ntlm_client_fuzzer.cc", + "ntlm/ntlm_test_data.h", ] deps = [ ":net_fuzzer_test_support", ":test_support", "//base", "//net", - "//net:net_unittests", ] dict = "data/fuzzer_dictionaries/net_ntlm_ntlm_client_fuzzer.dict" seed_corpus = "data/fuzzer_data/ntlm_client_fuzzer/"
diff --git a/net/cert/ct_policy_status.h b/net/cert/ct_policy_status.h index eb167b61..c672697 100644 --- a/net/cert/ct_policy_status.h +++ b/net/cert/ct_policy_status.h
@@ -27,7 +27,7 @@ // Compliance details for the connection are not available, e.g. because a // resource was loaded from disk cache. CT_POLICY_COMPLIANCE_DETAILS_NOT_AVAILABLE = 4, - CT_POLICY_MAX + CT_POLICY_COUNT }; } // namespace ct
diff --git a/net/dns/mock_host_resolver.cc b/net/dns/mock_host_resolver.cc index a7200ae6..299e776 100644 --- a/net/dns/mock_host_resolver.cc +++ b/net/dns/mock_host_resolver.cc
@@ -284,7 +284,8 @@ next_request_id_++; int rv = ResolveFromIPLiteralOrCache( info.host_port_pair(), info.address_family(), info.host_resolver_flags(), - HostResolverSource::ANY, info.allow_cached_response(), addresses); + HostResolverSource::ANY, info.allow_cached_response(), addresses, + stale_info); return rv; }
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc index 415520e..951cad57 100644 --- a/net/http/http_network_session.cc +++ b/net/http/http_network_session.cc
@@ -128,6 +128,7 @@ quic_migrate_sessions_on_network_change_v2(false), quic_migrate_sessions_early_v2(false), quic_retry_on_alternate_network_before_handshake(false), + quic_race_stale_dns_on_connection(false), quic_go_away_on_path_degrading(false), quic_max_time_on_non_default_network( base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs)), @@ -220,6 +221,7 @@ params.quic_migrate_sessions_on_network_change_v2, params.quic_migrate_sessions_early_v2, params.quic_retry_on_alternate_network_before_handshake, + params.quic_race_stale_dns_on_connection, params.quic_go_away_on_path_degrading, params.quic_max_time_on_non_default_network, params.quic_max_migrations_to_non_default_network_on_write_error, @@ -383,6 +385,8 @@ params_.quic_migrate_sessions_early_v2); dict->SetBoolean("retry_on_alternate_network_before_handshake", params_.quic_retry_on_alternate_network_before_handshake); + dict->SetBoolean("race_stale_dns_on_connection", + params_.quic_race_stale_dns_on_connection); dict->SetBoolean("go_away_on_path_degrading", params_.quic_go_away_on_path_degrading); dict->SetInteger("max_time_on_non_default_network_seconds",
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h index c485d5f..fa0596f 100644 --- a/net/http/http_network_session.h +++ b/net/http/http_network_session.h
@@ -191,6 +191,9 @@ // If true, a new connection may be kicked off on an alternate network when // a connection fails on the default network before handshake is confirmed. bool quic_retry_on_alternate_network_before_handshake; + // If true, the quic stream factory may race connection from stale dns + // result with the original dns resolution + bool quic_race_stale_dns_on_connection; // If true, the quic session may mark itself as GOAWAY on path degrading. bool quic_go_away_on_path_degrading; // Maximum time the session could be on the non-default network before
diff --git a/net/http/http_proxy_client_socket_wrapper_unittest.cc b/net/http/http_proxy_client_socket_wrapper_unittest.cc index 25b0d767..18427b1 100644 --- a/net/http/http_proxy_client_socket_wrapper_unittest.cc +++ b/net/http/http_proxy_client_socket_wrapper_unittest.cc
@@ -137,6 +137,7 @@ /*migrate_sessions_on_network_change_v2=*/false, /*migrate_sessions_early_v2=*/false, /*retry_on_alternate_network_before_handshake=*/false, + /*race_stale_dns_on_connection=*/false, /*go_away_on_path_degrading=*/false, base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs), kMaxMigrationsToNonDefaultNetworkOnWriteError,
diff --git a/net/http/transport_security_state.cc b/net/http/transport_security_state.cc index 2dc46777..3f3db5c8 100644 --- a/net/http/transport_security_state.cc +++ b/net/http/transport_security_state.cc
@@ -501,7 +501,7 @@ if (IsDynamicExpectCTEnabled() && GetDynamicExpectCTState(hostname, &state)) { UMA_HISTOGRAM_ENUMERATION( "Net.ExpectCTHeader.PolicyComplianceOnConnectionSetup", - policy_compliance, ct::CTPolicyCompliance::CT_POLICY_MAX); + policy_compliance, ct::CTPolicyCompliance::CT_POLICY_COUNT); if (!complies && expect_ct_reporter_ && !state.report_uri.is_empty() && report_status == ENABLE_EXPECT_CT_REPORTS) { MaybeNotifyExpectCTFailed(host_port_pair, state.report_uri, state.expiry, @@ -1106,7 +1106,7 @@ return; UMA_HISTOGRAM_ENUMERATION( "Net.ExpectCTHeader.PolicyComplianceOnHeaderProcessing", - ssl_info.ct_policy_compliance, ct::CTPolicyCompliance::CT_POLICY_MAX); + ssl_info.ct_policy_compliance, ct::CTPolicyCompliance::CT_POLICY_COUNT); if (ssl_info.ct_policy_compliance != ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS) { // If an Expect-CT header is observed over a non-compliant connection, the
diff --git a/net/http/transport_security_state_static.json b/net/http/transport_security_state_static.json index 0f05999..be599a2b 100644 --- a/net/http/transport_security_state_static.json +++ b/net/http/transport_security_state_static.json
@@ -202,20 +202,16 @@ { "name": "yahoo", "static_spki_hashes": [ - "DigiCertAssuredIDRoot", - "DigiCertGlobalRoot", - "DigiCertGlobalRootG2", - "DigiCertGlobalRootG3", - "DigiCertTrustedRootG4", - "DigiCertEVRoot", - "VeriSignClass2_G2", - "VeriSignClass2_G3", - "VeriSignClass3_G3", - "VeriSignClass3_G4", - "VeriSignClass3_G5", - "VeriSignUniversal", - "YahooBackup1", - "YahooBackup2" + "DigiCertAssuredIDRoot", + "DigiCertGlobalRoot", + "DigiCertGlobalRootG2", + "DigiCertGlobalRootG3", + "DigiCertTrustedRootG4", + "DigiCertEVRoot", + "GlobalSignRootCA", + "GlobalSignRootCA_R3", + "YahooBackup1", + "YahooBackup2" ], "report_uri": "http://csp.yahoo.com/beacon/csp?src=yahoocom-hpkp-report-only" },
diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h index 002ba87..c22bf49 100644 --- a/net/log/net_log_event_type_list.h +++ b/net/log/net_log_event_type_list.h
@@ -1673,6 +1673,12 @@ // will be attempted soon. EVENT_TYPE(QUIC_STREAM_FACTORY_JOB_RETRY_ON_ALTERNATE_NETWORK) +// This event indicates that the stale host resolution has failed. +EVENT_TYPE(QUIC_STREAM_FACTORY_JOB_STALE_HOST_RESOLUTION_FAILED) + +// This event indicates that the stale host doesn't match with fresh host. +EVENT_TYPE(QUIC_STREAM_FACTORY_JOB_STALE_HOST_RESOLUTION_NO_MATCH) + // ------------------------------------------------------------------------ // quic::QuicSession // ------------------------------------------------------------------------
diff --git a/net/quic/crypto/proof_verifier_chromium.cc b/net/quic/crypto/proof_verifier_chromium.cc index f3c9753..9c3b42b9 100644 --- a/net/quic/crypto/proof_verifier_chromium.cc +++ b/net/quic/crypto/proof_verifier_chromium.cc
@@ -412,7 +412,7 @@ UMA_HISTOGRAM_ENUMERATION( "Net.CertificateTransparency.EVCompliance2.QUIC", verify_details_->ct_verify_result.policy_compliance, - ct::CTPolicyCompliance::CT_POLICY_MAX); + ct::CTPolicyCompliance::CT_POLICY_COUNT); } } @@ -422,7 +422,7 @@ UMA_HISTOGRAM_ENUMERATION( "Net.CertificateTransparency.ConnectionComplianceStatus2.QUIC", verify_details_->ct_verify_result.policy_compliance, - ct::CTPolicyCompliance::CT_POLICY_MAX); + ct::CTPolicyCompliance::CT_POLICY_COUNT); } int ct_result = OK; @@ -446,7 +446,7 @@ "Net.CertificateTransparency.CTRequiredConnectionComplianceStatus2." "QUIC", verify_details_->ct_verify_result.policy_compliance, - ct::CTPolicyCompliance::CT_POLICY_MAX); + ct::CTPolicyCompliance::CT_POLICY_COUNT); } } else { verify_details_->ct_verify_result.policy_compliance_required = false;
diff --git a/net/quic/quic_stream_factory.cc b/net/quic/quic_stream_factory.cc index 5018f92..b79cc201 100644 --- a/net/quic/quic_stream_factory.cc +++ b/net/quic/quic_stream_factory.cc
@@ -316,6 +316,7 @@ const QuicSessionAliasKey& key, bool was_alternative_service_recently_broken, bool retry_on_alternate_network_before_handshake, + bool race_stale_dns_on_connection, RequestPriority priority, int cert_verify_flags, const NetLogWithSource& net_log); @@ -330,6 +331,8 @@ int DoConnect(); int DoConnectComplete(int rv); int DoConfirmConnection(int rv); + int DoWaitForHostResolution(); + int DoValidateHost(); void OnResolveHostComplete(int rv); void OnConnectComplete(int rv); @@ -362,9 +365,7 @@ return stream_requests_; } - bool IsHostResolutionComplete() const { - return io_state_ == STATE_NONE || io_state_ >= STATE_CONNECT; - } + bool IsHostResolutionComplete() const { return host_resolution_finished_; } private: enum IoState { @@ -373,9 +374,21 @@ STATE_RESOLVE_HOST_COMPLETE, STATE_CONNECT, STATE_CONNECT_COMPLETE, + STATE_WAIT_FOR_HOST_RESOLUTION, + STATE_HOST_VALIDATION, STATE_CONFIRM_CONNECTION, }; + void CloseStaleHostConnection() { + if (session_) { + QuicChromiumClientSession* session = session_; + session_ = nullptr; + session->CloseSessionOnError( + ERR_ABORTED, quic::QUIC_CONNECTION_CANCELLED, + quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); + } + } + IoState io_state_; QuicStreamFactory* factory_; quic::QuicTransportVersion quic_version_; @@ -386,8 +399,10 @@ const int cert_verify_flags_; const bool was_alternative_service_recently_broken_; const bool retry_on_alternate_network_before_handshake_; + const bool race_stale_dns_on_connection_; const NetLogWithSource net_log_; int num_sent_client_hellos_; + bool dns_race_ongoing_; bool host_resolution_finished_; QuicChromiumClientSession* session_; // If connection migraiton is supported, |network_| denotes the network on @@ -396,6 +411,7 @@ CompletionOnceCallback host_resolution_callback_; CompletionOnceCallback callback_; AddressList address_list_; + AddressList stale_address_list_; base::TimeTicks dns_resolution_start_time_; base::TimeTicks dns_resolution_end_time_; std::set<QuicStreamRequest*> stream_requests_; @@ -410,6 +426,7 @@ const QuicSessionAliasKey& key, bool was_alternative_service_recently_broken, bool retry_on_alternate_network_before_handshake, + bool race_stale_dns_on_connection, RequestPriority priority, int cert_verify_flags, const NetLogWithSource& net_log) @@ -424,10 +441,12 @@ was_alternative_service_recently_broken), retry_on_alternate_network_before_handshake_( retry_on_alternate_network_before_handshake), + race_stale_dns_on_connection_(race_stale_dns_on_connection), net_log_( NetLogWithSource::Make(net_log.net_log(), NetLogSourceType::QUIC_STREAM_FACTORY_JOB)), num_sent_client_hellos_(0), + dns_race_ongoing_(false), host_resolution_finished_(false), session_(nullptr), network_(NetworkChangeNotifier::kInvalidNetworkHandle), @@ -479,6 +498,12 @@ case STATE_CONNECT_COMPLETE: rv = DoConnectComplete(rv); break; + case STATE_WAIT_FOR_HOST_RESOLUTION: + rv = DoWaitForHostResolution(); + break; + case STATE_HOST_VALIDATION: + rv = DoValidateHost(); + break; case STATE_CONFIRM_CONNECTION: rv = DoConfirmConnection(rv); break; @@ -491,7 +516,31 @@ } void QuicStreamFactory::Job::OnResolveHostComplete(int rv) { - DCHECK_EQ(STATE_RESOLVE_HOST_COMPLETE, io_state_); + host_resolution_finished_ = true; + if (!race_stale_dns_on_connection_) + DCHECK_EQ(STATE_RESOLVE_HOST_COMPLETE, io_state_); + + if (dns_race_ongoing_) { + if (rv != OK) { + CloseStaleHostConnection(); + dns_race_ongoing_ = false; + io_state_ = STATE_RESOLVE_HOST_COMPLETE; + } else if (factory_->HasMatchingIpSession(key_, address_list_)) { + // Session with resolved IP has already existed, so close racing + // connection, run callback, and return. + CloseStaleHostConnection(); + if (!callback_.is_null()) + base::ResetAndReturn(&callback_).Run(OK); + return; + } else if (io_state_ != STATE_HOST_VALIDATION) { + // Case where host resolution returns successfully, but stale connection + // hasn't finished yet. Host validation will be handled in + // DoValidateHost(). + // TODO(renjietang): In the future, we can also compare IPs here and if + // they don't match, we can close the stale connection early. + return; + } + } rv = DoLoop(rv); @@ -504,6 +553,11 @@ } void QuicStreamFactory::Job::OnConnectComplete(int rv) { + // This early return will be triggered when CloseSessionOnError is called + // before crypto handshake has completed. + if (!session_) + return; + rv = DoLoop(rv); if (rv != ERR_IO_PENDING && !callback_.is_null()) base::ResetAndReturn(&callback_).Run(rv); @@ -526,10 +580,26 @@ dns_resolution_start_time_ = base::TimeTicks::Now(); io_state_ = STATE_RESOLVE_HOST_COMPLETE; - return host_resolver_->Resolve( + + int rv = host_resolver_->Resolve( HostResolver::RequestInfo(key_.destination()), priority_, &address_list_, base::Bind(&QuicStreamFactory::Job::OnResolveHostComplete, GetWeakPtr()), &request_, net_log_); + + if (rv != ERR_IO_PENDING || !race_stale_dns_on_connection_) + return rv; + + HostCache::EntryStaleness stale_info; + if (host_resolver_->ResolveStaleFromCache( + HostResolver::RequestInfo(key_.destination()), &stale_address_list_, + &stale_info, net_log_) == OK) { + io_state_ = STATE_CONNECT; + dns_race_ongoing_ = true; + return OK; + } + net_log_.AddEvent( + NetLogEventType::QUIC_STREAM_FACTORY_JOB_STALE_HOST_RESOLUTION_FAILED); + return ERR_IO_PENDING; } int QuicStreamFactory::Job::DoResolveHostComplete(int rv) { @@ -538,6 +608,7 @@ if (rv != OK) return rv; + DCHECK(!dns_race_ongoing_); DCHECK(!factory_->HasActiveSession(key_.session_key())); // Inform the factory of this resolution, which will set up @@ -551,7 +622,6 @@ int QuicStreamFactory::Job::DoConnect() { io_state_ = STATE_CONNECT_COMPLETE; - bool require_confirmation = was_alternative_service_recently_broken_; net_log_.BeginEvent( NetLogEventType::QUIC_STREAM_FACTORY_JOB_CONNECT, @@ -560,8 +630,9 @@ DCHECK_NE(quic_version_, quic::QUIC_VERSION_UNSUPPORTED); int rv = factory_->CreateSession( key_, quic_version_, cert_verify_flags_, require_confirmation, - address_list_, dns_resolution_start_time_, dns_resolution_end_time_, - net_log_, &session_, &network_); + dns_race_ongoing_ ? stale_address_list_ : address_list_, + dns_resolution_start_time_, dns_resolution_end_time_, net_log_, &session_, + &network_); DVLOG(1) << "Created session on network: " << network_; if (rv != OK) { @@ -589,8 +660,56 @@ } int QuicStreamFactory::Job::DoConnectComplete(int rv) { - io_state_ = STATE_CONFIRM_CONNECTION; - return rv; + if (!dns_race_ongoing_) { + io_state_ = STATE_CONFIRM_CONNECTION; + return rv; + } + + if (rv == OK) { + io_state_ = STATE_WAIT_FOR_HOST_RESOLUTION; + return OK; + } + + // Connection from stale host resolution failed, has been closed and will + // be deleted soon. Update Job status accordingly. + dns_race_ongoing_ = false; + session_ = nullptr; + + if (address_list_.empty()) { + io_state_ = STATE_RESOLVE_HOST_COMPLETE; + return ERR_IO_PENDING; + } + // TODO(renjietang): Check if IP matches. If so, we don't need to try + // connecting with the bad IP again. + io_state_ = STATE_CONNECT; + return OK; +} + +int QuicStreamFactory::Job::DoWaitForHostResolution() { + io_state_ = STATE_HOST_VALIDATION; + if (address_list_.empty()) + return ERR_IO_PENDING; + return OK; +} + +// This state is reached iff both host resolution and connection from stale dns +// have finished successfully. +int QuicStreamFactory::Job::DoValidateHost() { + std::vector<net::IPEndPoint> endpoints = address_list_.endpoints(); + IPEndPoint stale_address = session_->peer_address().impl().socket_address(); + + if (std::find(endpoints.begin(), endpoints.end(), stale_address) != + endpoints.end()) { + io_state_ = STATE_CONFIRM_CONNECTION; + return OK; + } + + net_log_.AddEvent( + NetLogEventType::QUIC_STREAM_FACTORY_JOB_STALE_HOST_RESOLUTION_NO_MATCH); + dns_race_ongoing_ = false; + CloseStaleHostConnection(); + io_state_ = STATE_CONNECT; + return OK; } int QuicStreamFactory::Job::DoConfirmConnection(int rv) { @@ -781,6 +900,7 @@ bool migrate_sessions_on_network_change_v2, bool migrate_sessions_early_v2, bool retry_on_alternate_network_before_handshake, + bool race_stale_dns_on_connection, bool go_away_on_path_degrading, base::TimeDelta max_time_on_non_default_network, int max_migrations_to_non_default_network_on_write_error, @@ -839,6 +959,7 @@ retry_on_alternate_network_before_handshake_( retry_on_alternate_network_before_handshake && migrate_sessions_on_network_change_v2_), + race_stale_dns_on_connection_(race_stale_dns_on_connection), go_away_on_path_degrading_(go_away_on_path_degrading), default_network_(NetworkChangeNotifier::kInvalidNetworkHandle), max_time_on_non_default_network_(max_time_on_non_default_network), @@ -1093,11 +1214,11 @@ StartCertVerifyJob(session_key.server_id(), cert_verify_flags, net_log)); QuicSessionAliasKey key(destination, session_key); - std::unique_ptr<Job> job = - std::make_unique<Job>(this, quic_version, host_resolver_, key, - WasQuicRecentlyBroken(session_key.server_id()), - retry_on_alternate_network_before_handshake_, - priority, cert_verify_flags, net_log); + std::unique_ptr<Job> job = std::make_unique<Job>( + this, quic_version, host_resolver_, key, + WasQuicRecentlyBroken(session_key.server_id()), + retry_on_alternate_network_before_handshake_, + race_stale_dns_on_connection_, priority, cert_verify_flags, net_log); int rv = job->Run( base::BindRepeating(&QuicStreamFactory::OnJobComplete, base::Unretained(this), job.get()));
diff --git a/net/quic/quic_stream_factory.h b/net/quic/quic_stream_factory.h index a6667e9..1595fb6 100644 --- a/net/quic/quic_stream_factory.h +++ b/net/quic/quic_stream_factory.h
@@ -250,6 +250,7 @@ bool migrate_sessions_on_network_change_v2, bool migrate_sessions_early_v2, bool retry_on_alternate_network_before_handshake, + bool race_stale_dns_on_connection, bool go_away_on_path_degrading, base::TimeDelta max_time_on_non_default_network, int max_migrations_to_non_default_network_on_write_error, @@ -548,6 +549,10 @@ // connection fails on the default network before handshake is confirmed. const bool retry_on_alternate_network_before_handshake_; + // Set if stale DNS result may be speculatively used to connect and then + // compared with the original DNS result. + const bool race_stale_dns_on_connection_; + // Set if client should mark the session as GOAWAY when the connection // experiences poor connectivity const bool go_away_on_path_degrading_;
diff --git a/net/quic/quic_stream_factory_fuzzer.cc b/net/quic/quic_stream_factory_fuzzer.cc index b81ca077..1b1e7f8d 100644 --- a/net/quic/quic_stream_factory_fuzzer.cc +++ b/net/quic/quic_stream_factory_fuzzer.cc
@@ -104,6 +104,7 @@ bool enable_token_binding = data_provider.ConsumeBool(); bool enable_channel_id = data_provider.ConsumeBool(); bool enable_socket_recv_optimization = data_provider.ConsumeBool(); + bool race_stale_dns_on_connection = data_provider.ConsumeBool(); env->crypto_client_stream_factory.AddProofVerifyDetails(&env->verify_details); @@ -143,7 +144,7 @@ quic::kMaxTimeForCryptoHandshakeSecs, quic::kInitialIdleTimeoutSecs, migrate_sessions_on_network_change_v2, migrate_sessions_early_v2, retry_on_alternate_network_before_handshake, - go_away_on_path_degrading, + race_stale_dns_on_connection, go_away_on_path_degrading, base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs), kMaxMigrationsToNonDefaultNetworkOnWriteError, kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
diff --git a/net/quic/quic_stream_factory_peer.cc b/net/quic/quic_stream_factory_peer.cc index efbb473..3b16743 100644 --- a/net/quic/quic_stream_factory_peer.cc +++ b/net/quic/quic_stream_factory_peer.cc
@@ -70,6 +70,22 @@ return factory->active_sessions_[session_key]; } +bool QuicStreamFactoryPeer::HasLiveSession( + QuicStreamFactory* factory, + const HostPortPair& destination, + const quic::QuicServerId& server_id) { + QuicSessionKey session_key = QuicSessionKey(server_id, SocketTag()); + QuicStreamFactory::QuicSessionAliasKey alias_key = + QuicStreamFactory::QuicSessionAliasKey(destination, session_key); + for (QuicStreamFactory::SessionIdMap::iterator it = + factory->all_sessions_.begin(); + it != factory->all_sessions_.end(); ++it) { + if (it->second == alias_key) + return true; + } + return false; +} + bool QuicStreamFactoryPeer::IsLiveSession(QuicStreamFactory* factory, QuicChromiumClientSession* session) { for (QuicStreamFactory::SessionIdMap::iterator it =
diff --git a/net/quic/quic_stream_factory_peer.h b/net/quic/quic_stream_factory_peer.h index cebf703..89e625d 100644 --- a/net/quic/quic_stream_factory_peer.h +++ b/net/quic/quic_stream_factory_peer.h
@@ -56,6 +56,10 @@ QuicStreamFactory* factory, const quic::QuicServerId& server_id); + static bool HasLiveSession(QuicStreamFactory* factory, + const HostPortPair& destination, + const quic::QuicServerId& server_id); + static bool IsLiveSession(QuicStreamFactory* factory, QuicChromiumClientSession* session);
diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc index 0259777f..ece11002 100644 --- a/net/quic/quic_stream_factory_test.cc +++ b/net/quic/quic_stream_factory_test.cc
@@ -109,6 +109,8 @@ const int kDefaultRTTMilliSecs = 300; const size_t kMinRetryTimeForDefaultNetworkSecs = 1; const size_t kWaitTimeForNewNetworkSecs = 10; +const IPAddress kCachedIPAddress = IPAddress(192, 168, 0, 2); +const char kNonCachedIPAddress[] = "192.168.0.1"; // Run QuicStreamFactoryTest instances with all value combinations of version // and enable_connection_racting. @@ -217,7 +219,8 @@ protected: QuicStreamFactoryTestBase(quic::QuicTransportVersion version, bool client_headers_include_h2_stream_dependency) - : ssl_config_service_(new MockSSLConfigService), + : host_resolver_(new MockHostResolver), + ssl_config_service_(new MockSSLConfigService), socket_factory_(new MockClientSocketFactory), random_generator_(0), runner_(new TestTaskRunner(&clock_)), @@ -264,6 +267,7 @@ migrate_sessions_on_network_change_v2_(false), migrate_sessions_early_v2_(false), retry_on_alternate_network_before_handshake_(false), + race_stale_dns_on_connection_(false), go_away_on_path_degrading_(false), allow_server_migration_(false), race_cert_verification_(false), @@ -274,7 +278,7 @@ void Initialize() { DCHECK(!factory_); factory_.reset(new QuicStreamFactory( - net_log_.net_log(), &host_resolver_, ssl_config_service_.get(), + net_log_.net_log(), host_resolver_.get(), ssl_config_service_.get(), socket_factory_.get(), &http_server_properties_, cert_verifier_.get(), &ct_policy_enforcer_, channel_id_service_.get(), &transport_security_state_, cert_transparency_verifier_.get(), @@ -289,7 +293,7 @@ max_idle_time_before_crypto_handshake_seconds_, migrate_sessions_on_network_change_v2_, migrate_sessions_early_v2_, retry_on_alternate_network_before_handshake_, - go_away_on_path_degrading_, + race_stale_dns_on_connection_, go_away_on_path_degrading_, base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs), kMaxMigrationsToNonDefaultNetworkOnWriteError, kMaxMigrationsToNonDefaultNetworkOnPathDegrading, @@ -330,6 +334,13 @@ return QuicStreamFactoryPeer::HasActiveSession(factory_.get(), server_id); } + bool HasLiveSession(const HostPortPair& host_port_pair) { + quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(), + false); + return QuicStreamFactoryPeer::HasLiveSession(factory_.get(), host_port_pair, + server_id); + } + bool HasActiveJob(const HostPortPair& host_port_pair, const PrivacyMode privacy_mode) { quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(), @@ -716,8 +727,8 @@ ++quic_server_info_map_it; EXPECT_EQ(quic_server_info_map_it->first, quic_server_id); - host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), - "192.168.0.1", ""); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + "192.168.0.1", ""); // Create a session and verify that the cached state is loaded. MockQuicData socket_data; @@ -756,8 +767,8 @@ socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); socket_data2.AddSocketDataToFactory(socket_factory_.get()); - host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), - "192.168.0.2", ""); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + "192.168.0.2", ""); QuicStreamRequest request2(factory_.get()); EXPECT_EQ(ERR_IO_PENDING, @@ -829,7 +840,7 @@ quic::QuicErrorCode error); QuicFlagSaver flags_; // Save/restore all QUIC flag values. - MockHostResolver host_resolver_; + std::unique_ptr<MockHostResolverBase> host_resolver_; std::unique_ptr<SSLConfigService> ssl_config_service_; std::unique_ptr<MockClientSocketFactory> socket_factory_; MockCryptoClientStreamFactory crypto_client_stream_factory_; @@ -873,6 +884,7 @@ bool migrate_sessions_on_network_change_v2_; bool migrate_sessions_early_v2_; bool retry_on_alternate_network_before_handshake_; + bool race_stale_dns_on_connection_; bool go_away_on_path_degrading_; bool allow_server_migration_; bool race_cert_verification_; @@ -916,7 +928,7 @@ std::unique_ptr<HttpStream> stream = CreateStream(&request); EXPECT_TRUE(stream.get()); - EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_.last_request_priority()); + EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->last_request_priority()); QuicStreamRequest request2(factory_.get()); EXPECT_EQ(OK, request2.Request(host_port_pair_, version_, privacy_mode_, @@ -958,9 +970,9 @@ crypto_client_stream_factory_.set_handshake_mode( MockCryptoClientStream::ZERO_RTT); - host_resolver_.set_synchronous_mode(true); - host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), - "192.168.0.1", ""); + host_resolver_->set_synchronous_mode(true); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + "192.168.0.1", ""); QuicStreamRequest request(factory_.get()); EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_, @@ -1031,9 +1043,9 @@ TEST_P(QuicStreamFactoryTest, RequireConfirmation) { crypto_client_stream_factory_.set_handshake_mode( MockCryptoClientStream::ZERO_RTT); - host_resolver_.set_synchronous_mode(true); - host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), - "192.168.0.1", ""); + host_resolver_->set_synchronous_mode(true); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + "192.168.0.1", ""); Initialize(); factory_->set_require_confirmation(true); ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); @@ -1071,9 +1083,9 @@ TEST_P(QuicStreamFactoryTest, DontRequireConfirmationFromSameIP) { crypto_client_stream_factory_.set_handshake_mode( MockCryptoClientStream::ZERO_RTT); - host_resolver_.set_synchronous_mode(true); - host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), - "192.168.0.1", ""); + host_resolver_->set_synchronous_mode(true); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + "192.168.0.1", ""); Initialize(); factory_->set_require_confirmation(true); http_server_properties_.SetSupportsQuic(IPAddress(192, 0, 2, 33)); @@ -1293,10 +1305,10 @@ socket_data.AddSocketDataToFactory(socket_factory_.get()); HostPortPair server2(kServer2HostName, kDefaultServerPort); - host_resolver_.set_synchronous_mode(true); - host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), - "192.168.0.1", ""); - host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", ""); + host_resolver_->set_synchronous_mode(true); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + "192.168.0.1", ""); + host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", ""); QuicStreamRequest request(factory_.get()); EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_, @@ -1326,8 +1338,8 @@ TEST_P(QuicStreamFactoryTest, PoolingWithServerMigration) { // Set up session to migrate. - host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), - "192.168.0.1", ""); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + "192.168.0.1", ""); IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 443); quic::QuicConfig config; config.SetAlternateServerAddressToSend( @@ -1342,7 +1354,7 @@ // Set up server IP, socket, proof, and config for new session. HostPortPair server2(kServer2HostName, kDefaultServerPort); - host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", ""); + host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", ""); MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)}; std::unique_ptr<quic::QuicEncryptedPacket> settings_packet( @@ -1391,10 +1403,10 @@ socket_data2.AddSocketDataToFactory(socket_factory_.get()); HostPortPair server2(kServer2HostName, kDefaultServerPort); - host_resolver_.set_synchronous_mode(true); - host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), - "192.168.0.1", ""); - host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", ""); + host_resolver_->set_synchronous_mode(true); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + "192.168.0.1", ""); + host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", ""); QuicStreamRequest request(factory_.get()); EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_, @@ -1452,9 +1464,9 @@ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); - host_resolver_.set_synchronous_mode(true); - host_resolver_.rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", ""); - host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", ""); + host_resolver_->set_synchronous_mode(true); + host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", ""); + host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", ""); QuicStreamRequest request(factory_.get()); EXPECT_EQ(OK, @@ -1500,9 +1512,9 @@ test::GetTestHashValue(primary_pin)); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); - host_resolver_.set_synchronous_mode(true); - host_resolver_.rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", ""); - host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", ""); + host_resolver_->set_synchronous_mode(true); + host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", ""); + host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", ""); QuicStreamRequest request(factory_.get()); EXPECT_EQ(OK, @@ -1559,9 +1571,9 @@ test::GetTestHashValue(primary_pin)); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2); - host_resolver_.set_synchronous_mode(true); - host_resolver_.rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", ""); - host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", ""); + host_resolver_->set_synchronous_mode(true); + host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", ""); + host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", ""); QuicStreamRequest request(factory_.get()); EXPECT_EQ(OK, @@ -1732,7 +1744,7 @@ MockQuicData socket_data; socket_data.AddSocketDataToFactory(socket_factory_.get()); - host_resolver_.rules()->AddSimulatedFailure(kDefaultServerHostName); + host_resolver_->rules()->AddSimulatedFailure(kDefaultServerHostName); QuicStreamRequest request(factory_.get()); EXPECT_EQ(ERR_IO_PENDING, @@ -1940,9 +1952,9 @@ // Use unmocked crypto stream to do crypto connect. crypto_client_stream_factory_.set_handshake_mode( MockCryptoClientStream::COLD_START_WITH_CHLO_SENT); - host_resolver_.set_synchronous_mode(true); - host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), - "192.168.0.1", ""); + host_resolver_->set_synchronous_mode(true); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + "192.168.0.1", ""); MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); @@ -4172,9 +4184,9 @@ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); - host_resolver_.set_synchronous_mode(true); - host_resolver_.rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", ""); - host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.2", ""); + host_resolver_->set_synchronous_mode(true); + host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", ""); + host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.2", ""); // Create request and QuicHttpStream to create session1. QuicStreamRequest request1(factory_.get()); @@ -7191,8 +7203,8 @@ TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv6) { // Add a resolver rule to make initial connection to an IPv6 address. - host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), - "fe80::aebc:32ff:febb:1e33", ""); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + "fe80::aebc:32ff:febb:1e33", ""); // Add alternate IPv6 server address to config. IPEndPoint alt_address = IPEndPoint( IPAddress(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 123); @@ -7204,8 +7216,8 @@ TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv4) { // Add a resolver rule to make initial connection to an IPv6 address. - host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), - "fe80::aebc:32ff:febb:1e33", ""); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + "fe80::aebc:32ff:febb:1e33", ""); // Add alternate IPv4 server address to config. IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 123); quic::QuicConfig config; @@ -7221,8 +7233,8 @@ Initialize(); // Add a resolver rule to make initial connection to an IPv4 address. - host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), "1.2.3.4", - ""); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), "1.2.3.4", + ""); // Add alternate IPv6 server address to config. IPEndPoint alt_address = IPEndPoint( IPAddress(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 123); @@ -7508,9 +7520,9 @@ crypto_client_stream_factory_.set_handshake_mode( MockCryptoClientStream::ZERO_RTT); - host_resolver_.set_synchronous_mode(true); - host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), - "192.168.0.1", ""); + host_resolver_->set_synchronous_mode(true); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + "192.168.0.1", ""); QuicStreamRequest request(factory_.get()); EXPECT_EQ(OK, request.Request(host_port_pair_, version_, privacy_mode_, @@ -7554,10 +7566,10 @@ crypto_client_stream_factory_.set_handshake_mode( MockCryptoClientStream::CONFIRM_HANDSHAKE); - host_resolver_.set_synchronous_mode(true); - host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), - "192.168.0.1", ""); - host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", ""); + host_resolver_->set_synchronous_mode(true); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + "192.168.0.1", ""); + host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", ""); // Quic should use default PING timeout when no previous connection times out // with open stream. @@ -7711,9 +7723,9 @@ crypto_client_stream_factory_.set_handshake_mode( MockCryptoClientStream::ZERO_RTT); - host_resolver_.set_synchronous_mode(true); - host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), - "192.168.0.1", ""); + host_resolver_->set_synchronous_mode(true); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + "192.168.0.1", ""); // Set up the TaskObserver to verify QuicChromiumPacketReader::StartReading // posts a task. @@ -7760,9 +7772,9 @@ crypto_client_stream_factory_.set_handshake_mode( MockCryptoClientStream::ZERO_RTT); - host_resolver_.set_synchronous_mode(true); - host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(), - "192.168.0.1", ""); + host_resolver_->set_synchronous_mode(true); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + "192.168.0.1", ""); // Set up the TaskObserver to verify QuicChromiumPacketReader::StartReading // posts a task. @@ -8390,7 +8402,7 @@ std::unique_ptr<HttpStream> stream = CreateStream(&request); EXPECT_TRUE(stream.get()); - EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_.last_request_priority()); + EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_->last_request_priority()); EXPECT_TRUE(socket_data.AllReadDataConsumed()); EXPECT_TRUE(socket_data.AllWriteDataConsumed()); @@ -8420,7 +8432,7 @@ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); - host_resolver_.set_ondemand_mode(true); + host_resolver_->set_ondemand_mode(true); MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_FAILED); @@ -8449,7 +8461,7 @@ // ERR_FAILED from socket reads/writes), |host_resolution_callback| should be // called with ERR_QUIC_PROTOCOL_ERROR since that's the next result in // forming the connection. - host_resolver_.ResolveAllPending(); + host_resolver_->ResolveAllPending(); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(host_resolution_callback.have_result()); EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, host_resolution_callback.WaitForResult()); @@ -8470,7 +8482,7 @@ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); - host_resolver_.set_ondemand_mode(true); + host_resolver_->set_ondemand_mode(true); crypto_client_stream_factory_.set_handshake_mode( MockCryptoClientStream::ZERO_RTT); factory_->set_require_confirmation(true); @@ -8501,7 +8513,7 @@ // Allow |host_resolver_| to finish host resolution. Since crypto handshake // will hang after host resolution, |host_resolution_callback| should run with // ERR_IO_PENDING since that's the next result in forming the connection. - host_resolver_.ResolveAllPending(); + host_resolver_->ResolveAllPending(); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(host_resolution_callback.have_result()); EXPECT_EQ(ERR_IO_PENDING, host_resolution_callback.WaitForResult()); @@ -8525,7 +8537,7 @@ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); - host_resolver_.set_synchronous_mode(true); + host_resolver_->set_synchronous_mode(true); MockQuicData socket_data; socket_data.AddRead(SYNCHRONOUS, ERR_FAILED); @@ -8559,7 +8571,7 @@ // Host resolution will succeed synchronously, but Request() as a whole // will fail asynchronously. - host_resolver_.set_synchronous_mode(true); + host_resolver_->set_synchronous_mode(true); crypto_client_stream_factory_.set_handshake_mode( MockCryptoClientStream::ZERO_RTT); factory_->set_require_confirmation(true); @@ -8601,8 +8613,8 @@ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); // Host resolution will fail synchronously. - host_resolver_.rules()->AddSimulatedFailure(host_port_pair_.host()); - host_resolver_.set_synchronous_mode(true); + host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host()); + host_resolver_->set_synchronous_mode(true); QuicStreamRequest request(factory_.get()); EXPECT_EQ(ERR_NAME_NOT_RESOLVED, @@ -8628,7 +8640,7 @@ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); - host_resolver_.rules()->AddSimulatedFailure(host_port_pair_.host()); + host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host()); QuicStreamRequest request(factory_.get()); EXPECT_EQ(ERR_IO_PENDING, @@ -8653,6 +8665,1007 @@ EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult()); } +// With dns race experiment turned on, and DNS resolve succeeds synchronously, +// the final connection is established through the resolved DNS. No racing +// connection. +TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceAndHostResolutionSync) { + race_stale_dns_on_connection_ = true; + host_resolver_ = std::make_unique<MockCachingHostResolver>(); + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + // Set an address in resolver for synchronous return. + host_resolver_->set_synchronous_mode(true); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + kNonCachedIPAddress, ""); + + // Set up a different address in stale resolver cache. + HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0); + HostCache::Entry entry(OK, + AddressList::CreateFromIPAddress(kCachedIPAddress, 0), + HostCache::Entry::SOURCE_DNS); + base::TimeDelta zero; + HostCache* cache = host_resolver_->GetHostCache(); + cache->Set(key, entry, base::TimeTicks::Now(), zero); + // Expire the cache + cache->OnNetworkChange(); + MockQuicData quic_data; + quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket()); + quic_data.AddSocketDataToFactory(socket_factory_.get()); + + QuicStreamRequest request(factory_.get()); + EXPECT_THAT(request.Request( + host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, + SocketTag(), + /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_, + failed_on_default_network_callback_, callback_.callback()), + IsOk()); + std::unique_ptr<HttpStream> stream = CreateStream(&request); + EXPECT_TRUE(stream.get()); + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_); + EXPECT_EQ( + session->peer_address().impl().socket_address().ToStringWithoutPort(), + kNonCachedIPAddress); + + EXPECT_TRUE(quic_data.AllReadDataConsumed()); + EXPECT_TRUE(quic_data.AllWriteDataConsumed()); +} + +// With dns race experiment on, DNS resolve returns async, no matching cache in +// host resolver, connection should be successful and through resolved DNS. No +// racing connection. +TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceAndHostResolutionAsync) { + race_stale_dns_on_connection_ = true; + host_resolver_ = std::make_unique<MockCachingHostResolver>(); + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + // Set an address in resolver for asynchronous return. + host_resolver_->set_ondemand_mode(true); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + kNonCachedIPAddress, ""); + + MockQuicData quic_data; + quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket()); + quic_data.AddSocketDataToFactory(socket_factory_.get()); + + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request( + host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, + SocketTag(), + /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_, + failed_on_default_network_callback_, callback_.callback())); + TestCompletionCallback host_resolution_callback; + EXPECT_TRUE( + request.WaitForHostResolution(host_resolution_callback.callback())); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(host_resolution_callback.have_result()); + + // Cause the host resolution to return. + host_resolver_->ResolveAllPending(); + EXPECT_THAT(host_resolution_callback.WaitForResult(), IsOk()); + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + + std::unique_ptr<HttpStream> stream = CreateStream(&request); + EXPECT_TRUE(stream.get()); + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_); + + EXPECT_EQ( + session->peer_address().impl().socket_address().ToStringWithoutPort(), + kNonCachedIPAddress); + + EXPECT_TRUE(quic_data.AllReadDataConsumed()); + EXPECT_TRUE(quic_data.AllWriteDataConsumed()); +} + +// With dns race experiment on, DNS resolve returns async, stale dns used, +// connects synchrounously, and then the resolved DNS matches. +TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsyncStaleMatch) { + race_stale_dns_on_connection_ = true; + host_resolver_ = std::make_unique<MockCachingHostResolver>(); + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + // Set an address in resolver for asynchronous return. + host_resolver_->set_ondemand_mode(true); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + kCachedIPAddress.ToString(), ""); + + // Set up the same address in the stale resolver cache. + HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0); + HostCache::Entry entry(OK, + AddressList::CreateFromIPAddress(kCachedIPAddress, 0), + HostCache::Entry::SOURCE_DNS); + base::TimeDelta zero; + HostCache* cache = host_resolver_->GetHostCache(); + cache->Set(key, entry, base::TimeTicks::Now(), zero); + // Expire the cache + cache->OnNetworkChange(); + + MockQuicData quic_data; + quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket()); + quic_data.AddSocketDataToFactory(socket_factory_.get()); + + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request( + host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, + SocketTag(), + /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_, + failed_on_default_network_callback_, callback_.callback())); + + // Check that the racing job is running. + EXPECT_TRUE(HasLiveSession(host_port_pair_)); + EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_)); + + // Resolve dns and return. + host_resolver_->ResolveAllPending(); + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + std::unique_ptr<HttpStream> stream = CreateStream(&request); + EXPECT_TRUE(stream.get()); + + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_); + + EXPECT_EQ( + session->peer_address().impl().socket_address().ToStringWithoutPort(), + kCachedIPAddress.ToString()); + + EXPECT_TRUE(quic_data.AllReadDataConsumed()); + EXPECT_TRUE(quic_data.AllWriteDataConsumed()); +} + +// With dns race experiment on, dns resolve async, stale dns used, connect +// async, and then the result matches. +TEST_P(QuicStreamFactoryTest, + ResultAfterDNSRaceHostResolveAsyncConnectAsyncStaleMatch) { + race_stale_dns_on_connection_ = true; + host_resolver_ = std::make_unique<MockCachingHostResolver>(); + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + // Set an address in resolver for asynchronous return. + host_resolver_->set_ondemand_mode(true); + factory_->set_require_confirmation(true); + crypto_client_stream_factory_.set_handshake_mode( + MockCryptoClientStream::ZERO_RTT); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + kCachedIPAddress.ToString(), ""); + + // Set up the same address in the stale resolver cache. + HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0); + HostCache::Entry entry(OK, + AddressList::CreateFromIPAddress(kCachedIPAddress, 0), + HostCache::Entry::SOURCE_DNS); + base::TimeDelta zero; + HostCache* cache = host_resolver_->GetHostCache(); + cache->Set(key, entry, base::TimeTicks::Now(), zero); + // Expire the cache + cache->OnNetworkChange(); + + MockQuicData quic_data; + quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket()); + quic_data.AddSocketDataToFactory(socket_factory_.get()); + + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request( + host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, + SocketTag(), + /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_, + failed_on_default_network_callback_, callback_.callback())); + + // Send Crypto handshake so connect will call back. + crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( + quic::QuicSession::HANDSHAKE_CONFIRMED); + base::RunLoop().RunUntilIdle(); + + // Check that the racing job is running. + EXPECT_TRUE(HasLiveSession(host_port_pair_)); + EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_)); + + // Resolve dns and call back, make sure job finishes. + host_resolver_->ResolveAllPending(); + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + + std::unique_ptr<HttpStream> stream = CreateStream(&request); + EXPECT_TRUE(stream.get()); + + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_); + + EXPECT_EQ( + session->peer_address().impl().socket_address().ToStringWithoutPort(), + kCachedIPAddress.ToString()); + + EXPECT_TRUE(quic_data.AllReadDataConsumed()); + EXPECT_TRUE(quic_data.AllWriteDataConsumed()); +} + +// With dns race experiment on, dns resolve async, stale dns used, dns resolve +// return, then connection finishes and matches with the result. +TEST_P(QuicStreamFactoryTest, + ResultAfterDNSRaceHostResolveAsyncStaleMatchConnectAsync) { + race_stale_dns_on_connection_ = true; + host_resolver_ = std::make_unique<MockCachingHostResolver>(); + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + // Set an address in resolver for asynchronous return. + host_resolver_->set_ondemand_mode(true); + factory_->set_require_confirmation(true); + crypto_client_stream_factory_.set_handshake_mode( + MockCryptoClientStream::ZERO_RTT); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + kCachedIPAddress.ToString(), ""); + + // Set up the same address in the stale resolver cache. + HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0); + HostCache::Entry entry(OK, + AddressList::CreateFromIPAddress(kCachedIPAddress, 0), + HostCache::Entry::SOURCE_DNS); + base::TimeDelta zero; + HostCache* cache = host_resolver_->GetHostCache(); + cache->Set(key, entry, base::TimeTicks::Now(), zero); + // Expire the cache + cache->OnNetworkChange(); + + MockQuicData quic_data; + quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket()); + quic_data.AddSocketDataToFactory(socket_factory_.get()); + + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request( + host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, + SocketTag(), + /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_, + failed_on_default_network_callback_, callback_.callback())); + + // Finish dns async, check we still need to wait for stale connection async. + host_resolver_->ResolveAllPending(); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(callback_.have_result()); + + // Finish stale connection async, and the stale connection should pass dns + // validation. + crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( + quic::QuicSession::HANDSHAKE_CONFIRMED); + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + std::unique_ptr<HttpStream> stream = CreateStream(&request); + EXPECT_TRUE(stream.get()); + + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_); + EXPECT_EQ( + session->peer_address().impl().socket_address().ToStringWithoutPort(), + kCachedIPAddress.ToString()); + + EXPECT_TRUE(quic_data.AllReadDataConsumed()); + EXPECT_TRUE(quic_data.AllWriteDataConsumed()); +} + +// With dns race experiment on, dns resolve async, stale used and connects +// sync, but dns no match +TEST_P(QuicStreamFactoryTest, + ResultAfterDNSRaceHostResolveAsyncStaleSyncNoMatch) { + race_stale_dns_on_connection_ = true; + host_resolver_ = std::make_unique<MockCachingHostResolver>(); + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + // Set an address in resolver for asynchronous return. + host_resolver_->set_ondemand_mode(true); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + kNonCachedIPAddress, ""); + + // Set up a different address in the stale resolver cache. + HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0); + HostCache::Entry entry(OK, + AddressList::CreateFromIPAddress(kCachedIPAddress, 0), + HostCache::Entry::SOURCE_DNS); + base::TimeDelta zero; + HostCache* cache = host_resolver_->GetHostCache(); + cache->Set(key, entry, base::TimeTicks::Now(), zero); + // Expire the cache + cache->OnNetworkChange(); + + // Socket for the stale connection which will invoke connection closure. + MockQuicData quic_data; + quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket()); + quic_data.AddWrite( + SYNCHRONOUS, client_maker_.MakeConnectionClosePacket( + 2, true, quic::QUIC_CONNECTION_CANCELLED, "net error")); + quic_data.AddSocketDataToFactory(socket_factory_.get()); + + // Socket for the new connection. + MockQuicData quic_data2; + quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket()); + quic_data2.AddSocketDataToFactory(socket_factory_.get()); + + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request( + host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, + SocketTag(), + /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_, + failed_on_default_network_callback_, callback_.callback())); + + // Check the stale connection is running. + EXPECT_TRUE(HasLiveSession(host_port_pair_)); + EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_)); + + // Finish dns resolution and check the job has finished. + host_resolver_->ResolveAllPending(); + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + + std::unique_ptr<HttpStream> stream = CreateStream(&request); + EXPECT_TRUE(stream.get()); + + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_); + + EXPECT_EQ( + session->peer_address().impl().socket_address().ToStringWithoutPort(), + kNonCachedIPAddress); + + EXPECT_TRUE(quic_data.AllReadDataConsumed()); + EXPECT_TRUE(quic_data.AllWriteDataConsumed()); + EXPECT_TRUE(quic_data2.AllReadDataConsumed()); + EXPECT_TRUE(quic_data2.AllWriteDataConsumed()); +} + +// With dns race experiment on, dns resolve async, stale used and connects +// async, finishes before dns, but no match +TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleAsyncResolveAsyncNoMatch) { + race_stale_dns_on_connection_ = true; + host_resolver_ = std::make_unique<MockCachingHostResolver>(); + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + // Set an address in resolver for asynchronous return. + host_resolver_->set_ondemand_mode(true); + factory_->set_require_confirmation(true); + crypto_client_stream_factory_.set_handshake_mode( + MockCryptoClientStream::ZERO_RTT); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + kNonCachedIPAddress, ""); + + // Set up a different address in the stale resolvercache. + HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0); + HostCache::Entry entry(OK, + AddressList::CreateFromIPAddress(kCachedIPAddress, 0), + HostCache::Entry::SOURCE_DNS); + base::TimeDelta zero; + HostCache* cache = host_resolver_->GetHostCache(); + cache->Set(key, entry, base::TimeTicks::Now(), zero); + // Expire the cache + cache->OnNetworkChange(); + + MockQuicData quic_data; + quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket()); + quic_data.AddWrite( + SYNCHRONOUS, client_maker_.MakeConnectionClosePacket( + 2, true, quic::QUIC_CONNECTION_CANCELLED, "net error")); + quic_data.AddSocketDataToFactory(socket_factory_.get()); + + MockQuicData quic_data2; + quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data2.AddSocketDataToFactory(socket_factory_.get()); + + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request( + host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, + SocketTag(), + /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_, + failed_on_default_network_callback_, callback_.callback())); + + // Finish the stale connection. + crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( + quic::QuicSession::HANDSHAKE_CONFIRMED); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(HasLiveSession(host_port_pair_)); + EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_)); + + // Finish host resolution and check the job is done. + host_resolver_->ResolveAllPending(); + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + + std::unique_ptr<HttpStream> stream = CreateStream(&request); + EXPECT_TRUE(stream.get()); + + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_); + EXPECT_EQ( + session->peer_address().impl().socket_address().ToStringWithoutPort(), + kNonCachedIPAddress); + + EXPECT_TRUE(quic_data.AllReadDataConsumed()); + EXPECT_TRUE(quic_data.AllWriteDataConsumed()); + EXPECT_TRUE(quic_data2.AllReadDataConsumed()); + EXPECT_TRUE(quic_data2.AllWriteDataConsumed()); +} + +// With dns race experiment on, dns resolve async, stale used and connects +// async, dns finishes first, but no match +TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceResolveAsyncStaleAsyncNoMatch) { + race_stale_dns_on_connection_ = true; + host_resolver_ = std::make_unique<MockCachingHostResolver>(); + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + // Set an address in resolver for asynchronous return. + host_resolver_->set_ondemand_mode(true); + factory_->set_require_confirmation(true); + crypto_client_stream_factory_.set_handshake_mode( + MockCryptoClientStream::ZERO_RTT); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + kNonCachedIPAddress, ""); + + // Set up a different address in the stale resolver cache. + HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0); + HostCache::Entry entry(OK, + AddressList::CreateFromIPAddress(kCachedIPAddress, 0), + HostCache::Entry::SOURCE_DNS); + base::TimeDelta zero; + HostCache* cache = host_resolver_->GetHostCache(); + cache->Set(key, entry, base::TimeTicks::Now(), zero); + // Expire the cache + cache->OnNetworkChange(); + + MockQuicData quic_data; + quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket()); + quic_data.AddWrite( + SYNCHRONOUS, client_maker_.MakeConnectionClosePacket( + 2, true, quic::QUIC_CONNECTION_CANCELLED, "net error")); + quic_data.AddSocketDataToFactory(socket_factory_.get()); + + MockQuicData quic_data2; + quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data2.AddSocketDataToFactory(socket_factory_.get()); + + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request( + host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, + SocketTag(), + /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_, + failed_on_default_network_callback_, callback_.callback())); + // Finish dns resolution, but need to wait for stale connection. + host_resolver_->ResolveAllPending(); + EXPECT_FALSE(callback_.have_result()); + + // Finish stale connection and expect the job to be done. + crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( + quic::QuicSession::HANDSHAKE_CONFIRMED); + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + + std::unique_ptr<HttpStream> stream = CreateStream(&request); + EXPECT_TRUE(stream.get()); + + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_); + EXPECT_EQ( + session->peer_address().impl().socket_address().ToStringWithoutPort(), + kNonCachedIPAddress); + + EXPECT_TRUE(quic_data.AllReadDataConsumed()); + EXPECT_TRUE(quic_data.AllWriteDataConsumed()); + EXPECT_TRUE(quic_data2.AllReadDataConsumed()); + EXPECT_TRUE(quic_data2.AllWriteDataConsumed()); +} + +// With dns race experiment on, dns resolve returns error sync, same behavior +// as experiment is not on +TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveError) { + race_stale_dns_on_connection_ = true; + host_resolver_ = std::make_unique<MockCachingHostResolver>(); + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + // Set synchronous failure in resolver. + host_resolver_->set_synchronous_mode(true); + host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host()); + + MockQuicData quic_data; + quic_data.AddSocketDataToFactory(socket_factory_.get()); + QuicStreamRequest request(factory_.get()); + + EXPECT_EQ(ERR_NAME_NOT_RESOLVED, + request.Request( + host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, + SocketTag(), + /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_, + failed_on_default_network_callback_, callback_.callback())); +} + +// With dns race experiment on, no cache available, dns resolve returns error +// async +TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsyncError) { + race_stale_dns_on_connection_ = true; + host_resolver_ = std::make_unique<MockCachingHostResolver>(); + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + // Set asynchronous failure in resolver. + host_resolver_->set_ondemand_mode(true); + host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host()); + + MockQuicData quic_data; + quic_data.AddSocketDataToFactory(socket_factory_.get()); + QuicStreamRequest request(factory_.get()); + + EXPECT_EQ(ERR_IO_PENDING, + request.Request( + host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, + SocketTag(), + /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_, + failed_on_default_network_callback_, callback_.callback())); + + // Resolve and expect result that shows the resolution error. + host_resolver_->ResolveAllPending(); + EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED)); +} + +// With dns race experiment on, dns resolve async, staled used and connects +// sync, dns returns error and no connection is established. +TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleSyncHostResolveError) { + race_stale_dns_on_connection_ = true; + host_resolver_ = std::make_unique<MockCachingHostResolver>(); + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + // Set asynchronous failure in resolver. + host_resolver_->set_ondemand_mode(true); + host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host()); + + // Set up an address in the stale cache. + HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0); + HostCache::Entry entry(OK, + AddressList::CreateFromIPAddress(kCachedIPAddress, 0), + HostCache::Entry::SOURCE_DNS); + base::TimeDelta zero; + HostCache* cache = host_resolver_->GetHostCache(); + cache->Set(key, entry, base::TimeTicks::Now(), zero); + // Expire the cache + cache->OnNetworkChange(); + + // Socket for the stale connection which is supposed to disconnect. + MockQuicData quic_data; + quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket()); + quic_data.AddWrite( + SYNCHRONOUS, client_maker_.MakeConnectionClosePacket( + 2, true, quic::QUIC_CONNECTION_CANCELLED, "net error")); + quic_data.AddSocketDataToFactory(socket_factory_.get()); + + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request( + host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, + SocketTag(), + /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_, + failed_on_default_network_callback_, callback_.callback())); + + // Check that the stale connection is running. + EXPECT_TRUE(HasLiveSession(host_port_pair_)); + EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_)); + + // Finish host resolution. + host_resolver_->ResolveAllPending(); + EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED)); + + EXPECT_FALSE(HasLiveSession(host_port_pair_)); + + EXPECT_TRUE(quic_data.AllReadDataConsumed()); + EXPECT_TRUE(quic_data.AllWriteDataConsumed()); +} + +// With dns race experiment on, dns resolve async, stale used and connection +// return error, then dns matches +TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSMatches) { + race_stale_dns_on_connection_ = true; + host_resolver_ = std::make_unique<MockCachingHostResolver>(); + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + // Set an address in host resolver for asynchronous return. + host_resolver_->set_ondemand_mode(true); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + kCachedIPAddress.ToString(), ""); + + // Set up the same address in the stale resolver cache. + HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0); + HostCache::Entry entry(OK, + AddressList::CreateFromIPAddress(kCachedIPAddress, 0), + HostCache::Entry::SOURCE_DNS); + base::TimeDelta zero; + HostCache* cache = host_resolver_->GetHostCache(); + cache->Set(key, entry, base::TimeTicks::Now(), zero); + // Expire the cache + cache->OnNetworkChange(); + + // Simulate synchronous connect failure. + MockQuicData quic_data; + quic_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE); + quic_data.AddSocketDataToFactory(socket_factory_.get()); + + MockQuicData quic_data2; + quic_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE); + quic_data2.AddSocketDataToFactory(socket_factory_.get()); + + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request( + host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, + SocketTag(), + /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_, + failed_on_default_network_callback_, callback_.callback())); + EXPECT_FALSE(HasLiveSession(host_port_pair_)); + EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_)); + + host_resolver_->ResolveAllPending(); + EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE)); +} + +// With dns race experiment on, dns resolve async, stale used and connection +// returns error, dns no match, new connection is established +TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSNoMatch) { + race_stale_dns_on_connection_ = true; + host_resolver_ = std::make_unique<MockCachingHostResolver>(); + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + // Set an address in host resolver. + host_resolver_->set_ondemand_mode(true); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + kNonCachedIPAddress, ""); + + // Set up a different address in stale resolver cache. + HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0); + HostCache::Entry entry(OK, + AddressList::CreateFromIPAddress(kCachedIPAddress, 0), + HostCache::Entry::SOURCE_DNS); + base::TimeDelta zero; + HostCache* cache = host_resolver_->GetHostCache(); + cache->Set(key, entry, base::TimeTicks::Now(), zero); + // Expire the cache + cache->OnNetworkChange(); + + // Add failure for the stale connection. + MockQuicData quic_data; + quic_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE); + quic_data.AddSocketDataToFactory(socket_factory_.get()); + + MockQuicData quic_data2; + quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket()); + quic_data2.AddSocketDataToFactory(socket_factory_.get()); + + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request( + host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, + SocketTag(), + /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_, + failed_on_default_network_callback_, callback_.callback())); + + // Check that the stale connection fails. + EXPECT_FALSE(HasLiveSession(host_port_pair_)); + EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_)); + + // Finish host resolution and check the job finishes ok. + host_resolver_->ResolveAllPending(); + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + + std::unique_ptr<HttpStream> stream = CreateStream(&request); + EXPECT_TRUE(stream.get()); + + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_); + + EXPECT_EQ( + session->peer_address().impl().socket_address().ToStringWithoutPort(), + kNonCachedIPAddress); + + EXPECT_TRUE(quic_data2.AllReadDataConsumed()); + EXPECT_TRUE(quic_data2.AllWriteDataConsumed()); +} + +// With dns race experiment on, dns resolve async, stale used and connection +// returns error, dns no match, new connection error +TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSNoMatchError) { + race_stale_dns_on_connection_ = true; + host_resolver_ = std::make_unique<MockCachingHostResolver>(); + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + // Set an address in host resolver asynchronously. + host_resolver_->set_ondemand_mode(true); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + kNonCachedIPAddress, ""); + + // Set up a different address in the stale cache. + HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0); + HostCache::Entry entry(OK, + AddressList::CreateFromIPAddress(kCachedIPAddress, 0), + HostCache::Entry::SOURCE_DNS); + base::TimeDelta zero; + HostCache* cache = host_resolver_->GetHostCache(); + cache->Set(key, entry, base::TimeTicks::Now(), zero); + // Expire the cache + cache->OnNetworkChange(); + + // Add failure for stale connection. + MockQuicData quic_data; + quic_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE); + quic_data.AddSocketDataToFactory(socket_factory_.get()); + + // Add failure for resolved dns connection. + MockQuicData quic_data2; + quic_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE); + quic_data2.AddSocketDataToFactory(socket_factory_.get()); + + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request( + host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, + SocketTag(), + /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_, + failed_on_default_network_callback_, callback_.callback())); + + // Check the stale connection fails. + EXPECT_FALSE(HasLiveSession(host_port_pair_)); + EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_)); + + // Check the resolved dns connection fails. + host_resolver_->ResolveAllPending(); + EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE)); +} + +// With dns race experiment on, dns resolve async and stale connect async, dns +// resolve returns error and then preconnect finishes +TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceResolveAsyncErrorStaleAsync) { + race_stale_dns_on_connection_ = true; + host_resolver_ = std::make_unique<MockCachingHostResolver>(); + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + // Add asynchronous failure in host resolver. + host_resolver_->set_ondemand_mode(true); + host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host()); + factory_->set_require_confirmation(true); + crypto_client_stream_factory_.set_handshake_mode( + MockCryptoClientStream::ZERO_RTT); + + // Set up an address in stale resolver cache. + HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0); + HostCache::Entry entry(OK, + AddressList::CreateFromIPAddress(kCachedIPAddress, 0), + HostCache::Entry::SOURCE_DNS); + base::TimeDelta zero; + HostCache* cache = host_resolver_->GetHostCache(); + cache->Set(key, entry, base::TimeTicks::Now(), zero); + // Expire the cache + cache->OnNetworkChange(); + + // Socket data for stale connection which is supposed to disconnect. + MockQuicData quic_data; + quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL); + quic_data.AddWrite( + SYNCHRONOUS, client_maker_.MakeConnectionClosePacket( + 1, true, quic::QUIC_CONNECTION_CANCELLED, "net error")); + quic_data.AddSocketDataToFactory(socket_factory_.get()); + + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request( + host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, + SocketTag(), + /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_, + failed_on_default_network_callback_, callback_.callback())); + + // host resolution returned but stale connection hasn't finished yet. + host_resolver_->ResolveAllPending(); + EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED)); + + EXPECT_TRUE(quic_data.AllReadDataConsumed()); + EXPECT_TRUE(quic_data.AllWriteDataConsumed()); +} + +// With dns race experiment on, dns resolve async and stale connect async, dns +// resolve returns fine then preconnect fails +TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceResolveAsyncStaleAsyncError) { + race_stale_dns_on_connection_ = true; + host_resolver_ = std::make_unique<MockCachingHostResolver>(); + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + // Set asynchronous fresh address in host resolver. + host_resolver_->set_ondemand_mode(true); + factory_->set_require_confirmation(true); + crypto_client_stream_factory_.set_handshake_mode( + MockCryptoClientStream::ZERO_RTT); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + kNonCachedIPAddress, ""); + + // Set up an address in stale resolver cache. + HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0); + HostCache::Entry entry(OK, + AddressList::CreateFromIPAddress(kCachedIPAddress, 0), + HostCache::Entry::SOURCE_DNS); + base::TimeDelta zero; + HostCache* cache = host_resolver_->GetHostCache(); + cache->Set(key, entry, base::TimeTicks::Now(), zero); + // Expire the cache + cache->OnNetworkChange(); + + MockQuicData quic_data; + quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data.AddSocketDataToFactory(socket_factory_.get()); + + MockQuicData quic_data2; + quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket()); + quic_data2.AddSocketDataToFactory(socket_factory_.get()); + + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request( + host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, + SocketTag(), + /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_, + failed_on_default_network_callback_, callback_.callback())); + + // Host resolution finishes but stale connection is still running. + host_resolver_->ResolveAllPending(); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(callback_.have_result()); + + // Kill the session so that crypto connect will return error. + QuicChromiumClientSession* session = GetPendingSession(host_port_pair_); + session->CloseSessionOnError(ERR_ABORTED, quic::QUIC_INTERNAL_ERROR, + quic::ConnectionCloseBehavior::SILENT_CLOSE); + EXPECT_FALSE(callback_.have_result()); + + // Send crypto handshake for the new connection and check that it finishes. + crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( + quic::QuicSession::HANDSHAKE_CONFIRMED); + EXPECT_THAT(callback_.WaitForResult(), IsOk()); + + std::unique_ptr<HttpStream> stream = CreateStream(&request); + EXPECT_TRUE(stream.get()); + + QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_); + + EXPECT_EQ( + session2->peer_address().impl().socket_address().ToStringWithoutPort(), + kNonCachedIPAddress); + + EXPECT_TRUE(quic_data.AllReadDataConsumed()); + EXPECT_TRUE(quic_data.AllWriteDataConsumed()); + EXPECT_TRUE(quic_data2.AllReadDataConsumed()); + EXPECT_TRUE(quic_data2.AllWriteDataConsumed()); +} + +// With dns race experiment on, dns resolve async and stale connect async, dns +// resolve returns error and then preconnect fails. +TEST_P(QuicStreamFactoryTest, + ResultAfterDNSRaceResolveAsyncErrorStaleAsyncError) { + race_stale_dns_on_connection_ = true; + host_resolver_ = std::make_unique<MockCachingHostResolver>(); + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + // Add asynchronous failure to host resolver. + host_resolver_->set_ondemand_mode(true); + factory_->set_require_confirmation(true); + crypto_client_stream_factory_.set_handshake_mode( + MockCryptoClientStream::ZERO_RTT); + host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host()); + + // Set up an address in stale resolver cache. + HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0); + HostCache::Entry entry(OK, + AddressList::CreateFromIPAddress(kCachedIPAddress, 0), + HostCache::Entry::SOURCE_DNS); + base::TimeDelta zero; + HostCache* cache = host_resolver_->GetHostCache(); + cache->Set(key, entry, base::TimeTicks::Now(), zero); + // Expire the cache + cache->OnNetworkChange(); + + MockQuicData quic_data; + quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + client_maker_.SetEncryptionLevel(quic::ENCRYPTION_INITIAL); + quic_data.AddWrite( + SYNCHRONOUS, client_maker_.MakeConnectionClosePacket( + 1, true, quic::QUIC_CONNECTION_CANCELLED, "net error")); + quic_data.AddSocketDataToFactory(socket_factory_.get()); + + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request( + host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, + SocketTag(), + /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_, + failed_on_default_network_callback_, callback_.callback())); + + // Host Resolution returns failure but stale connection hasn't finished. + host_resolver_->ResolveAllPending(); + + // Check that the final error is on resolution failure. + EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED)); + + EXPECT_TRUE(quic_data.AllReadDataConsumed()); +} + +// With dns race experiment on, test that host resolution callback behaves +// normal as experiment is not on +TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsync) { + race_stale_dns_on_connection_ = true; + host_resolver_ = std::make_unique<MockCachingHostResolver>(); + Initialize(); + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails(); + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details); + + host_resolver_->set_ondemand_mode(true); + host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), + kNonCachedIPAddress, ""); + + MockQuicData quic_data; + quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); + quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket()); + quic_data.AddSocketDataToFactory(socket_factory_.get()); + + QuicStreamRequest request(factory_.get()); + EXPECT_EQ(ERR_IO_PENDING, + request.Request( + host_port_pair_, version_, privacy_mode_, DEFAULT_PRIORITY, + SocketTag(), + /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_, + failed_on_default_network_callback_, callback_.callback())); + + // Check that expect_on_host_resolution_ is properlly set. + TestCompletionCallback host_resolution_callback; + EXPECT_TRUE( + request.WaitForHostResolution(host_resolution_callback.callback())); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(host_resolution_callback.have_result()); + + host_resolver_->ResolveAllPending(); + EXPECT_THAT(host_resolution_callback.WaitForResult(), IsOk()); + + // Check that expect_on_host_resolution_ is flipped back. + EXPECT_FALSE( + request.WaitForHostResolution(host_resolution_callback.callback())); + + EXPECT_TRUE(quic_data.AllReadDataConsumed()); + EXPECT_TRUE(quic_data.AllWriteDataConsumed()); +} + // Test that QuicStreamRequests with similar and different tags results in // reused and unique QUIC streams using appropriately tagged sockets. TEST_P(QuicStreamFactoryTest, Tag) {
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc index 5af3913..bdcbf4b 100644 --- a/net/socket/ssl_client_socket_impl.cc +++ b/net/socket/ssl_client_socket_impl.cc
@@ -1547,7 +1547,7 @@ if (server_cert_verify_result_.is_issued_by_known_root) { UMA_HISTOGRAM_ENUMERATION("Net.CertificateTransparency.EVCompliance2.SSL", ct_verify_result_.policy_compliance, - ct::CTPolicyCompliance::CT_POLICY_MAX); + ct::CTPolicyCompliance::CT_POLICY_COUNT); } } @@ -1557,7 +1557,7 @@ UMA_HISTOGRAM_ENUMERATION( "Net.CertificateTransparency.ConnectionComplianceStatus2.SSL", ct_verify_result_.policy_compliance, - ct::CTPolicyCompliance::CT_POLICY_MAX); + ct::CTPolicyCompliance::CT_POLICY_COUNT); } TransportSecurityState::CTRequirementsStatus ct_requirement_status = @@ -1578,7 +1578,7 @@ "Net.CertificateTransparency.CTRequiredConnectionComplianceStatus2." "SSL", ct_verify_result_.policy_compliance, - ct::CTPolicyCompliance::CT_POLICY_MAX); + ct::CTPolicyCompliance::CT_POLICY_COUNT); } } else { ct_verify_result_.policy_compliance_required = false;
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index aee8755..729775e 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc
@@ -131,7 +131,7 @@ UMA_HISTOGRAM_ENUMERATION( "Net.CertificateTransparency.RequestComplianceStatus", ssl_info.ct_policy_compliance, - net::ct::CTPolicyCompliance::CT_POLICY_MAX); + net::ct::CTPolicyCompliance::CT_POLICY_COUNT); // Record the CT compliance of each request which was required to be CT // compliant. This gives a picture of the sites that are supposed to be // compliant and how well they do at actually being compliant. @@ -139,7 +139,7 @@ UMA_HISTOGRAM_ENUMERATION( "Net.CertificateTransparency.CTRequiredRequestComplianceStatus", ssl_info.ct_policy_compliance, - net::ct::CTPolicyCompliance::CT_POLICY_MAX); + net::ct::CTPolicyCompliance::CT_POLICY_COUNT); } }
diff --git a/printing/BUILD.gn b/printing/BUILD.gn index 8bea75d..83d6eec 100644 --- a/printing/BUILD.gn +++ b/printing/BUILD.gn
@@ -352,7 +352,6 @@ "android/java/src/org/chromium/printing/PrintManagerDelegateImpl.java", "android/java/src/org/chromium/printing/Printable.java", "android/java/src/org/chromium/printing/PrintingContext.java", - "android/java/src/org/chromium/printing/PrintingContextInterface.java", "android/java/src/org/chromium/printing/PrintingController.java", "android/java/src/org/chromium/printing/PrintingControllerImpl.java", ]
diff --git a/printing/android/java/src/org/chromium/printing/PrintingContext.java b/printing/android/java/src/org/chromium/printing/PrintingContext.java index ed878777..2cd855c 100644 --- a/printing/android/java/src/org/chromium/printing/PrintingContext.java +++ b/printing/android/java/src/org/chromium/printing/PrintingContext.java
@@ -4,9 +4,6 @@ package org.chromium.printing; -import android.print.PrintDocumentAdapter; -import android.util.SparseArray; - import org.chromium.base.Log; import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.CalledByNative; @@ -18,17 +15,8 @@ * to talk to the framework. */ @JNINamespace("printing") -public class PrintingContext implements PrintingContextInterface { - private static final String TAG = "cr.printing"; - /** - * Mapping from a file descriptor (as originally provided from - * {@link PrintDocumentAdapter#onWrite}) to a PrintingContext. - * - * This is static because a static method of the native code (inside PrintingContextAndroid) - * needs to find Java PrintingContext class corresponding to a file descriptor. - **/ - private static final SparseArray<PrintingContext> PRINTING_CONTEXT_MAP = - new SparseArray<PrintingContext>(); +public class PrintingContext { + private static final String TAG = "Printing"; /** The controller this object interacts with, which in turn communicates with the framework. */ private final PrintingController mController; @@ -41,22 +29,6 @@ mNativeObject = ptr; } - /** - * Updates PRINTING_CONTEXT_MAP to map from the file descriptor to this object. - * @param fileDescriptor The file descriptor passed down from - * {@link PrintDocumentAdapter#onWrite}. - * @param delete If true, delete the entry (if it exists). If false, add it to the map. - */ - @Override - public void updatePrintingContextMap(int fileDescriptor, boolean delete) { - ThreadUtils.assertOnUiThread(); - if (delete) { - PRINTING_CONTEXT_MAP.remove(fileDescriptor); - } else { - PRINTING_CONTEXT_MAP.put(fileDescriptor, this); - } - } - @CalledByNative public static PrintingContext create(long nativeObjectPointer) { ThreadUtils.assertOnUiThread(); @@ -91,7 +63,7 @@ @CalledByNative public void showPrintDialog() { ThreadUtils.assertOnUiThread(); - if (mController != null) { // The native side doesn't check if printing is enabled + if (mController != null) { // The native side doesn't check if printing is enabled mController.startPendingPrint(); } // Reply to native side with |CANCEL| since there is no printing settings available yet at @@ -100,16 +72,12 @@ } @CalledByNative - public static void pdfWritingDone(int fd, int pageCount) { + public static void pdfWritingDone(int pageCount) { ThreadUtils.assertOnUiThread(); - // TODO(cimamoglu): Do something when fd == -1. - if (PRINTING_CONTEXT_MAP.get(fd) != null) { - ThreadUtils.assertOnUiThread(); - PrintingContext printingContext = PRINTING_CONTEXT_MAP.get(fd); - printingContext.mController.pdfWritingDone(pageCount); - PRINTING_CONTEXT_MAP.remove(fd); + if (PrintingControllerImpl.getInstance() != null) { + PrintingControllerImpl.getInstance().pdfWritingDone(pageCount); } else { - Log.d(TAG, "No PrintingContext found for fd %d, can't notify print completion.", fd); + Log.d(TAG, "No PrintingController, can't notify print completion."); } } @@ -129,7 +97,6 @@ askUserForSettingsReply(false); } else { mController.setPrintingContext(this); - updatePrintingContextMap(mController.getFileDescriptor(), /* delete = */ false); askUserForSettingsReply(true); } }
diff --git a/printing/android/java/src/org/chromium/printing/PrintingContextInterface.java b/printing/android/java/src/org/chromium/printing/PrintingContextInterface.java deleted file mode 100644 index 4f6499f5..0000000 --- a/printing/android/java/src/org/chromium/printing/PrintingContextInterface.java +++ /dev/null
@@ -1,18 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.printing; - -/** - * Defines an interface for PrintingContext. - */ -public interface PrintingContextInterface { - /** - * Updates file descriptor to class instance mapping. - * @param fileDescriptor The file descriptor to which the current PrintingContext will be - * mapped. - * @param delete If true, delete the entry (if it exists). If false, add it to the map. - */ - void updatePrintingContextMap(int fileDescriptor, boolean delete); -}
diff --git a/printing/android/java/src/org/chromium/printing/PrintingController.java b/printing/android/java/src/org/chromium/printing/PrintingController.java index ab249d3..e760461 100644 --- a/printing/android/java/src/org/chromium/printing/PrintingController.java +++ b/printing/android/java/src/org/chromium/printing/PrintingController.java
@@ -68,7 +68,7 @@ * counterpart is created, and then the Java. PrintingController implementation * needs this to interact with the native side, since JNI is built on PrintingContext. **/ - void setPrintingContext(final PrintingContextInterface printingContext); + void setPrintingContext(final PrintingContext printingContext); /** * @return Whether a complete PDF generation cycle inside Chromium has been completed.
diff --git a/printing/android/java/src/org/chromium/printing/PrintingControllerImpl.java b/printing/android/java/src/org/chromium/printing/PrintingControllerImpl.java index 192f7482..6e4ac21 100644 --- a/printing/android/java/src/org/chromium/printing/PrintingControllerImpl.java +++ b/printing/android/java/src/org/chromium/printing/PrintingControllerImpl.java
@@ -49,13 +49,13 @@ private final String mErrorMessage; - private PrintingContextInterface mPrintingContext; + private PrintingContext mPrintingContext; private int mRenderProcessId; private int mRenderFrameId; /** The file descriptor into which the PDF will be written. Provided by the framework. */ - private int mFileDescriptor; + private ParcelFileDescriptor mFileDescriptor; /** Dots per inch, as provided by the framework. */ private int mDpi; @@ -143,7 +143,7 @@ @Override public int getFileDescriptor() { - return mFileDescriptor; + return mFileDescriptor.getFd(); } @Override @@ -167,7 +167,7 @@ } @Override - public void setPrintingContext(final PrintingContextInterface printingContext) { + public void setPrintingContext(final PrintingContext printingContext) { mPrintingContext = printingContext; } @@ -215,8 +215,7 @@ public void pdfWritingDone(int pageCount) { if (mPrintingState == PRINTING_STATE_FINISHED) return; mPrintingState = PRINTING_STATE_READY; - closeFileDescriptor(mFileDescriptor); - mFileDescriptor = -1; + closeFileDescriptor(); if (pageCount > 0) { PageRange[] pageRanges = convertIntegerArrayToPageRanges(mPages, pageCount); mOnWriteCallback.onWriteFinished(pageRanges); @@ -279,8 +278,14 @@ mOnWriteCallback = callback; assert mPrintingState == PRINTING_STATE_READY; - - mFileDescriptor = destination.getFd(); + assert mFileDescriptor == null; + try { + mFileDescriptor = destination.dup(); + } catch (IOException e) { + mOnWriteCallback.onWriteFailed("ParcelFileDescriptor.dup() failed: " + e.toString()); + resetCallbacks(); + return; + } mPages = convertPageRangesToIntegerArray(ranges); // mRenderProcessId and mRenderFrameId could be invalid values, in this case we are going to @@ -299,18 +304,14 @@ @Override public void onFinish() { mPages = null; - if (mPrintingContext != null) { - mPrintingContext.updatePrintingContextMap(mFileDescriptor, true); - mPrintingContext = null; - } + mPrintingContext = null; mRenderProcessId = -1; mRenderFrameId = -1; mPrintingState = PRINTING_STATE_FINISHED; - closeFileDescriptor(mFileDescriptor); - mFileDescriptor = -1; + closeFileDescriptor(); resetCallbacks(); // The printmanager contract is that onFinish() is always called as the last @@ -323,12 +324,14 @@ mOnLayoutCallback = null; } - private static void closeFileDescriptor(int fd) { - ParcelFileDescriptor fileDescriptor = ParcelFileDescriptor.adoptFd(fd); + private void closeFileDescriptor() { + if (mFileDescriptor == null) return; try { - fileDescriptor.close(); + mFileDescriptor.close(); } catch (IOException ioe) { /* ignore */ + } finally { + mFileDescriptor = null; } }
diff --git a/printing/printing_context_android.cc b/printing/printing_context_android.cc index e11a0da..1f07f49 100644 --- a/printing/printing_context_android.cc +++ b/printing/printing_context_android.cc
@@ -64,9 +64,9 @@ } // static -void PrintingContextAndroid::PdfWritingDone(int fd, int page_count) { +void PrintingContextAndroid::PdfWritingDone(int page_count) { JNIEnv* env = base::android::AttachCurrentThread(); - Java_PrintingContext_pdfWritingDone(env, fd, page_count); + Java_PrintingContext_pdfWritingDone(env, page_count); } PrintingContextAndroid::PrintingContextAndroid(Delegate* delegate)
diff --git a/printing/printing_context_android.h b/printing/printing_context_android.h index a6691f0..44157a9c 100644 --- a/printing/printing_context_android.h +++ b/printing/printing_context_android.h
@@ -22,9 +22,9 @@ // Called when the page is successfully written to a PDF using the file // descriptor specified, or when the printing operation failed. On success, - // the PDF written to |fd| has |page_count| pages. Non-positive |page_count| - // indicates failure. - static void PdfWritingDone(int fd, int page_count); + // the PDF has |page_count| pages. Non-positive |page_count| indicates + // failure. + static void PdfWritingDone(int page_count); // Called from Java, when printing settings from the user are ready or the // printing operation is canceled.
diff --git a/services/viz/privileged/interfaces/gl/gpu_service.mojom b/services/viz/privileged/interfaces/gl/gpu_service.mojom index 2188a90..ad15dbc2 100644 --- a/services/viz/privileged/interfaces/gl/gpu_service.mojom +++ b/services/viz/privileged/interfaces/gl/gpu_service.mojom
@@ -80,7 +80,8 @@ [EnableIf=is_win] RequestCompleteGpuInfo() => (gpu.mojom.DxDiagNode dx_diagnostics); [EnableIf=is_win] - GetGpuSupportedRuntimeVersion() => (gpu.mojom.GpuInfo gpu_info); + GetGpuSupportedRuntimeVersion() + => (gpu.mojom.Dx12VulkanVersionInfo dx12_vulkan_version_info); // Requests that the GPU process query system availability of HDR output and // return it.
diff --git a/testing/buildbot/filters/chromeos.single_process_mash.browser_tests.filter b/testing/buildbot/filters/chromeos.single_process_mash.browser_tests.filter index e31a8f2a..d829630 100644 --- a/testing/buildbot/filters/chromeos.single_process_mash.browser_tests.filter +++ b/testing/buildbot/filters/chromeos.single_process_mash.browser_tests.filter
@@ -172,18 +172,6 @@ # Default extension tests. -DefaultProfileExtensionBrowserTest.NoExtensionHosts -# Encrypted media tests are flaky due to race condition. crbug.com/880584 --ECKEncryptedMediaTest.* --EncryptedMediaTest.* --CDM_9/ECKEncryptedMediaTest.* --CDM_10/ECKEncryptedMediaTest.* --CDM_11/ECKEncryptedMediaTest.* --MSE_ClearKey/EncryptedMediaTest.* --MSE_ExternalClearKey/EncryptedMediaTest.* --MSE_Widevine/EncryptedMediaTest.* --SRC_ClearKey/EncryptedMediaTest.* --SRC_ExternalClearKey/EncryptedMediaTest.* - # Failing on ASAN bot. crbug.com/882631 -ExtensionWebRequestApiTest.WebRequestTypes @@ -204,12 +192,6 @@ -ManagedWithoutPermission/ManagedWithoutPermissionPlatformKeysTest.* -ManagedWithPermission/ManagedWithPermissionPlatformKeysTest.* -# Needs video surface layer support. Should be fixed when renderers don't use -# the window service for embedding. -# https://crbug.com/884589 https://crbug.com/881574 --MediaEngagementBrowserTest.* --MediaEngagementAutoplayBrowserTest.* - # Flaky https://crbug.com/887175 -PrerenderBrowserTest.PrerenderHTML5VideoJs
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/clip-rotate-opacity-fixed-expected.html b/third_party/WebKit/LayoutTests/compositing/overflow/clip-rotate-opacity-fixed-expected.html new file mode 100644 index 0000000..e8a7931 --- /dev/null +++ b/third_party/WebKit/LayoutTests/compositing/overflow/clip-rotate-opacity-fixed-expected.html
@@ -0,0 +1,3 @@ +<!DOCTYPE html> +Passes if no red. +<div style="width: 300px; height: 300px; background: green; outline: 1px solid green"></div>
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/clip-rotate-opacity-fixed.html b/third_party/WebKit/LayoutTests/compositing/overflow/clip-rotate-opacity-fixed.html new file mode 100644 index 0000000..6c0b757c --- /dev/null +++ b/third_party/WebKit/LayoutTests/compositing/overflow/clip-rotate-opacity-fixed.html
@@ -0,0 +1,10 @@ +<!DOCTYPE html> +Passes if no red. +<div style="width: 300px; height: 300px; background: green; outline: 1px solid green; position: absolute; z-index: 1"></div> +<div style="width: 300px; height: 300px; overflow: hidden"> + <div style="transform: rotate(45deg); width: 300px; height: 300px"> + <div style="opacity: 0.9"> + <div style="position: fixed; will-change: transform; width: 300px; height: 300px; background: red"></div> + </div> + </div> +</div>
diff --git a/third_party/WebKit/LayoutTests/custom-elements/v0-v1-interop.html b/third_party/WebKit/LayoutTests/custom-elements/v0-v1-interop.html index 0686094..fc153be1 100644 --- a/third_party/WebKit/LayoutTests/custom-elements/v0-v1-interop.html +++ b/third_party/WebKit/LayoutTests/custom-elements/v0-v1-interop.html
@@ -54,4 +54,28 @@ assert_true(w.document.createElement('div', 'b-b') instanceof w.HTMLDivElement, 'V0 createElement syntax does not work with V1 defined element'); }, 'V0 and V1 definition and createElement cannot be used together'); + +test_with_window((w) => { + const element = w.document.createElement('my-element'); + assert_true(element.matches(':unresolved'), 'Undefined element should be matched to :unresolved'); + assert_false(element.matches(':defined'), 'Undefined element should not be matched to :defined'); + + class MyElement extends w.HTMLElement {}; + w.document.registerElement('my-element', {prototype: MyElement.prototype}); + assert_true(element instanceof MyElement, 'Make sure V0-upgraded'); + assert_false(element.matches(':unresolved'), 'V0-defined element should not be matched to :unresolved'); + assert_true(element.matches(':defined'), 'V0-defined element should be matched to :defined'); + + const element1 = w.document.createElement('my-element1'); + w.customElements.define('my-element1', MyElement); + w.customElements.upgrade(element1); + assert_true(element1 instanceof MyElement, 'Make sure V1-upgraded'); + assert_false(element1.matches(':unresolved'), 'V1-defined element should not be matched to :unresolved'); + assert_true(element1.matches(':defined'), 'V1-defined element should be matched to :defined'); + + const builtin = w.document.createElement('span'); + assert_false(builtin.matches(':unresolved'), 'Built-in element should not be matched to :unresolved'); + assert_true(builtin.matches(':defined'), 'Built-in element should be matched to :defined'); + +}, ':unresolved and :defined work with both of V0 and V1 custom elements'); </script>
diff --git a/third_party/WebKit/LayoutTests/editing/execCommand/clipboard-access-with-userGesture-expected.txt b/third_party/WebKit/LayoutTests/editing/execCommand/clipboard-access-with-userGesture-expected.txt deleted file mode 100644 index 6093af3..0000000 --- a/third_party/WebKit/LayoutTests/editing/execCommand/clipboard-access-with-userGesture-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -To manually test, click one of the buttons below. The result should be two 'PASS' events for either button. - -Copy Cut -PASS successfullyParsed is true - -TEST COMPLETE -PASS document.execCommand('copy') is true -PASS copyEventSeen is true -PASS document.execCommand('cut') is true -PASS cutEventSeen is true -
diff --git a/third_party/WebKit/LayoutTests/editing/execCommand/clipboard-access-with-userGesture.html b/third_party/WebKit/LayoutTests/editing/execCommand/clipboard-access-with-userGesture.html index 125100f5..4fd9316 100644 --- a/third_party/WebKit/LayoutTests/editing/execCommand/clipboard-access-with-userGesture.html +++ b/third_party/WebKit/LayoutTests/editing/execCommand/clipboard-access-with-userGesture.html
@@ -1,17 +1,23 @@ <!DOCTYPE html> -<script src="../../resources/js-test.js"></script> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <script> var copyEventSeen; var cutEventSeen; function runTest() { - if (window.testRunner) - testRunner.setJavaScriptCanAccessClipboard(false); - else - return; - clickButton("copy"); - clickButton("cut"); + test(() => { + assert_exists(window, 'testRunner'); + testRunner.setJavaScriptCanAccessClipboard(false); + clickButton("copy"); + }, 'Copy'); + + test(() => { + assert_exists(window, 'testRunner'); + testRunner.setJavaScriptCanAccessClipboard(false); + clickButton("cut"); + }, 'Cut'); } function clickButton(id) @@ -25,15 +31,15 @@ function onClickCopy() { copyEventSeen = false; - shouldBeTrue("document.execCommand('copy')"); - shouldBeTrue("copyEventSeen"); + assert_true(document.execCommand('copy')); + assert_true(copyEventSeen); } function onClickCut() { cutEventSeend = false; - shouldBeTrue("document.execCommand('cut')"); - shouldBeTrue("cutEventSeen"); + assert_true(document.execCommand('cut')); + assert_true(cutEventSeen); } function onCopy() @@ -46,11 +52,13 @@ cutEventSeen = true; } </script> -<body onload="runTest()" oncopy="onCopy()" oncut="onCut()"> +<body oncopy="onCopy()" oncut="onCut()"> <p>To manually test, click one of the buttons below. The result should be two 'PASS' events for either button. <div> <button id="copy" onclick="onClickCopy()">Copy</button> <button id="cut" onclick="onClickCut()">Cut</button> </div> -<div id="console"></div> +<script> +runTest(); +</script> </body>
diff --git a/third_party/WebKit/LayoutTests/editing/selection/drag-drop-events-expected.txt b/third_party/WebKit/LayoutTests/editing/selection/drag-drop-events-expected.txt deleted file mode 100644 index 2d624f9a6..0000000 --- a/third_party/WebKit/LayoutTests/editing/selection/drag-drop-events-expected.txt +++ /dev/null
@@ -1,17 +0,0 @@ - -This test verifies the order of events fired by drag-and-drop. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS successfullyParsed is true - -TEST COMPLETE -focus src -drop dst -input src -change src -blur src -focus dst -input dst -
diff --git a/third_party/WebKit/LayoutTests/editing/selection/drag-drop-events.html b/third_party/WebKit/LayoutTests/editing/selection/drag-drop-events.html index 80a8ec8..5137a29 100644 --- a/third_party/WebKit/LayoutTests/editing/selection/drag-drop-events.html +++ b/third_party/WebKit/LayoutTests/editing/selection/drag-drop-events.html
@@ -1,23 +1,37 @@ <!DOCTYPE html> <html> <head> - <script src="../../resources/js-test.js"></script> + <script src="../../resources/testharness.js"></script> + <script src="../../resources/testharnessreport.js"></script> </head> -<body onload="runTest()"> +<body> <input type="text" id="src" value="abc"> <input type="text" id="dst"> -<div id="console"></div> <script> -description("This test verifies the order of events fired by drag-and-drop."); +test(() => { + const expected = [ + {name: 'focus', target: 'src'}, + {name: 'drop', target: 'dst'}, + {name: 'input', target: 'src'}, + {name: 'change', target: 'src'}, + {name: 'blur', target: 'src'}, + {name: 'focus', target: 'dst'}, + {name: 'input', target: 'dst'}, + ]; -function runTest() -{ + var fired = 0; + function checkEvent(name, target) { + assert_equals(name, expected[fired].name); + assert_equals(target, expected[fired].target); + ++fired; + } + var src = document.getElementById('src'); var dst = document.getElementById('dst'); ['blur', 'change', 'drop', 'focus', 'input'].forEach(function(event) { - src.addEventListener(event, debug.bind(null, event + ' src')); - dst.addEventListener(event, debug.bind(null, event + ' dst')); + src.addEventListener(event, () => checkEvent(event, 'src')); + dst.addEventListener(event, () => checkEvent(event, 'dst')); }); src.select(); @@ -26,7 +40,7 @@ eventSender.leapForward(1000); eventSender.mouseMoveTo(dst.offsetLeft + dst.offsetWidth / 2, dst.offsetTop + dst.offsetHeight / 2); eventSender.mouseUp(); -} +}, 'Event order by drag-and-drop'); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST_5.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST_5.json index 4dd01bd..f118ebb 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST_5.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST_5.json
@@ -248586,6 +248586,12 @@ {} ] ], + "payment-method-id/payment-request-ctor-pmi-handling.https.html": [ + [ + "/payment-method-id/payment-request-ctor-pmi-handling.https.html", + {} + ] + ], "payment-request/MerchantValidationEvent/complete-method.https.html": [ [ "/payment-request/MerchantValidationEvent/complete-method.https.html", @@ -390238,7 +390244,7 @@ "testharness" ], "html/semantics/scripting-1/the-script-element/module/credentials.sub.html": [ - "1293d7f6913453118f2adf4e3453be250053278c", + "c7cab6e958388f940c41760d32d81bed96bab108", "testharness" ], "html/semantics/scripting-1/the-script-element/module/crossorigin-common.js": [ @@ -390874,7 +390880,7 @@ "support" ], "html/semantics/scripting-1/the-script-element/module/resources/credentials-iframe.sub.html": [ - "f086e702822a42d318396d2aeb348ffac0276a05", + "d2b28714b1606dea015650114740362bcf6f31b3", "support" ], "html/semantics/scripting-1/the-script-element/module/resources/delayed-modulescript.py": [ @@ -406789,6 +406795,10 @@ "3d1bb8ddda2b999858fba14ec9420f127fb5dd13", "support" ], + "payment-method-id/payment-request-ctor-pmi-handling.https.html": [ + "5f888f0389f6c756ede8c3e481ece7bcf8b71ccf", + "testharness" + ], "payment-request/META.yml": [ "f8460d403ffa42d9dfc1bae6e0c3e500f7742fc9", "support"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border-ref.html b/third_party/WebKit/LayoutTests/external/wpt/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border-ref.html new file mode 100644 index 0000000..2f313f3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border-ref.html
@@ -0,0 +1,18 @@ +<!DOCTYPE html> +<style> +table { + border-collapse: collapse; +} +td { + border: 5px solid black; + width: 100px; + height: 100px; +} +</style> +Passes if there is a grid containing 2x2 squares. +<table> + <tbody> + <tr><td></td><td></td></tr> + <tr><td></td><td></td></tr> + </tbody> +</table>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border.html b/third_party/WebKit/LayoutTests/external/wpt/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border.html new file mode 100644 index 0000000..5f131e6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border.html
@@ -0,0 +1,23 @@ +<!DOCTYPE html> +<title>Test for transformed tbody and tr with collapsed borders</title> +<link rel="match" href="transformed-tbody-tr-collapsed-border-ref.html"> +<style> +table { + border-collapse: collapse; +} +tbody, tr { + transform: translateY(0); +} +td { + border: 5px solid black; + width: 100px; + height: 100px; +} +</style> +Passes if there is a grid containing 2x2 squares. +<table> + <tbody> + <tr><td></td><td></td></tr> + <tr><td></td><td></td></tr> + </tbody> +</table>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/navigation-timing/dom_interactive_image_document.html b/third_party/WebKit/LayoutTests/external/wpt/navigation-timing/dom_interactive_image_document.html new file mode 100644 index 0000000..36742f0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/navigation-timing/dom_interactive_image_document.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8" /> + <title>Test domInteractive on image document.</title> + <link rel="author" title="Google" href="http://www.google.com/" /> + <link rel="help" href="https://html.spec.whatwg.org/multipage/browsing-the-web.html#read-media"/> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + </head> + <script> + const t = async_test("Test domInteractive on image document"); + function frameLoaded() { + const timing = document.querySelector("iframe").contentWindow.performance.timing; + assert_greater_than(timing.domInteractive, 0, + "Expect domInteractive to be positive value."); + t.done(); + } + </script> + <body> + <h1>Description</h1> + <p>This tests that a image document has positive-value domInteractive.</p> + <iframe src="../images/smiley.png" onload="frameLoaded()"></iframe> + </body> +</html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/navigation-timing/dom_interactive_media_document.html b/third_party/WebKit/LayoutTests/external/wpt/navigation-timing/dom_interactive_media_document.html new file mode 100644 index 0000000..e4e4572 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/navigation-timing/dom_interactive_media_document.html
@@ -0,0 +1,25 @@ +<!DOCTYPE html> +<html> + <head> + <meta charset="utf-8" /> + <title>Test domInteractive on media document.</title> + <link rel="author" title="Google" href="http://www.google.com/" /> + <link rel="help" href="https://html.spec.whatwg.org/multipage/browsing-the-web.html#read-media"/> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + </head> + <script> + const t = async_test("Test domInteractive on media document"); + function frameLoaded() { + const timing = document.querySelector("iframe").contentWindow.performance.timing; + assert_greater_than(timing.domInteractive, 0, + "Expect domInteractive to be positive value."); + t.done(); + } + </script> + <body> + <h1>Description</h1> + <p>This tests that a media document has positive-value domInteractive.</p> + <iframe src="../media/A4.mp4" onload="frameLoaded()"></iframe> + </body> +</html> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/payment-method-id/payment-request-ctor-pmi-handling.https.html b/third_party/WebKit/LayoutTests/external/wpt/payment-method-id/payment-request-ctor-pmi-handling.https.html new file mode 100644 index 0000000..5f888f03 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/payment-method-id/payment-request-ctor-pmi-handling.https.html
@@ -0,0 +1,149 @@ +<!DOCTYPE html> +<!-- Copyright © 2017 Mozilla and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). --> +<meta charset="utf-8"> +<title>Test for validity of payment method identifiers during construction</title> +<link rel="help" href="https://w3c.github.io/browser-payment-api/#constructor"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +"use strict"; +const validAmount = Object.freeze({ + currency: "USD", + value: "1.0", +}); +const validTotal = Object.freeze({ + label: "Default Total", + amount: validAmount, +}); +const defaultDetails = Object.freeze({ + total: validTotal, +}); + +test(() => { + const validMethods = [ + "https://wpt", + "https://wpt.fyi/", + "https://wpt.fyi/payment", + "https://wpt.fyi/payment-request", + "https://wpt.fyi/payment-request?", + "https://wpt.fyi/payment-request?this=is", + "https://wpt.fyi/payment-request?this=is&totally", + "https://wpt.fyi:443/payment-request?this=is&totally", + "https://wpt.fyi:443/payment-request?this=is&totally#fine", + "https://:@wpt.fyi:443/payment-request?this=is&totally#👍", + " \thttps://wpt\n ", + "https://xn--c1yn36f", + "https://點看", + ]; + for (const validMethod of validMethods) { + try { + const methods = [{ supportedMethods: validMethod }]; + new PaymentRequest(methods, defaultDetails); + } catch (err) { + assert_unreached( + `Unexpected exception with valid standardized PMI: ${validMethod}. ${err}` + ); + } + } +}, "Must support valid standard URL PMIs"); + +test(() => { + const validMethods = [ + "e", + "n6jzof05mk2g4lhxr-u-q-w1-c-i-pa-ty-bdvs9-ho-ae7-p-md8-s-wq3-h-qd-e-q-sa", + "a-b-q-n-s-pw0", + "m-u", + "s-l5", + "k9-f", + "m-l", + "u4-n-t", + "i488jh6-g18-fck-yb-v7-i", + "x-x-t-t-c34-o", + "basic-card", + // gets coerced to "basic-card", for compat with old version of spec + ["basic-card"], + ]; + for (const validMethod of validMethods) { + try { + const methods = [{ supportedMethods: validMethod }]; + new PaymentRequest(methods, defaultDetails); + } catch (err) { + assert_unreached( + `Unexpected exception with valid standardized PMI: ${validMethod}. ${err}` + ); + } + } +}, "Must not throw on syntactically valid standardized payment method identifiers, even if they are not supported"); + +test(() => { + const invalidMethods = [ + "basic-💳", + "¡basic-*-card!", + "Basic-Card", + "0", + "-", + "--", + "a--b", + "-a--b", + "a-b-", + "0-", + "0-a", + "a0--", + "A-", + "A-B", + "A-b", + "a-0", + "a-0b", + " a-b", + "\t\na-b", + "a-b ", + "a-b\n\t", + "basic-card?not-really", + "basic-card://not-ok", + "basic card", + "/basic card/", + "BaSicCarD", + "BASIC-CARD", + " basic-card ", + "this is not supported", + " ", + "foo,var", + ["visa","mastercard"], // stringifies to "visa,mastercard" + ]; + for (const invalidMethod of invalidMethods) { + assert_throws( + new RangeError(), + () => { + const methods = [{ supportedMethods: invalidMethod }]; + new PaymentRequest(methods, defaultDetails); + }, + `expected RangeError processing invalid standardized PMI "${invalidMethod}"` + ); + } +}, "Must throw on syntactically invalid standardized payment method identifiers"); + +test(() => { + const invalidMethods = [ + "https://username@example.com/pay", + "https://:password@example.com/pay", + "https://username:password@example.com/pay", + "http://username:password@example.com/pay", + "http://foo.com:100000000/pay", + "not-https://wpt.fyi/payment-request", + "../realitive/url", + "/absolute/../path?", + "https://", + ]; + for (const invalidMethod of invalidMethods) { + assert_throws( + new RangeError(), + () => { + const methods = [{ supportedMethods: invalidMethod }]; + new PaymentRequest(methods, defaultDetails); + }, + `expected RangeError processing invalid URL PMI "${invalidMethod}"` + ); + } +}, "Constructor MUST throw if given an invalid URL-based payment method identifier"); + +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/content-selector-query-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/shadow/content-selector-query-expected.txt deleted file mode 100644 index ec171fe..0000000 --- a/third_party/WebKit/LayoutTests/fast/dom/shadow/content-selector-query-expected.txt +++ /dev/null
@@ -1,180 +0,0 @@ -This test checks select attribute of content element is valid. - -null -PASS internals.isValidContentSelect(content) is true - -PASS internals.isValidContentSelect(content) is true -*|div -PASS internals.isValidContentSelect(content) is true -|div -PASS internals.isValidContentSelect(content) is true -div -PASS internals.isValidContentSelect(content) is true -*|* -PASS internals.isValidContentSelect(content) is true -|* -PASS internals.isValidContentSelect(content) is true -* -PASS internals.isValidContentSelect(content) is true -.elem -PASS internals.isValidContentSelect(content) is true -p.elem -PASS internals.isValidContentSelect(content) is true -foo.elem -PASS internals.isValidContentSelect(content) is true -*.right -PASS internals.isValidContentSelect(content) is true -#elem -PASS internals.isValidContentSelect(content) is true -p#elem -PASS internals.isValidContentSelect(content) is true -foo#elem -PASS internals.isValidContentSelect(content) is true -*#something -PASS internals.isValidContentSelect(content) is true -div[title] -PASS internals.isValidContentSelect(content) is true -div[class="example"] -PASS internals.isValidContentSelect(content) is true -div[hello="Cleveland"][goodbye="Columbus"] -PASS internals.isValidContentSelect(content) is true -div[rel~="copyright"] -PASS internals.isValidContentSelect(content) is true -div[href="http://www.example.com/"] -PASS internals.isValidContentSelect(content) is true -div[hreflang|="en"] -PASS internals.isValidContentSelect(content) is true -div[character=romeo] -PASS internals.isValidContentSelect(content) is true -div, div -PASS internals.isValidContentSelect(content) is true - div, div -PASS internals.isValidContentSelect(content) is true -div:not(div) -PASS internals.isValidContentSelect(content) is true -div div -PASS internals.isValidContentSelect(content) is false -div > div -PASS internals.isValidContentSelect(content) is false -div + div -PASS internals.isValidContentSelect(content) is false -div ~ div -PASS internals.isValidContentSelect(content) is false -ns|div -PASS internals.isValidContentSelect(content) is false -ns|* -PASS internals.isValidContentSelect(content) is false -div:root -PASS internals.isValidContentSelect(content) is false -div:lang(en) -PASS internals.isValidContentSelect(content) is false -div::before -PASS internals.isValidContentSelect(content) is false -div::after -PASS internals.isValidContentSelect(content) is false -div::first-line -PASS internals.isValidContentSelect(content) is false -div::first-letter -PASS internals.isValidContentSelect(content) is false -div:active -PASS internals.isValidContentSelect(content) is false -div:hover -PASS internals.isValidContentSelect(content) is false -div:focus -PASS internals.isValidContentSelect(content) is false -div div:not(div) -PASS internals.isValidContentSelect(content) is false -div:not(div) div -PASS internals.isValidContentSelect(content) is false -div span div -PASS internals.isValidContentSelect(content) is false -div < div -PASS internals.isValidContentSelect(content) is false -div - dvi -PASS internals.isValidContentSelect(content) is false -< div -PASS internals.isValidContentSelect(content) is false -+div -PASS internals.isValidContentSelect(content) is false -~div -PASS internals.isValidContentSelect(content) is false -div:! -PASS internals.isValidContentSelect(content) is false -!:! -PASS internals.isValidContentSelect(content) is false -div::! -PASS internals.isValidContentSelect(content) is false -div::first_of_type -PASS internals.isValidContentSelect(content) is false -pe;ro -PASS internals.isValidContentSelect(content) is false -@screen -PASS internals.isValidContentSelect(content) is false -@import "style.css" -PASS internals.isValidContentSelect(content) is false -div :first-of-type -PASS internals.isValidContentSelect(content) is false -div::first-of-type -PASS internals.isValidContentSelect(content) is false - div, ,div -PASS internals.isValidContentSelect(content) is false -div '' -PASS internals.isValidContentSelect(content) is false -div:link -PASS internals.isValidContentSelect(content) is false -div:visited -PASS internals.isValidContentSelect(content) is false -div:target -PASS internals.isValidContentSelect(content) is false -div:enabled -PASS internals.isValidContentSelect(content) is false -div:checked -PASS internals.isValidContentSelect(content) is false -div:indeterminate -PASS internals.isValidContentSelect(content) is false -div:nth-child(1) -PASS internals.isValidContentSelect(content) is false -div:nth-last-child(1) -PASS internals.isValidContentSelect(content) is false -div:nth-of-type(1) -PASS internals.isValidContentSelect(content) is false -div:nth-last-of-type(1) -PASS internals.isValidContentSelect(content) is false -div:first-child -PASS internals.isValidContentSelect(content) is false -div:last-child -PASS internals.isValidContentSelect(content) is false -div:first-of-type -PASS internals.isValidContentSelect(content) is false -div:last-of-type -PASS internals.isValidContentSelect(content) is false -div:only-of-type -PASS internals.isValidContentSelect(content) is false -div:first-of-type:last-of-type -PASS internals.isValidContentSelect(content) is false -div.elem:visited -PASS internals.isValidContentSelect(content) is false -*:visited -PASS internals.isValidContentSelect(content) is false -div:first-of-type, div -PASS internals.isValidContentSelect(content) is false -div, div:first-of-type -PASS internals.isValidContentSelect(content) is false -div:first-of-type, div:last-of-type -PASS internals.isValidContentSelect(content) is false -div:not(:not(div)) -PASS internals.isValidContentSelect(content) is false -div:not(:hover) -PASS internals.isValidContentSelect(content) is false -div:not(div div) -PASS internals.isValidContentSelect(content) is false -div:not(div div:not) -PASS internals.isValidContentSelect(content) is false -div:not(div div:hover) -PASS internals.isValidContentSelect(content) is false -div div:not(:hover) -PASS internals.isValidContentSelect(content) is false -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/dom/shadow/content-selector-query.html b/third_party/WebKit/LayoutTests/fast/dom/shadow/content-selector-query.html index 927720c..6ae1386 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/shadow/content-selector-query.html +++ b/third_party/WebKit/LayoutTests/fast/dom/shadow/content-selector-query.html
@@ -1,7 +1,8 @@ <!DOCTYPE html> <html> <head> -<script src="../../../resources/js-test.js"></script> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> </head> <body> <p>This test checks select attribute of content element is valid.</p> @@ -12,16 +13,16 @@ var container = document.getElementById("container"); var content; -function test(select, valid) { +function runTest(select, valid) { content = document.createElement('content'); if (select != null) content.setAttribute('select', select); - debug(select); - if (valid) - shouldBe("internals.isValidContentSelect(content)", "true"); - else - shouldBe("internals.isValidContentSelect(content)", "false"); + test(() => { + assert_exists(window, 'internals', + 'This test requires internals.isValidContentSelect'); + assert_equals(internals.isValidContentSelect(content), valid); + }, `${select} ${valid}`); } var dataOfValidCases = [ @@ -53,19 +54,15 @@ ]; function doTest() { - if (!window.internals) - return; - for (var i = 0; i < dataOfValidCases.length; ++i) { - test(dataOfValidCases[i], true); + runTest(dataOfValidCases[i], true); } for (var i = 0; i < dataOfInvalidCases.length; ++i) { - test(dataOfInvalidCases[i], false); + runTest(dataOfInvalidCases[i], false); } } doTest(); -var successfullyParsed = true; </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/fast/events/autoscroll-upwards-propagation-overflow-hidden-body-expected.txt b/third_party/WebKit/LayoutTests/fast/events/autoscroll-upwards-propagation-overflow-hidden-body-expected.txt deleted file mode 100644 index 2a10728..0000000 --- a/third_party/WebKit/LayoutTests/fast/events/autoscroll-upwards-propagation-overflow-hidden-body-expected.txt +++ /dev/null
@@ -1,10 +0,0 @@ -This test ensures that if an autoscroll starts from within a scrollable div, it does not propagate to its non-scrollable document body. Furthermore, it tests that if the body has only one of overflowX or overflowY set to hidden, the scrollable axis actually scrolls. Note that this test is pertaining to crbug.com/531525. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS Document didn't scroll. -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/events/autoscroll-upwards-propagation-overflow-hidden-body.html b/third_party/WebKit/LayoutTests/fast/events/autoscroll-upwards-propagation-overflow-hidden-body.html index cf5dc5d9..9895737 100644 --- a/third_party/WebKit/LayoutTests/fast/events/autoscroll-upwards-propagation-overflow-hidden-body.html +++ b/third_party/WebKit/LayoutTests/fast/events/autoscroll-upwards-propagation-overflow-hidden-body.html
@@ -14,32 +14,27 @@ width: 100px; } </style> -<script src="../../resources/js-test.js"></script> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <script type="text/javascript"> var scrollTopBefore; var maxScrollLeft; - setPrintTestResultsLazily(); - jsTestIsAsync = true; - description("This test ensures that if an autoscroll starts from within a " + + const testCase = async_test( + "If an autoscroll starts from within a " + "scrollable div, it does not propagate to its non-scrollable document " + "body. Furthermore, it tests that if the body has only one of overflowX " + "or overflowY set to hidden, the scrollable axis actually scrolls. Note " + "that this test is pertaining to crbug.com/531525."); - function finishTest() { + const finishTest = testCase.step_func_done(() => { eventSender.mouseUp(); // Because only overflowY:hidden is set, horizontal scroll should happen and // vertical scroll shouldn't. - if (document.scrollingElement.scrollTop == scrollTopBefore && document.scrollingElement.scrollLeft == maxScrollLeft) { - testPassed("Document didn't scroll."); - } else { - testFailed("Document scrolled although overflow:hidden."); - testFailed(document.scrollingElement.scrollTop + " " + scrollTopBefore + " " + document.scrollingElement.scrollLeft + " " + maxScrollLeft); - } + assert_equals(document.scrollingElement.scrollTop, scrollTopBefore); + assert_equals(document.scrollingElement.scrollLeft, maxScrollLeft); document.getElementById('text-wrapper').style.display = 'none'; - finishJSTest(); - } + }); window.onload = function () { scrollTopBefore = document.scrollingElement.scrollTop;
diff --git a/third_party/WebKit/LayoutTests/fast/events/click-with-large-negative-text-indent-expected.txt b/third_party/WebKit/LayoutTests/fast/events/click-with-large-negative-text-indent-expected.txt deleted file mode 100644 index 33fb3da..0000000 --- a/third_party/WebKit/LayoutTests/fast/events/click-with-large-negative-text-indent-expected.txt +++ /dev/null
@@ -1,2 +0,0 @@ -Move -Button is clicked.
diff --git a/third_party/WebKit/LayoutTests/fast/events/click-with-large-negative-text-indent.html b/third_party/WebKit/LayoutTests/fast/events/click-with-large-negative-text-indent.html index bac122c..ae1572a 100644 --- a/third_party/WebKit/LayoutTests/fast/events/click-with-large-negative-text-indent.html +++ b/third_party/WebKit/LayoutTests/fast/events/click-with-large-negative-text-indent.html
@@ -1,25 +1,23 @@ <html> <head> -<script> -if (window.testRunner) { - testRunner.dumpAsText(); -} -</script> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> </head> <body> <button id="testButton" style="text-indent: -99999999px;" onclick="btnClicked()">Move</button> <p id="output"></p> <script> -function btnClicked() -{ - document.getElementById('output').innerHTML = "Button is clicked."; -} -if (window.eventSender) { - var testEle = document.getElementById('testButton'); - eventSender.mouseMoveTo(testEle.offsetLeft + testEle.offsetWidth / 2, testEle.offsetTop + testEle.offsetHeight / 2); - eventSender.mouseDown(); - eventSender.mouseUp(); -} +const testCase = async_test('Button is clicked'); + +const btnClicked = testCase.step_func_done(() => {}); + +testCase.step(() => { + assert_exists(window, 'eventSender'); + var testEle = document.getElementById('testButton'); + eventSender.mouseMoveTo(testEle.offsetLeft + testEle.offsetWidth / 2, testEle.offsetTop + testEle.offsetHeight / 2); + eventSender.mouseDown(); + eventSender.mouseUp(); +}); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/fast/events/content-changed-during-drop-expected.txt b/third_party/WebKit/LayoutTests/fast/events/content-changed-during-drop-expected.txt deleted file mode 100644 index 95e19ab7..0000000 --- a/third_party/WebKit/LayoutTests/fast/events/content-changed-during-drop-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -This tests that we don't lose data dropped onto an input field that changes its content during a drop event - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -PASS dragTarget.value is elementToDrag.href -PASS Didn't crash. -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/events/content-changed-during-drop.html b/third_party/WebKit/LayoutTests/fast/events/content-changed-during-drop.html index d262f80c..7ca2309 100644 --- a/third_party/WebKit/LayoutTests/fast/events/content-changed-during-drop.html +++ b/third_party/WebKit/LayoutTests/fast/events/content-changed-during-drop.html
@@ -1,6 +1,7 @@ <html> <head> - <script src="../../resources/js-test.js"></script> + <script src="../../resources/testharness.js"></script> + <script src="../../resources/testharnessreport.js"></script> <script> function resetField() @@ -10,9 +11,11 @@ function runTest() { - if (window.testRunner) { - testRunner.dumpAsText(); - + test(() => { + assert_exists( + window, 'eventSender', + 'This test requires eventSender. To test this manually drag the link into the text field.'); + elementToDrag = document.getElementById("elementToDrag"); x1 = elementToDrag.offsetLeft + elementToDrag.offsetWidth / 2; y1 = elementToDrag.offsetTop + elementToDrag.offsetHeight / 2; @@ -26,14 +29,12 @@ eventSender.leapForward(400); eventSender.mouseMoveTo(x2, y2); eventSender.mouseUp(); - shouldBe("dragTarget.value", "elementToDrag.href"); - testPassed("Didn't crash."); + assert_equals(dragTarget.value, elementToDrag.href); + //clean up output elementToDrag.parentNode.removeChild(elementToDrag); dragTarget.parentNode.removeChild(dragTarget); - } else { - debug('<br>To test this manually drag the link into the text field.') - } + }, "This tests that we don't lose data dropped onto an input field that changes its content during a drop event"); } </script> </head> @@ -43,8 +44,7 @@ <input id="dragTarget" type="text" value="Original Text" onfocus="resetField()" /> <div id="console"></div> <script> - description("This tests that we don't lose data dropped onto an input field that changes its content during a drop event"); runTest(); </script> </body> -</html> \ No newline at end of file +</html>
diff --git a/third_party/WebKit/LayoutTests/fast/events/dispatch-mouse-events-to-window-always-expected.txt b/third_party/WebKit/LayoutTests/fast/events/dispatch-mouse-events-to-window-always-expected.txt deleted file mode 100644 index 44034bf1..0000000 --- a/third_party/WebKit/LayoutTests/fast/events/dispatch-mouse-events-to-window-always-expected.txt +++ /dev/null
@@ -1,36 +0,0 @@ -Test that wheel and mouse events are dispatched to document and window even if they do not hit any element in the page. - -On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". - - -outside body, inside element -eventType: mousedown -PASS objectsToString(actualReceivers) is "HTMLDivElement,HTMLBodyElement,HTMLDocument,Window" -eventType: mouseup -PASS objectsToString(actualReceivers) is "HTMLDivElement,HTMLBodyElement,HTMLDocument,Window" -eventType: click -PASS objectsToString(actualReceivers) is "HTMLDivElement,HTMLBodyElement,HTMLDocument,Window" -eventType: wheel -PASS objectsToString(actualReceivers) is "HTMLDivElement,HTMLBodyElement,HTMLDocument,Window" -inside body, outside element -eventType: mousedown -PASS objectsToString(actualReceivers) is "HTMLBodyElement,HTMLDocument,Window" -eventType: mouseup -PASS objectsToString(actualReceivers) is "HTMLBodyElement,HTMLDocument,Window" -eventType: click -PASS objectsToString(actualReceivers) is "HTMLBodyElement,HTMLDocument,Window" -eventType: wheel -PASS objectsToString(actualReceivers) is "HTMLBodyElement,HTMLDocument,Window" -outside body, outside element, inside frame -eventType: mousedown -PASS objectsToString(actualReceivers) is "HTMLDocument,Window" -eventType: mouseup -PASS objectsToString(actualReceivers) is "HTMLDocument,Window" -eventType: click -PASS objectsToString(actualReceivers) is "HTMLDocument,Window" -eventType: wheel -PASS objectsToString(actualReceivers) is "HTMLDocument,Window" -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/events/dispatch-mouse-events-to-window-always.html b/third_party/WebKit/LayoutTests/fast/events/dispatch-mouse-events-to-window-always.html index 8ac3fd28..da8b6d3 100644 --- a/third_party/WebKit/LayoutTests/fast/events/dispatch-mouse-events-to-window-always.html +++ b/third_party/WebKit/LayoutTests/fast/events/dispatch-mouse-events-to-window-always.html
@@ -33,18 +33,15 @@ <div id='console'></div> </body> -<script src="../../resources/js-test.js"></script> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <script> -jsTestIsAsync = true; -setPrintTestResultsLazily(); -description('Test that wheel and mouse events are dispatched to document ' + - 'and window even if they do not hit any element in the page.'); +const purpose = + 'Test that wheel and mouse events are dispatched to document' + + 'and window even if they do not hit any element in the page.'; -onload = function() { - if (!window.eventSender) { - testFailed('window.eventSender is required for this test.'); - return; - } +test(() => { + assert_exists(window, 'eventSender', 'window.eventSender is required for this test.'); window.receivers = new Map(); var eventTypes = ['wheel', 'click', 'mousedown', 'mouseup']; @@ -57,20 +54,19 @@ } } - debug('outside body, inside element'); // received by element, body, doc, window - generateEventsAndVerify(500, 500, [document.getElementById('child'), document.body, document, window]); - debug('inside body, outside element'); // received by body, doc, window - generateEventsAndVerify(10, 10, [document.body, document, window]); - debug('outside body, outside element, inside frame'); // received by doc, window - generateEventsAndVerify(10, 500, [document, window]); - - finishJSTest(); + // received by element, body, doc, window + generateEventsAndVerify(500, 500, [document.getElementById('child'), document.body, document, window], 'outside body, inside element.'); + // received by body, doc, window + generateEventsAndVerify(10, 10, [document.body, document, window], 'inside body, outside element.'); + // received by doc, window + generateEventsAndVerify(10, 500, [document, window], 'outside body, outside element, inside frame.'); function registerEvent(e) { window.receivers[e.type].push(this); } - function generateEventsAndVerify(x, y, expectedReceivers) { + function generateEventsAndVerify(x, y, expectedReceivers, title) { + test(() => { eventSender.mouseMoveTo(x, y); eventSender.mouseDown(); verifyReceivers('mousedown', expectedReceivers); @@ -81,16 +77,16 @@ eventSender.mouseScrollBy(10, 10); verifyReceivers('wheel', expectedReceivers); + }, title + ' ' + purpose); } function verifyReceivers(eventType, expectedReceivers) { - debug('eventType: ' + eventType); window.actualReceivers = window.receivers[eventType]; - shouldBeEqualToString('objectsToString(actualReceivers)', objectsToString(expectedReceivers)); + assert_equals(objectsToString(actualReceivers), objectsToString(expectedReceivers), eventType); window.receivers[eventType] = []; } -} +}); function objectsToString(objects) { return String(objects.map(function(o) {return o.constructor.name;}));
diff --git a/third_party/WebKit/LayoutTests/fast/events/focus-change-crash-expected.txt b/third_party/WebKit/LayoutTests/fast/events/focus-change-crash-expected.txt deleted file mode 100644 index 0b73fb9..0000000 --- a/third_party/WebKit/LayoutTests/fast/events/focus-change-crash-expected.txt +++ /dev/null
@@ -1,3 +0,0 @@ -Type something into the first input and press tab. The browser should not crash. - -PASSED
diff --git a/third_party/WebKit/LayoutTests/fast/events/focus-change-crash.html b/third_party/WebKit/LayoutTests/fast/events/focus-change-crash.html index a1ec50b..10f1571 100644 --- a/third_party/WebKit/LayoutTests/fast/events/focus-change-crash.html +++ b/third_party/WebKit/LayoutTests/fast/events/focus-change-crash.html
@@ -1,9 +1,10 @@ +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> <div>Type something into the first input and press tab. The browser should not crash.</div> <div id="parent"> <input id="a" /> <input id="b" /> </div> -<div id="results"></div> <script> document.getElementById("a").addEventListener("change", function(e) { var parent = document.getElementById("parent"); @@ -11,17 +12,11 @@ document.getElementById("c").select(); }, false); -function runTest() -{ +test(() => { document.getElementById("a").focus(); if (!window.testRunner) return; - testRunner.dumpAsText(); eventSender.keyDown("x") eventSender.keyDown("\t"); - document.getElementById("results").innerText = "PASSED"; -} - -runTest(); - +}, "Typing followed by focus change doesn't crash"); </script>
diff --git a/third_party/WebKit/LayoutTests/fast/events/popup-allowed-from-gesture-initiated-event-expected.txt b/third_party/WebKit/LayoutTests/fast/events/popup-allowed-from-gesture-initiated-event-expected.txt deleted file mode 100644 index 37595ad..0000000 --- a/third_party/WebKit/LayoutTests/fast/events/popup-allowed-from-gesture-initiated-event-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ -Click Here Click Here Too -PASS win is non-null. -PASS successfullyParsed is true - -TEST COMPLETE -PASS win is non-null. -
diff --git a/third_party/WebKit/LayoutTests/fast/events/popup-allowed-from-gesture-initiated-event.html b/third_party/WebKit/LayoutTests/fast/events/popup-allowed-from-gesture-initiated-event.html index a0b3bbc..f78ac03 100644 --- a/third_party/WebKit/LayoutTests/fast/events/popup-allowed-from-gesture-initiated-event.html +++ b/third_party/WebKit/LayoutTests/fast/events/popup-allowed-from-gesture-initiated-event.html
@@ -1,19 +1,21 @@ <html> <head> - <script src="../../resources/js-test.js"></script> + <script src="../../resources/testharness.js"></script> + <script src="../../resources/testharnessreport.js"></script> </head> <body> <button id="button1" onclick="testButton1()">Click Here</button> <button id="button2" onclick="testButton2()">Click Here Too</button> <button id="test" onclick="popup()" style="display:none"></button> - <div id="console"></div> <script> + setup({explicit_done: true}); + var testNum = 0; var win; function popup() { win = window.open("about:blank", "blank"); - shouldBeNonNull("win"); + assert_not_equals(win, null); } function testButton1() { @@ -44,28 +46,30 @@ function nextTest() { if (testNum == 0) { + test(() => { var button1 = document.getElementById("button1"); eventSender.mouseMoveTo(button1.offsetLeft + button1.offsetWidth / 2, button1.offsetTop + button1.offsetHeight / 2); eventSender.mouseDown(); eventSender.mouseUp(); + }, 'Click button1'); } else if (testNum == 1) { + test(() => { var button2 = document.getElementById("button2"); eventSender.mouseMoveTo(button2.offsetLeft + button2.offsetWidth / 2, button2.offsetTop + button2.offsetHeight / 2); eventSender.mouseDown(); eventSender.mouseUp(); + }, 'Click button2'); } else { - testRunner.notifyDone(); + done(); } ++testNum; closeWindowAndRunNextTest(); } if (window.testRunner) { - testRunner.dumpAsText(); testRunner.setCanOpenWindows(); testRunner.setPopupBlockingEnabled(true); testRunner.setCloseRemainingWindowsWhenComplete(true); - testRunner.waitUntilDone(); nextTest(); }
diff --git a/third_party/WebKit/LayoutTests/fast/events/popup-blocked-from-fake-button-click-expected.txt b/third_party/WebKit/LayoutTests/fast/events/popup-blocked-from-fake-button-click-expected.txt deleted file mode 100644 index bdd5846..0000000 --- a/third_party/WebKit/LayoutTests/fast/events/popup-blocked-from-fake-button-click-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -PASS win is null -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/events/popup-blocked-from-fake-button-click.html b/third_party/WebKit/LayoutTests/fast/events/popup-blocked-from-fake-button-click.html index fe5694a..6f130a61 100644 --- a/third_party/WebKit/LayoutTests/fast/events/popup-blocked-from-fake-button-click.html +++ b/third_party/WebKit/LayoutTests/fast/events/popup-blocked-from-fake-button-click.html
@@ -1,6 +1,7 @@ <html> <head> - <script src="../../resources/js-test.js"></script> + <script src="../../resources/testharness.js"></script> + <script src="../../resources/testharnessreport.js"></script> </head> <body> <button id="test" onclick="popup()" style="display:none"></button> @@ -9,21 +10,16 @@ var win; function popup() { win = window.open("about:blank", "blank"); - shouldBeNull("win"); + assert_equals(win, null); } if (window.testRunner) { - testRunner.dumpAsText(); testRunner.setCanOpenWindows(); testRunner.setPopupBlockingEnabled(true); testRunner.setCloseRemainingWindowsWhenComplete(true); - testRunner.waitUntilDone(); } - document.getElementById("test").click(); - - if (window.testRunner) - testRunner.notifyDone(); + test(() => document.getElementById("test").click(), 'Fake button click'); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/fast/events/popup-blocked-from-fake-focus-expected.txt b/third_party/WebKit/LayoutTests/fast/events/popup-blocked-from-fake-focus-expected.txt deleted file mode 100644 index e9dce7f..0000000 --- a/third_party/WebKit/LayoutTests/fast/events/popup-blocked-from-fake-focus-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ - -PASS win is null -PASS win is null -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/events/popup-blocked-from-fake-focus.html b/third_party/WebKit/LayoutTests/fast/events/popup-blocked-from-fake-focus.html index c429a57c..e8c45cb 100644 --- a/third_party/WebKit/LayoutTests/fast/events/popup-blocked-from-fake-focus.html +++ b/third_party/WebKit/LayoutTests/fast/events/popup-blocked-from-fake-focus.html
@@ -1,31 +1,26 @@ <html> <head> - <script src="../../resources/js-test.js"></script> + <script src="../../resources/testharness.js"></script> + <script src="../../resources/testharnessreport.js"></script> </head> <body> <textarea id="test" width="100" onfocus="popup()" onblur="popup()"></textarea> - <div id="console"></div> <script> var win; function popup() { win = window.open("about:blank", "blank"); - shouldBeNull("win"); + assert_equals(win, null); } if (window.testRunner) { - testRunner.dumpAsText(); testRunner.setCanOpenWindows(); testRunner.setPopupBlockingEnabled(true); testRunner.setCloseRemainingWindowsWhenComplete(true); - testRunner.waitUntilDone(); } - document.getElementById("test").focus(); - document.getElementById("test").blur(); - - if (window.testRunner) - testRunner.notifyDone(); + test(() => document.getElementById("test").focus(), 'focus'); + test(() => document.getElementById("test").blur(), 'blur'); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/fast/events/popup-blocked-from-untrusted-click-event-on-anchor-expected.txt b/third_party/WebKit/LayoutTests/fast/events/popup-blocked-from-untrusted-click-event-on-anchor-expected.txt deleted file mode 100644 index ae18561..0000000 --- a/third_party/WebKit/LayoutTests/fast/events/popup-blocked-from-untrusted-click-event-on-anchor-expected.txt +++ /dev/null
@@ -1,6 +0,0 @@ -test -PASS win is null -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/events/popup-blocked-from-untrusted-click-event-on-anchor.html b/third_party/WebKit/LayoutTests/fast/events/popup-blocked-from-untrusted-click-event-on-anchor.html index 4a6f73e..dd1c944 100644 --- a/third_party/WebKit/LayoutTests/fast/events/popup-blocked-from-untrusted-click-event-on-anchor.html +++ b/third_party/WebKit/LayoutTests/fast/events/popup-blocked-from-untrusted-click-event-on-anchor.html
@@ -1,6 +1,7 @@ <html> <head> - <script src="../../resources/js-test.js"></script> + <script src="../../resources/testharness.js"></script> + <script src="../../resources/testharnessreport.js"></script> </head> <body> <a id=test href="javascript:popup()">test</a> @@ -9,23 +10,18 @@ var win; function popup() { win = window.open('about:blank','blank','height=200,width=200'); - shouldBeNull("win"); + assert_equals(win, null); } if (window.testRunner) { - testRunner.dumpAsText(); testRunner.setCanOpenWindows(); testRunner.setPopupBlockingEnabled(true); testRunner.setCloseRemainingWindowsWhenComplete(true); - testRunner.waitUntilDone(); } clickEvent = document.createEvent("MouseEvents"); clickEvent.initEvent("click", true, true, document.defaultView, 0, 0, 0, 0, 0, false, false, false, false, 0, null); - document.getElementById("test").dispatchEvent(clickEvent); - - if (window.testRunner) - testRunner.notifyDone(); + test(() => document.getElementById("test").dispatchEvent(clickEvent), 'Untrusted click'); </script> </body> </html>
diff --git a/third_party/WebKit/LayoutTests/fast/events/touch/touch-user-gesture-expected.txt b/third_party/WebKit/LayoutTests/fast/events/touch/touch-user-gesture-expected.txt deleted file mode 100644 index ab5ced9..0000000 --- a/third_party/WebKit/LayoutTests/fast/events/touch/touch-user-gesture-expected.txt +++ /dev/null
@@ -1,14 +0,0 @@ -Target -Test user gesture behavior during touch events. -During a scroll, no touch events are user gestures -PASS openedPopup is false -PASS openedPopup is false -PASS openedPopup is false -During a drag that isn't a scroll, only touchend is a user gesture -PASS openedPopup is false -PASS openedPopup is false -PASS openedPopup is true -PASS successfullyParsed is true - -TEST COMPLETE -
diff --git a/third_party/WebKit/LayoutTests/fast/events/touch/touch-user-gesture.html b/third_party/WebKit/LayoutTests/fast/events/touch/touch-user-gesture.html index c3909678..efd5366f 100644 --- a/third_party/WebKit/LayoutTests/fast/events/touch/touch-user-gesture.html +++ b/third_party/WebKit/LayoutTests/fast/events/touch/touch-user-gesture.html
@@ -1,7 +1,7 @@ -<script src="../../../resources/js-test.js"></script> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> <div id="target">Target</div> <div id="description">Test user gesture behavior during touch events.</div> -<div id="console"></div> <script> @@ -9,7 +9,7 @@ var openedPopup = undefined; function handler(e) { if (openedPopup !== undefined) - testFailed("Handler invoked multiple times"); + assert_unreached("Handler invoked multiple times"); var w = window.open("about:blank", "_blank"); if (w) { @@ -31,12 +31,9 @@ operation(); - if (openedPopup===undefined) - testFailed(eventType + ' handler was not invoked'); - else if (expectPopup) - shouldBeTrue("openedPopup"); - else - shouldBeFalse("openedPopup"); + assert_not_equals(openedPopup, undefined, + eventType + ' handler was not invoked'); + assert_equals(openedPopup, expectPopup); target.removeEventListener(eventType, handler); } @@ -52,17 +49,19 @@ var targetX = rect.left + rect.width / 2; var targetY = rect.top + rect.height / 2; -debug("During a scroll, no touch events are user gestures"); -cancelEvent = false; -eventSender.addTouchPoint(targetX, targetY); -testPopupOnEventDuring('touchstart', false, function() { eventSender.touchStart(); }); -eventSender.updateTouchPoint(0, targetX + 10, targetY); -testPopupOnEventDuring('touchmove', false, function() { eventSender.touchMove(); }); -eventSender.notifyStartOfTouchScroll(); -eventSender.releaseTouchPoint(0); -testPopupOnEventDuring('touchend', false, function() { eventSender.touchEnd(); }); +test(() => { + cancelEvent = false; + eventSender.addTouchPoint(targetX, targetY); + testPopupOnEventDuring('touchstart', false, function() { eventSender.touchStart(); }); + eventSender.updateTouchPoint(0, targetX + 10, targetY); + testPopupOnEventDuring('touchmove', false, function() { eventSender.touchMove(); }); + eventSender.notifyStartOfTouchScroll(); + eventSender.releaseTouchPoint(0); + testPopupOnEventDuring('touchend', false, function() { eventSender.touchEnd(); }); +}, "During a scroll, no touch events are user gestures"); -debug("During a drag that isn't a scroll, only touchend is a user gesture"); + +test(() => { cancelEvent = true; eventSender.addTouchPoint(targetX, targetY); testPopupOnEventDuring('touchstart', false, function() { eventSender.touchStart(); }); @@ -70,5 +69,6 @@ testPopupOnEventDuring('touchmove', false, function() { eventSender.touchMove(); }); eventSender.releaseTouchPoint(0); testPopupOnEventDuring('touchend', true, function() { eventSender.touchEnd(); }); +}, "During a drag that isn't a scroll, only touchend is a user gesture"); </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/img-blocked-no-gc-crash-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/img-blocked-no-gc-crash-expected.txt deleted file mode 100644 index 1fce13f..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/img-blocked-no-gc-crash-expected.txt +++ /dev/null
@@ -1,6 +0,0 @@ -CONSOLE ERROR: line 248: Uncaught EvalError: Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'unsafe-inline'". - -CONSOLE ERROR: Refused to load the image 'http://127.0.0.1:8000/security/resources/abe.png' because it violates the following Content Security Policy directive: "img-src 'none'". - -ALERT: PASS (1/1) -This test ensures that blocking an image via CSP doesn't crash if GC executes before the error event fires.
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/img-blocked-no-gc-crash.html b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/img-blocked-no-gc-crash.html index d9c12d2b..adf9309e 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/img-blocked-no-gc-crash.html +++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/img-blocked-no-gc-crash.html
@@ -1,33 +1,22 @@ <!DOCTYPE html> <html> <head> -<script src="/js-test-resources/js-test.js"></script> +<script src="/js-test-resources/testharness.js"></script> +<script src="/js-test-resources/testharnessreport.js"></script> <meta http-equiv="Content-Security-Policy" content="img-src 'none'; script-src 'unsafe-inline'"> <script> - if (window.testRunner) - testRunner.waitUntilDone(); + const testCase = async_test( + 'Blocking an image via CSP doesn\'t crash if GC executes before the error event fires'); function test() { (function () { var img = document.createElement('img'); - img.onload = function () { - alert('FAIL (1/1)'); - finishTesting(); - }; - img.onerror = function () { - alert('PASS (1/1)'); - finishTesting(); - }; + img.onload = testCase.step_func_done(() => assert_unreached()); + img.onerror = testCase.step_func_done(() => {}); img.src = "../resources/abe.png"; })(); gc(); } - - function finishTesting() { - if (window.testRunner) - setTimeout(function () { testRunner.notifyDone(); }, 0); - return true; - } </script> </head> <body onload='test();'>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/inline-style-allowed-while-cloning-objects-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/inline-style-allowed-while-cloning-objects-expected.txt deleted file mode 100644 index 94928d8..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/inline-style-allowed-while-cloning-objects-expected.txt +++ /dev/null
@@ -1,40 +0,0 @@ -CONSOLE ERROR: line 95: Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-SKwGvORdKBYTYiM4lxIkanDyKH8J0qJ5Ix8LGkKsbhw='), or a nonce ('nonce-...') is required to enable inline execution. - -CONSOLE ERROR: line 77: Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self'". Either the 'unsafe-inline' keyword, a hash ('sha256-E8Yv3p3nivzZKSVWxu7y2Pr+w7Nco7lvx8r5nBVoLFA='), or a nonce ('nonce-...') is required to enable inline execution. - -PASS successfullyParsed is true - -TEST COMPLETE -This test ensures that styles can be set by object.cloneNode() -PASS node1.style.background is "yellow" -PASS node2.style.background is "yellow" -PASS node3.style.background is "blue" -PASS node4.style.background is "blue" -PASS node1.style.color is "red" -PASS node2.style.color is "red" -PASS node3.style.color is "green" -PASS node4.style.color is "green" -PASS window.getComputedStyle(node1).background is window.getComputedStyle(node2).background -PASS window.getComputedStyle(node3).background is window.getComputedStyle(node4).background -PASS window.getComputedStyle(node1).color is window.getComputedStyle(node2).color -PASS window.getComputedStyle(node3).color is window.getComputedStyle(node4).color -PASS ops.style.background is "" -getComputedStyle(clonedOps).background: rgba(0, 0, 0, 0) none repeat scroll 0% 0% / auto padding-box border-box -PASS ops.style.color is "red" -PASS clonedOps.style.background is "" -PASS violetOps.style.background is "rgb(238, 130, 238)" -PASS window.getComputedStyle(clonedOps).background is window.getComputedStyle(ops).background -PASS window.getComputedStyle(clonedOps).color is window.getComputedStyle(ops).color -getComputedStyle(violetOps).background: rgb(238, 130, 238) none repeat scroll 0% 0% / auto padding-box border-box -PASS window.getComputedStyle(ops).background is not window.getComputedStyle(violetOps).background -PASS window.getComputedStyle(clonedOps).background is not window.getComputedStyle(violetOps).background -PASS ops.id is "ops" -PASS ops.id is clonedOps.id -This is a div (nodes) -This is a div. (node 1 or 2) -This is a div. (node 1 or 2) -This is a div. (node 3 or 4) -Node #4 -Yet another div. -Yet another div. -Yet another div.
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/inline-style-allowed-while-cloning-objects.html b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/inline-style-allowed-while-cloning-objects.html index b208901..55d6617 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/inline-style-allowed-while-cloning-objects.html +++ b/third_party/WebKit/LayoutTests/http/tests/security/contentSecurityPolicy/inline-style-allowed-while-cloning-objects.html
@@ -2,11 +2,11 @@ <html> <head> <meta http-equiv="Content-Security-Policy" content="style-src 'self';"> - <script src="/js-test-resources/js-test.js"></script> + <script src="/js-test-resources/testharness.js"></script> + <script src="/js-test-resources/testharnessreport.js"></script> <script> - window.onload = function () { - debug("This test ensures that styles can be set by object.cloneNode()"); - + const testCase = async_test('Styles can be set by object.cloneNode()'); + window.onload = testCase.step_func_done(() => { window.nodes = document.getElementById('nodes'); window.node1 = document.getElementById('node1'); window.node1.style.background = "yellow"; @@ -25,21 +25,21 @@ nodes.appendChild(node3); nodes.appendChild(node4); - shouldBeEqualToString("node1.style.background", "yellow"); - shouldBeEqualToString("node2.style.background", "yellow"); - shouldBeEqualToString("node3.style.background", "blue"); - shouldBeEqualToString("node4.style.background", "blue"); + assert_equals(node1.style.background, "yellow"); + assert_equals(node2.style.background, "yellow"); + assert_equals(node3.style.background, "blue"); + assert_equals(node4.style.background, "blue"); - shouldBeEqualToString("node1.style.color", "red"); - shouldBeEqualToString("node2.style.color", "red"); - shouldBeEqualToString("node3.style.color", "green"); - shouldBeEqualToString("node4.style.color", "green"); + assert_equals(node1.style.color, "red"); + assert_equals(node2.style.color, "red"); + assert_equals(node3.style.color, "green"); + assert_equals(node4.style.color, "green"); - shouldBe("window.getComputedStyle(node1).background", "window.getComputedStyle(node2).background"); - shouldBe("window.getComputedStyle(node3).background", "window.getComputedStyle(node4).background"); + assert_equals(window.getComputedStyle(node1).background, window.getComputedStyle(node2).background); + assert_equals(window.getComputedStyle(node3).background, window.getComputedStyle(node4).background); - shouldBe("window.getComputedStyle(node1).color", "window.getComputedStyle(node2).color"); - shouldBe("window.getComputedStyle(node3).color", "window.getComputedStyle(node4).color"); + assert_equals(window.getComputedStyle(node1).color, window.getComputedStyle(node2).color); + assert_equals(window.getComputedStyle(node3).color, window.getComputedStyle(node4).color); window.ops = document.getElementById('ops'); ops.style.color = 'red'; @@ -49,21 +49,19 @@ violetOps.style.background = 'rgb(238, 130, 238)'; document.getElementsByTagName('body')[0].appendChild(clonedOps); - shouldBeEqualToString("ops.style.background", ""); - debug("getComputedStyle(clonedOps).background: " + window.getComputedStyle(ops).background); - shouldBeEqualToString("ops.style.color", "red"); - shouldBeEqualToString("clonedOps.style.background", ""); - shouldBeEqualToString("violetOps.style.background", "rgb(238, 130, 238)"); + assert_equals(ops.style.background, ""); + assert_equals(ops.style.color, "red"); + assert_equals(clonedOps.style.background, ""); + assert_equals(violetOps.style.background, "rgb(238, 130, 238)"); - shouldBe("window.getComputedStyle(clonedOps).background", "window.getComputedStyle(ops).background"); - shouldBe("window.getComputedStyle(clonedOps).color", "window.getComputedStyle(ops).color"); - debug("getComputedStyle(violetOps).background: " + window.getComputedStyle(violetOps).background); - shouldNotBe("window.getComputedStyle(ops).background", "window.getComputedStyle(violetOps).background"); - shouldNotBe("window.getComputedStyle(clonedOps).background", "window.getComputedStyle(violetOps).background"); + assert_equals(window.getComputedStyle(clonedOps).background, window.getComputedStyle(ops).background); + assert_equals(window.getComputedStyle(clonedOps).color, window.getComputedStyle(ops).color); + assert_not_equals(window.getComputedStyle(ops).background, window.getComputedStyle(violetOps).background); + assert_not_equals(window.getComputedStyle(clonedOps).background, window.getComputedStyle(violetOps).background); - shouldBeEqualToString("ops.id", "ops"); - shouldBe("ops.id", "clonedOps.id"); - }; + assert_equals(ops.id, "ops"); + assert_equals(ops.id, clonedOps.id); + }); </script> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/printing/OWNERS b/third_party/WebKit/LayoutTests/printing/OWNERS index 7c1ec12..6904c86 100644 --- a/third_party/WebKit/LayoutTests/printing/OWNERS +++ b/third_party/WebKit/LayoutTests/printing/OWNERS
@@ -1,2 +1,2 @@ -# TEAM: layout-dev@chromium.org -# COMPONENT: Blink>Layout +# TEAM: paint-dev@chromium.org +# COMPONENT: Blink>Paint
diff --git a/third_party/WebKit/LayoutTests/virtual/android/url-bar/bottom-and-top-fixed-sticks-to-top-expected.html b/third_party/WebKit/LayoutTests/virtual/android/url-bar/bottom-and-top-fixed-sticks-to-top-expected.html new file mode 100644 index 0000000..a1f7dc7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/android/url-bar/bottom-and-top-fixed-sticks-to-top-expected.html
@@ -0,0 +1,28 @@ +<!DOCTYPE html> +<meta name="viewport" content="width=device-width, user-scalable=no" /> +<script> + // NOTE: It is important that this test be run with the Android viewport + // flags turned on. + if (window.internals) { + internals.settings.setHideScrollbars(true); + } +</script> +<style> + html, body { + height: 100%; + width: 100%; + margin: 0; + background-color: palegreen; + } + #bottom { + position: fixed; + right: 0px; + width: 200px; + top: 0px; + height: 500px; + background-color: coral; + } +</style> + +Test passes if the orange bar's top edge is at the top of the screen. +<div id="bottom"></div>
diff --git a/third_party/WebKit/LayoutTests/virtual/android/url-bar/bottom-and-top-fixed-sticks-to-top.html b/third_party/WebKit/LayoutTests/virtual/android/url-bar/bottom-and-top-fixed-sticks-to-top.html new file mode 100644 index 0000000..def9192 --- /dev/null +++ b/third_party/WebKit/LayoutTests/virtual/android/url-bar/bottom-and-top-fixed-sticks-to-top.html
@@ -0,0 +1,44 @@ +<!DOCTYPE html> +<meta name="viewport" content="width=device-width, user-scalable=no" /> +<script> + // NOTE: It is important that this test be run with the Android viewport + // flags turned on. + // Set the browser controls to be 100px and start off showing. Bring them in + // fully without causing a resize. i.e. as if the user dragged them into view + // but hasn't lifted their finger. + // This test verifies that a position: fixed element that has both |top| and + // |bottom| properties set sticks to the top of the screen, rather than the + // bottom. + if (window.internals) { + internals.setBrowserControlsShownRatio(1); + internals.setBrowserControlsState(100, 0, true); + internals.setBrowserControlsShownRatio(0); + internals.settings.setHideScrollbars(true); + } +</script> +<style> + html, body { + height: 100%; + width: 100%; + margin: 0; + } + #cover { + width: 100%; + /* Must be scrollable to force fixed elements to get a transform node. */ + height: 200%; + background-color: palegreen; + } + #bottom { + position: fixed; + right: 0px; + width: 200px; + top: 0px; + bottom: 0px; + background-color: coral; + } +</style> + +<div id="cover"> + Test passes if the orange bar's top edge is at the top of the screen. +</div> +<div id="bottom"></div>
diff --git a/third_party/blink/public/BUILD.gn b/third_party/blink/public/BUILD.gn index 739444e9..aeb5c2a 100644 --- a/third_party/blink/public/BUILD.gn +++ b/third_party/blink/public/BUILD.gn
@@ -245,6 +245,7 @@ "platform/web_encrypted_media_key_information.h", "platform/web_encrypted_media_request.h", "platform/web_encrypted_media_types.h", + "platform/web_file_system.h", "platform/web_file_system_type.h", "platform/web_file_utilities.h", "platform/web_float_point.h",
diff --git a/third_party/blink/public/mojom/filesystem/file_system.mojom b/third_party/blink/public/mojom/filesystem/file_system.mojom index d33a4ee..8a03eb6 100644 --- a/third_party/blink/public/mojom/filesystem/file_system.mojom +++ b/third_party/blink/public/mojom/filesystem/file_system.mojom
@@ -219,7 +219,9 @@ // success. // TODO(https://crbug.com/878581): Add more options to this method to support // multiple files, directories, "open" vs "save" dialogs, etc. - ChooseEntry() => + // TODO(https://crbug.com/873661): Make interface per frame/worker and remove + // |render_frame_id|. + ChooseEntry(int32 render_frame_id) => (mojo_base.mojom.FileError error_code, array<FileSystemEntry> entries); };
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h index 306e811..4ecca06 100644 --- a/third_party/blink/public/platform/platform.h +++ b/third_party/blink/public/platform/platform.h
@@ -102,6 +102,7 @@ class WebCookieJar; class WebCrypto; class WebDatabaseObserver; +class WebFileSystem; class WebGraphicsContext3DProvider; class WebImageCaptureFrameGrabber; class WebLocalFrame; @@ -278,6 +279,9 @@ // FileSystem ---------------------------------------------------------- + // Must return non-null. + virtual WebFileSystem* FileSystem() { return nullptr; } + // Return a filename-friendly identifier for an origin. virtual WebString FileSystemCreateOriginIdentifier( const WebSecurityOrigin& origin) {
diff --git a/third_party/blink/public/platform/web_file_system.h b/third_party/blink/public/platform/web_file_system.h new file mode 100644 index 0000000..87a373ac --- /dev/null +++ b/third_party/blink/public/platform/web_file_system.h
@@ -0,0 +1,67 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_FILE_SYSTEM_H_ +#define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_WEB_FILE_SYSTEM_H_ + +#include "base/files/file.h" +#include "mojo/public/cpp/system/message_pipe.h" +#include "third_party/blink/public/platform/web_callbacks.h" +#include "third_party/blink/public/platform/web_common.h" +#include "third_party/blink/public/platform/web_file_system_type.h" +#include "third_party/blink/public/platform/web_url.h" +#include "third_party/blink/public/platform/web_vector.h" + +namespace blink { + +class WebFrame; + +class WebFileSystem { + public: + struct FileSystemEntry { + WebString file_system_id; + WebString base_name; + }; + + // Prompts the user to select a file from the native filesystem. Returns an + // error code if something failed, or a list of the selected entries on + // success. + using ChooseEntryCallbacks = + WebCallbacks<WebVector<FileSystemEntry>, base::File::Error>; + virtual void ChooseEntry(WebFrame* frame, + std::unique_ptr<ChooseEntryCallbacks>) = 0; + + protected: + virtual ~WebFileSystem() = default; +}; + +} // namespace blink + +#endif
diff --git a/third_party/blink/public/web/web_dom_file_system.h b/third_party/blink/public/web/web_dom_file_system.h index f277aed..77ed4b6 100644 --- a/third_party/blink/public/web/web_dom_file_system.h +++ b/third_party/blink/public/web/web_dom_file_system.h
@@ -31,7 +31,7 @@ #define THIRD_PARTY_BLINK_PUBLIC_WEB_WEB_DOM_FILE_SYSTEM_H_ #include "third_party/blink/public/platform/web_common.h" -#include "third_party/blink/public/platform/web_file_system_type.h" +#include "third_party/blink/public/platform/web_file_system.h" #include "third_party/blink/public/platform/web_private_ptr.h" #include "third_party/blink/public/platform/web_string.h" #include "third_party/blink/public/platform/web_url.h"
diff --git a/third_party/blink/public/web/web_local_frame_client.h b/third_party/blink/public/web/web_local_frame_client.h index cb74488..7d18e0c 100644 --- a/third_party/blink/public/web/web_local_frame_client.h +++ b/third_party/blink/public/web/web_local_frame_client.h
@@ -47,6 +47,7 @@ #include "third_party/blink/public/platform/web_content_security_policy_struct.h" #include "third_party/blink/public/platform/web_content_settings_client.h" #include "third_party/blink/public/platform/web_effective_connection_type.h" +#include "third_party/blink/public/platform/web_file_system.h" #include "third_party/blink/public/platform/web_file_system_type.h" #include "third_party/blink/public/platform/web_insecure_request_policy.h" #include "third_party/blink/public/platform/web_loading_behavior_flag.h"
diff --git a/third_party/blink/renderer/controller/oom_intervention_impl.cc b/third_party/blink/renderer/controller/oom_intervention_impl.cc index 8eb5912..4bf6e8d8 100644 --- a/third_party/blink/renderer/controller/oom_intervention_impl.cc +++ b/third_party/blink/renderer/controller/oom_intervention_impl.cc
@@ -53,6 +53,7 @@ void OomInterventionImpl::Check(TimerBase*) { DCHECK(host_); + DCHECK(renderer_pause_enabled_ || navigate_ads_enabled_); OomInterventionMetrics current_memory = GetCurrentMemoryMetrics(); bool oom_detected = false; @@ -70,6 +71,9 @@ current_memory.current_vm_size_kb * 1024 > detection_args_->virtual_memory_thresold; + // Report memory stats every second to send UMA. + ReportMemoryStats(current_memory); + if (oom_detected) { if (navigate_ads_enabled_) { for (const auto& page : Page::OrdinaryPages()) { @@ -92,6 +96,24 @@ // intervention runs, as it indicates that memory usage is high. V8GCForContextDispose::Instance().SetForcePageNavigationGC(); } +} + +void OomInterventionImpl::ReportMemoryStats( + OomInterventionMetrics& current_memory) { + UMA_HISTOGRAM_MEMORY_MB( + "Memory.Experimental.OomIntervention.RendererBlinkUsage", + current_memory.current_blink_usage_kb / 1024); + UMA_HISTOGRAM_MEMORY_LARGE_MB( + "Memory.Experimental.OomIntervention." + "RendererPrivateMemoryFootprint", + current_memory.current_private_footprint_kb / 1024); + UMA_HISTOGRAM_MEMORY_MB( + "Memory.Experimental.OomIntervention.RendererSwapFootprint", + current_memory.current_swap_kb / 1024); + UMA_HISTOGRAM_MEMORY_LARGE_MB( + "Memory.Experimental.OomIntervention.RendererVmSize", + current_memory.current_vm_size_kb / 1024); + CrashMemoryMetricsReporterImpl::Instance().WriteIntoSharedMemory( current_memory); }
diff --git a/third_party/blink/renderer/controller/oom_intervention_impl.h b/third_party/blink/renderer/controller/oom_intervention_impl.h index a2113ac2..9fb26d81 100644 --- a/third_party/blink/renderer/controller/oom_intervention_impl.h +++ b/third_party/blink/renderer/controller/oom_intervention_impl.h
@@ -45,6 +45,8 @@ virtual OomInterventionMetrics GetCurrentMemoryMetrics(); void Check(TimerBase*); + void ReportMemoryStats(OomInterventionMetrics& current_memory); + mojom::blink::DetectionArgsPtr detection_args_; mojom::blink::OomInterventionHostPtr host_;
diff --git a/third_party/blink/renderer/controller/oom_intervention_impl_test.cc b/third_party/blink/renderer/controller/oom_intervention_impl_test.cc index 874409ff..aeb5f89 100644 --- a/third_party/blink/renderer/controller/oom_intervention_impl_test.cc +++ b/third_party/blink/renderer/controller/oom_intervention_impl_test.cc
@@ -242,8 +242,8 @@ MockOomInterventionHost mock_host(mojo::MakeRequest(&host_ptr)); mojom::blink::DetectionArgsPtr args(mojom::blink::DetectionArgs::New()); intervention_->StartDetection(std::move(host_ptr), std::move(args), - false /*renderer_pause_enabled*/, - false /*navigate_ads_enabled*/); + true /*renderer_pause_enabled*/, + true /*navigate_ads_enabled*/); // Create unsafe shared memory region to write metrics in reporter. base::UnsafeSharedMemoryRegion shm = base::UnsafeSharedMemoryRegion::Create(sizeof(OomInterventionMetrics));
diff --git a/third_party/blink/renderer/core/css/selector_checker.cc b/third_party/blink/renderer/core/css/selector_checker.cc index 1f579e95..ca097214 100644 --- a/third_party/blink/renderer/core/css/selector_checker.cc +++ b/third_party/blink/renderer/core/css/selector_checker.cc
@@ -1071,9 +1071,9 @@ return element == ToShadowRoot(context.scope)->host(); return context.scope == &element; case CSSSelector::kPseudoUnresolved: - return element.IsUnresolvedV0CustomElement(); + return !element.IsDefined() && element.IsUnresolvedV0CustomElement(); case CSSSelector::kPseudoDefined: - return element.IsDefined(); + return element.IsDefined() || element.IsUpgradedV0CustomElement(); case CSSSelector::kPseudoHost: case CSSSelector::kPseudoHostContext: return CheckPseudoHost(context, result);
diff --git a/third_party/blink/renderer/core/dom/raw_data_document_parser.h b/third_party/blink/renderer/core/dom/raw_data_document_parser.h index 19277f7..2813444 100644 --- a/third_party/blink/renderer/core/dom/raw_data_document_parser.h +++ b/third_party/blink/renderer/core/dom/raw_data_document_parser.h
@@ -37,8 +37,10 @@ : DocumentParser(document) {} void Finish() override { - if (!IsStopped()) + if (!IsStopped()) { + GetDocument()->SetReadyState(Document::kInteractive); GetDocument()->FinishedParsing(); + } } private:
diff --git a/third_party/blink/renderer/core/editing/layout_selection.cc b/third_party/blink/renderer/core/editing/layout_selection.cc index 8e7dec9..78a04405 100644 --- a/third_party/blink/renderer/core/editing/layout_selection.cc +++ b/third_party/blink/renderer/core/editing/layout_selection.cc
@@ -445,14 +445,6 @@ return ToText(node).length(); } -static void MarkSelected(HeapHashSet<Member<const Node>>* selected_objects, - const Node& node, - SelectionState state) { - DCHECK(node.GetLayoutObject()->CanBeSelectionLeaf()); - SetSelectionStateIfNeeded(node, state); - selected_objects->insert(&node); -} - #if DCHECK_IS_ON() // Position should be offset on text or before/after a break element. static bool IsPositionValidText(const Position& position) { @@ -515,10 +507,9 @@ return GetTextContentOffset(Position::AfterNode(node)); } -static NewPaintRangeAndSelectedNodes ComputeNewPaintRange( - NewPaintRangeAndSelectedNodes* new_range) { - const SelectionPaintRange& paint_range = *new_range->paint_range; - DCHECK(!paint_range.IsNull()) << new_range; +static SelectionPaintRange* ComputeNewPaintRange( + const SelectionPaintRange& paint_range) { + DCHECK(!paint_range.IsNull()); const Node& start_node = *paint_range.start_node; // If LayoutObject is not in NG, use legacy offset. @@ -533,9 +524,8 @@ ? GetTextContentOffsetEnd(end_node, paint_range.end_offset) : paint_range.end_offset; - return {new SelectionPaintRange(*paint_range.start_node, start_offset, - *paint_range.end_node, end_offset), - std::move(new_range->selected_objects)}; + return new SelectionPaintRange(*paint_range.start_node, start_offset, + *paint_range.end_node, end_offset); } // ClampOffset modifies |offset| fixed in a range of |text_fragment| start/end @@ -755,8 +745,10 @@ // In this loop, |end_node| is pointing current last candidate // LayoutObject and if it is not start and we find next, we mark the // current one as kInside. - if (end_node != start_node) - MarkSelected(&selected_objects, *end_node, SelectionState::kInside); + if (end_node != start_node) { + SetSelectionStateIfNeeded(*end_node, SelectionState::kInside); + selected_objects.insert(end_node); + } end_node = &node; } @@ -772,18 +764,20 @@ const base::Optional<unsigned> end_offset = ComputeEndOffset(*end_node, selection.EndPosition().ToOffsetInAnchor()); if (start_node == end_node) { - MarkSelected(&selected_objects, *start_node, SelectionState::kStartAndEnd); + SetSelectionStateIfNeeded(*start_node, SelectionState::kStartAndEnd); + selected_objects.insert(start_node); } else { - MarkSelected(&selected_objects, *start_node, SelectionState::kStart); - MarkSelected(&selected_objects, *end_node, SelectionState::kEnd); + SetSelectionStateIfNeeded(*start_node, SelectionState::kStart); + selected_objects.insert(start_node); + SetSelectionStateIfNeeded(*end_node, SelectionState::kEnd); + selected_objects.insert(end_node); } - NewPaintRangeAndSelectedNodes new_range = { - new SelectionPaintRange(*start_node, start_offset, *end_node, end_offset), - std::move(selected_objects)}; + SelectionPaintRange* new_range = + new SelectionPaintRange(*start_node, start_offset, *end_node, end_offset); if (!RuntimeEnabledFeatures::LayoutNGEnabled()) - return new_range; - return ComputeNewPaintRange(&new_range); + return {new_range, std::move(selected_objects)}; + return {ComputeNewPaintRange(*new_range), std::move(selected_objects)}; } void LayoutSelection::SetHasPendingSelection() {
diff --git a/third_party/blink/renderer/core/frame/deprecation.cc b/third_party/blink/renderer/core/frame/deprecation.cc index c5a5b1b..aa7481e 100644 --- a/third_party/blink/renderer/core/frame/deprecation.cc +++ b/third_party/blink/renderer/core/frame/deprecation.cc
@@ -601,6 +601,11 @@ "worker installation", kM71, "5748516353736704")}; + case WebFeature::kCacheStorageAddAllSuccessWithDuplicate: + return {"CacheStorageAddAllSuccessWithDuplicate", kM72, + WillBeRemoved("Cache.addAll() with duplicate requests", kM72, + "5622587912617984")}; + // Features that aren't deprecated don't have a deprecation message. default: return {"NotDeprecated", kUnknown, ""};
diff --git a/third_party/blink/renderer/core/frame/deprecation.h b/third_party/blink/renderer/core/frame/deprecation.h index 766325d..6ff0372 100644 --- a/third_party/blink/renderer/core/frame/deprecation.h +++ b/third_party/blink/renderer/core/frame/deprecation.h
@@ -39,9 +39,6 @@ // Be considerate to developers' consoles: features should only send // deprecation warnings when we're actively interested in removing them from // the platform. - // - // For shared workers and service workers, the ExecutionContext* overload - // doesn't count the usage but only sends a console warning. static void CountDeprecation(const LocalFrame*, WebFeature); static void CountDeprecation(ExecutionContext*, WebFeature); static void CountDeprecation(const Document&, WebFeature);
diff --git a/third_party/blink/renderer/core/html/image_document.cc b/third_party/blink/renderer/core/html/image_document.cc index 2bde271..06eec5f 100644 --- a/third_party/blink/renderer/core/html/image_document.cc +++ b/third_party/blink/renderer/core/html/image_document.cc
@@ -177,8 +177,10 @@ GetDocument()->ImageLoaded(); } - if (!IsDetached()) + if (!IsDetached()) { + GetDocument()->SetReadyState(Document::kInteractive); GetDocument()->FinishedParsing(); + } } // --------
diff --git a/third_party/blink/renderer/core/html/image_document_test.cc b/third_party/blink/renderer/core/html/image_document_test.cc index 4a293f7..fb661d20 100644 --- a/third_party/blink/renderer/core/html/image_document_test.cc +++ b/third_party/blink/renderer/core/html/image_document_test.cc
@@ -214,6 +214,11 @@ EXPECT_EQ(50, ImageHeight()); } +TEST_F(ImageDocumentTest, DomInteractive) { + CreateDocument(25, 30); + EXPECT_FALSE(GetDocument().GetTiming().DomInteractive().is_null()); +} + #if defined(OS_ANDROID) #define MAYBE(test) DISABLED_##test #else
diff --git a/third_party/blink/renderer/core/html/media/html_media_element_test.cc b/third_party/blink/renderer/core/html/media/html_media_element_test.cc index ac6c5c41..bd081d81 100644 --- a/third_party/blink/renderer/core/html/media/html_media_element_test.cc +++ b/third_party/blink/renderer/core/html/media/html_media_element_test.cc
@@ -462,4 +462,8 @@ EXPECT_EQ(HasLazyLoadObserver(), GetParam() == MediaTestParam::kVideo); } +TEST_P(HTMLMediaElementTest, DomInteractive) { + EXPECT_FALSE(Media()->GetDocument().GetTiming().DomInteractive().is_null()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc index d90a3946..c238218 100644 --- a/third_party/blink/renderer/core/inspector/inspector_page_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_page_agent.cc
@@ -70,8 +70,6 @@ #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/core/style/computed_style.h" #include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h" -#include "third_party/blink/renderer/platform/json/json_parser.h" -#include "third_party/blink/renderer/platform/json/json_values.h" #include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h" #include "third_party/blink/renderer/platform/loader/fetch/resource.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" @@ -465,6 +463,8 @@ bypass_csp_enabled_(&agent_state_, /*default_value=*/false), scripts_to_evaluate_on_load_(&agent_state_, /*default_value=*/WTF::String()), + worlds_to_evaluate_on_load_(&agent_state_, + /*default_value=*/WTF::String()), standard_font_family_(&agent_state_, /*default_value=*/WTF::String()), fixed_font_family_(&agent_state_, /*default_value=*/WTF::String()), serif_font_family_(&agent_state_, /*default_value=*/WTF::String()), @@ -565,10 +565,8 @@ *identifier = String::Number(Decimal::FromString(*result).ToDouble() + 1); } - std::unique_ptr<JSONObject> script = JSONObject::Create(); - script->SetString("source", source); - script->SetString("world_name", world_name.fromMaybe("")); - scripts_to_evaluate_on_load_.Set(*identifier, script->ToJSONString()); + scripts_to_evaluate_on_load_.Set(*identifier, source); + worlds_to_evaluate_on_load_.Set(*identifier, world_name.fromMaybe("")); return Response::OK(); } @@ -577,6 +575,7 @@ if (scripts_to_evaluate_on_load_.Get(identifier).IsNull()) return Response::Error("Script not found"); scripts_to_evaluate_on_load_.Clear(identifier); + worlds_to_evaluate_on_load_.Clear(identifier); return Response::OK(); } @@ -853,13 +852,8 @@ HashMap<String, int> world_id_by_name; for (const WTF::String& key : keys) { - const String script = scripts_to_evaluate_on_load_.Get(key); - std::unique_ptr<JSONObject> object = JSONObject::From(ParseJSON(script)); - String source; - DCHECK(object->GetString("source", &source)); - String world_name; - DCHECK(object->GetString("world_name", &world_name)); - + const String source = scripts_to_evaluate_on_load_.Get(key); + const String world_name = worlds_to_evaluate_on_load_.Get(key); if (world_name.IsEmpty()) { frame->GetScriptController().ExecuteScriptInMainWorld(source); continue;
diff --git a/third_party/blink/renderer/core/inspector/inspector_page_agent.h b/third_party/blink/renderer/core/inspector/inspector_page_agent.h index f099ed6..d241417c 100644 --- a/third_party/blink/renderer/core/inspector/inspector_page_agent.h +++ b/third_party/blink/renderer/core/inspector/inspector_page_agent.h
@@ -250,6 +250,7 @@ InspectorAgentState::Boolean lifecycle_events_enabled_; InspectorAgentState::Boolean bypass_csp_enabled_; InspectorAgentState::StringMap scripts_to_evaluate_on_load_; + InspectorAgentState::StringMap worlds_to_evaluate_on_load_; InspectorAgentState::String standard_font_family_; InspectorAgentState::String fixed_font_family_; InspectorAgentState::String serif_font_family_;
diff --git a/third_party/blink/renderer/core/layout/min_max_size.cc b/third_party/blink/renderer/core/layout/min_max_size.cc index c5f1075..c501516 100644 --- a/third_party/blink/renderer/core/layout/min_max_size.cc +++ b/third_party/blink/renderer/core/layout/min_max_size.cc
@@ -8,6 +8,11 @@ namespace blink { +void MinMaxSize::Encompass(const MinMaxSize& other) { + min_size = std::max(min_size, other.min_size); + max_size = std::max(max_size, other.max_size); +} + void MinMaxSize::Encompass(LayoutUnit value) { min_size = std::max(min_size, value); max_size = std::max(max_size, value);
diff --git a/third_party/blink/renderer/core/layout/min_max_size.h b/third_party/blink/renderer/core/layout/min_max_size.h index e52c9f2..b17ecb6 100644 --- a/third_party/blink/renderer/core/layout/min_max_size.h +++ b/third_party/blink/renderer/core/layout/min_max_size.h
@@ -17,6 +17,9 @@ LayoutUnit min_size; LayoutUnit max_size; + // Make sure that our min/max sizes are at least as large as |other|. + void Encompass(const MinMaxSize& other); + // Make sure that our min/max sizes are at least as large as |value|. void Encompass(LayoutUnit value); @@ -36,6 +39,11 @@ } void operator=(LayoutUnit value) { min_size = max_size = value; } + MinMaxSize& operator+=(MinMaxSize extra) { + min_size += extra.min_size; + max_size += extra.max_size; + return *this; + } MinMaxSize& operator+=(const LayoutUnit); MinMaxSize& operator-=(const LayoutUnit); };
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc index 8c3010b..99fa9756 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm.cc
@@ -14,6 +14,7 @@ #include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h" #include "third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.h" #include "third_party/blink/renderer/core/layout/ng/ng_physical_box_fragment.h" +#include "third_party/blink/renderer/core/layout/ng/ng_space_utils.h" namespace blink { @@ -137,8 +138,56 @@ base::Optional<MinMaxSize> NGFieldsetLayoutAlgorithm::ComputeMinMaxSize( const MinMaxSizeInput& input) const { - // TODO(mstensho): Implement min/max - return MinMaxSize(); + MinMaxSize sizes; + + // Size-contained elements don't consider their contents for intrinsic sizing. + if (node_.ShouldApplySizeContainment()) + return sizes; + + if (NGBlockNode legend = Node().GetRenderedLegend()) { + // We'll need extrinsic sizing data when computing min/max for orthogonal + // flow roots, because calculating min/max in that case will involve doing + // layout. Note that we only need to do this for the legend, and not for the + // fieldset contents. The contents child is just an anonymous one, which + // inherits writing-mode from the fieldset, so it can never be a writing + // mode root. + NGConstraintSpace extrinsic_constraint_space; + const NGConstraintSpace* optional_constraint_space = nullptr; + if (!IsParallelWritingMode(Style().GetWritingMode(), + legend.Style().GetWritingMode())) { + NGBoxStrut border_padding = ComputeBorders(ConstraintSpace(), Node()) + + ComputePadding(ConstraintSpace(), Style()); + // If there is a resolvable extrinsic block size, use that as input. + // Otherwise we'll fall back to the initial containing block size as a + // constraint. + LayoutUnit extrinsic_block_size = ComputeBlockSizeForFragment( + ConstraintSpace(), Style(), NGSizeIndefinite, border_padding); + if (extrinsic_block_size != NGSizeIndefinite) { + extrinsic_block_size -= border_padding.BlockSum(); + extrinsic_block_size = extrinsic_block_size.ClampNegativeToZero(); + } + extrinsic_constraint_space = CreateExtrinsicConstraintSpaceForChild( + ConstraintSpace(), extrinsic_block_size, legend); + optional_constraint_space = &extrinsic_constraint_space; + } + sizes = ComputeMinAndMaxContentContribution( + Style().GetWritingMode(), legend, input, optional_constraint_space); + sizes += ComputeMinMaxMargins(Style(), legend).InlineSum(); + } + // The fieldset content includes the fieldset padding (and any scrollbars), + // while the legend is a regular child and doesn't. We may have a fieldset + // without any content or legend, so add the padding here, on the outside. + sizes += ComputePadding(ConstraintSpace(), node_.Style()).InlineSum(); + + if (NGBlockNode content = Node().GetFieldsetContent()) { + MinMaxSize content_minmax = ComputeMinAndMaxContentContribution( + Style().GetWritingMode(), content, input); + content_minmax += ComputeMinMaxMargins(Style(), content).InlineSum(); + sizes.Encompass(content_minmax); + } + + sizes += ComputeBorders(ConstraintSpace(), node_.Style()).InlineSum(); + return sizes; } const NGConstraintSpace
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc index f964d04..22ce230d 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_fieldset_layout_algorithm_test.cc
@@ -47,6 +47,24 @@ return RunBlockLayoutAlgorithm(space, container); } + MinMaxSize RunComputeMinAndMax(NGBlockNode node) { + NGConstraintSpace space = ConstructBlockLayoutTestConstraintSpace( + WritingMode::kHorizontalTb, TextDirection::kLtr, + NGLogicalSize(LayoutUnit(), LayoutUnit())); + + NGFieldsetLayoutAlgorithm algorithm(node, space); + MinMaxSizeInput input; + auto min_max = algorithm.ComputeMinMaxSize(input); + EXPECT_TRUE(min_max.has_value()); + return *min_max; + } + + MinMaxSize RunComputeMinAndMax(const char* element_id) { + Element* element = GetDocument().getElementById(element_id); + NGBlockNode node(ToLayoutBox(element->GetLayoutObject())); + return RunComputeMinAndMax(node); + } + String DumpFragmentTree(const NGPhysicalBoxFragment* fragment) { NGPhysicalFragment::DumpFlags flags = NGPhysicalFragment::DumpHeaderText | NGPhysicalFragment::DumpSubtree | @@ -438,5 +456,71 @@ EXPECT_EQ(expectation, dump); } +TEST_F(NGFieldsetLayoutAlgorithmTest, MinMax) { + SetBodyInnerHTML(R"HTML( + <style> + fieldset { margin:123px; border:3px solid; padding:10px; width:100px; } + legend { margin:20px; border:11px solid; padding:7px; } + .float { float:left; width:50px; height:50px; } + </style> + <div id="container"> + <fieldset id="fieldset1"></fieldset> + <fieldset id="fieldset2"> + <legend></legend> + </fieldset> + <fieldset id="fieldset3"> + <legend></legend> + <div class="float"></div> + <div class="float"></div> + </fieldset> + <fieldset id="fieldset4"> + <legend> + <div class="float"></div> + <div class="float"></div> + </legend> + <div class="float"></div> + </fieldset> + <fieldset id="fieldset5"> + <legend> + <div class="float"></div> + </legend> + <div class="float"></div> + <div class="float"></div> + <div class="float"></div> + </fieldset> + <fieldset id="fieldset6"> + <div class="float"></div> + <div class="float"></div> + </fieldset> + </div> + )HTML"); + + MinMaxSize size; + + size = RunComputeMinAndMax("fieldset1"); + EXPECT_EQ(size.min_size, LayoutUnit(26)); + EXPECT_EQ(size.max_size, LayoutUnit(26)); + + size = RunComputeMinAndMax("fieldset2"); + EXPECT_EQ(size.min_size, LayoutUnit(102)); + EXPECT_EQ(size.max_size, LayoutUnit(102)); + + size = RunComputeMinAndMax("fieldset3"); + EXPECT_EQ(size.min_size, LayoutUnit(102)); + EXPECT_EQ(size.max_size, LayoutUnit(126)); + + size = RunComputeMinAndMax("fieldset4"); + EXPECT_EQ(size.min_size, LayoutUnit(152)); + EXPECT_EQ(size.max_size, LayoutUnit(202)); + + size = RunComputeMinAndMax("fieldset5"); + EXPECT_EQ(size.min_size, LayoutUnit(152)); + EXPECT_EQ(size.max_size, LayoutUnit(176)); + + size = RunComputeMinAndMax("fieldset6"); + EXPECT_EQ(size.min_size, LayoutUnit(76)); + EXPECT_EQ(size.max_size, LayoutUnit(126)); +} + } // anonymous namespace } // namespace blink
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.cc b/third_party/blink/renderer/core/page/chrome_client_impl.cc index f6f721d..c34ed36 100644 --- a/third_party/blink/renderer/core/page/chrome_client_impl.cc +++ b/third_party/blink/renderer/core/page/chrome_client_impl.cc
@@ -837,7 +837,6 @@ void ChromeClientImpl::SetBrowserControlsShownRatio(float ratio) { web_view_->GetBrowserControls().SetShownRatio(ratio); - web_view_->DidUpdateBrowserControls(); } bool ChromeClientImpl::ShouldOpenModalDialogDuringPageDismissal(
diff --git a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc index 59c602f..c2a44df0 100644 --- a/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc +++ b/third_party/blink/renderer/core/page/scrolling/scrolling_coordinator.cc
@@ -309,7 +309,7 @@ if (layer->GetLayoutObject().Style()->GetPosition() == EPosition::kFixed) { const LayoutObject& fixed_position_object = layer->GetLayoutObject(); bool fixed_to_right = !fixed_position_object.Style()->Right().IsAuto(); - bool fixed_to_bottom = !fixed_position_object.Style()->Bottom().IsAuto(); + bool fixed_to_bottom = fixed_position_object.Style()->IsFixedToBottom(); cc::LayerPositionConstraint constraint; constraint.set_is_fixed_position(true); constraint.set_is_fixed_to_right_edge(fixed_to_right);
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc index ae0fc6c..042af92 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -137,6 +137,7 @@ ALWAYS_INLINE void UpdateStickyTranslation(); ALWAYS_INLINE void UpdateTransform(); ALWAYS_INLINE void UpdateTransformForNonRootSVG(); + ALWAYS_INLINE bool EffectCanUseCurrentClipAsOutputClip() const; ALWAYS_INLINE void UpdateEffect(); ALWAYS_INLINE void UpdateLinkHighlightEffect(); ALWAYS_INLINE void UpdateFilter(); @@ -376,7 +377,7 @@ state.affected_by_outer_viewport_bounds_delta = object_.StyleRef().GetPosition() == EPosition::kFixed && - !object_.StyleRef().Bottom().IsAuto(); + object_.StyleRef().IsFixedToBottom(); if (RuntimeEnabledFeatures::SlimmingPaintV2Enabled() || RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) @@ -734,26 +735,35 @@ // An effect node can use the current clip as its output clip if the clip won't // end before the effect ends. Having explicit output clip can let the later // stages use more optimized code path. -static bool EffectCanUseCurrentClipAsOutputClip(const LayoutObject& object) { - DCHECK(NeedsEffect(object)); +bool FragmentPaintPropertyTreeBuilder::EffectCanUseCurrentClipAsOutputClip() + const { + DCHECK(NeedsEffect(object_)); - if (!object.HasLayer()) { + if (!object_.HasLayer()) { // An SVG object's effect never interleaves with clips. - DCHECK(object.IsSVG()); + DCHECK(object_.IsSVG()); return true; } - const auto* layer = ToLayoutBoxModelObject(object).Layer(); + const auto* layer = ToLayoutBoxModelObject(object_).Layer(); // Out-of-flow descendants not contained by this object may escape clips. - if (layer->HasNonContainedAbsolutePositionDescendant()) + if (layer->HasNonContainedAbsolutePositionDescendant() && + object_.ContainingBlockForAbsolutePosition() + ->FirstFragment() + .PostOverflowClip() != context_.current.clip) return false; if (layer->HasFixedPositionDescendant() && - !object.CanContainFixedPositionObjects()) + !object_.CanContainFixedPositionObjects() && + object_.ContainingBlockForFixedPosition() + ->FirstFragment() + .PostOverflowClip() != context_.current.clip) return false; + // Some descendants under a pagination container (e.g. composited objects // in SPv1 and column spanners) may escape fragment clips. if (layer->EnclosingPaginationLayer()) return false; + return true; } @@ -790,7 +800,7 @@ clip_path_clip = IntRect(); } - const auto* output_clip = EffectCanUseCurrentClipAsOutputClip(object_) + const auto* output_clip = EffectCanUseCurrentClipAsOutputClip() ? context_.current.clip : nullptr;
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc index de451e17..63918af 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
@@ -950,7 +950,8 @@ const ObjectPaintProperties* node_with_opacity_properties = node_with_opacity->FirstFragment().PaintProperties(); EXPECT_EQ(0.6f, node_with_opacity_properties->Effect()->Opacity()); - EXPECT_EQ(nullptr, node_with_opacity_properties->Effect()->OutputClip()); + EXPECT_EQ(DocContentClip(), + node_with_opacity_properties->Effect()->OutputClip()); EXPECT_NE(nullptr, node_with_opacity_properties->Effect()->Parent()); EXPECT_EQ(nullptr, node_with_opacity_properties->Transform()); CHECK_EXACT_VISUAL_RECT(LayoutRect(8, 8, 100, 200), node_with_opacity,
diff --git a/third_party/blink/renderer/core/paint/table_row_painter.cc b/third_party/blink/renderer/core/paint/table_row_painter.cc index a518a76..8a82fd6 100644 --- a/third_party/blink/renderer/core/paint/table_row_painter.cc +++ b/third_party/blink/renderer/core/paint/table_row_painter.cc
@@ -134,6 +134,7 @@ void TableRowPainter::PaintCollapsedBorders(const PaintInfo& paint_info, const CellSpan& dirtied_columns) { + ScopedPaintState paint_state(layout_table_row_, paint_info); base::Optional<DrawingRecorder> recorder; if (LIKELY(!layout_table_row_.Table()->ShouldPaintAllCollapsedBorders())) { @@ -153,8 +154,10 @@ unsigned row = layout_table_row_.RowIndex(); for (unsigned c = std::min(dirtied_columns.End(), section->NumCols(row)); c > dirtied_columns.Start(); c--) { - if (const auto* cell = section->OriginatingCellAt(row, c - 1)) - CollapsedBorderPainter(*cell).PaintCollapsedBorders(paint_info); + if (const auto* cell = section->OriginatingCellAt(row, c - 1)) { + CollapsedBorderPainter(*cell).PaintCollapsedBorders( + paint_state.GetPaintInfo()); + } } }
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h index 8fe67bb4..31420083 100644 --- a/third_party/blink/renderer/core/style/computed_style.h +++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -381,6 +381,10 @@ return static_cast<EFillBox>(BackgroundInternal().Clip()); } + // Returns true if the Element should stick to the viewport bottom as the URL + // bar hides. + bool IsFixedToBottom() const { return !Bottom().IsAuto() && Top().IsAuto(); } + // Border properties. // border-image-slice const LengthBox& BorderImageSlices() const {
diff --git a/third_party/blink/renderer/devtools/BUILD.gn b/third_party/blink/renderer/devtools/BUILD.gn index e607430..60a3909 100644 --- a/third_party/blink/renderer/devtools/BUILD.gn +++ b/third_party/blink/renderer/devtools/BUILD.gn
@@ -509,11 +509,12 @@ "front_end/profiler/CPUProfileView.js", "front_end/profiler/heapProfiler.css", "front_end/profiler/HeapProfileView.js", + "front_end/profiler/HeapProfilerPanel.js", "front_end/profiler/HeapSnapshotDataGrids.js", "front_end/profiler/HeapSnapshotGridNodes.js", "front_end/profiler/HeapSnapshotProxy.js", "front_end/profiler/HeapSnapshotView.js", - "front_end/profiler/HeapProfilerPanel.js", + "front_end/profiler/HeapTimelineOverview.js", "front_end/profiler/IsolateSelector.js", "front_end/profiler/module.json", "front_end/profiler/ProfileDataGrid.js",
diff --git a/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js b/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js index 84fd1dc..a9f19d78 100644 --- a/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js +++ b/third_party/blink/renderer/devtools/front_end/profiler/HeapSnapshotView.js
@@ -52,9 +52,9 @@ const isHeapTimeline = profile.profileType().id === Profiler.TrackingHeapSnapshotProfileType.TypeId; if (isHeapTimeline) { - this._trackingOverviewGrid = new Profiler.HeapTrackingOverviewGrid(profile); + this._trackingOverviewGrid = new Profiler.HeapTimelineOverview(profile); this._trackingOverviewGrid.addEventListener( - Profiler.HeapTrackingOverviewGrid.IdsRangeChanged, this._onIdsRangeChanged.bind(this)); + Profiler.HeapTimelineOverview.IdsRangeChanged, this._onIdsRangeChanged.bind(this)); } this._parentDataDisplayDelegate = dataDisplayDelegate; @@ -233,14 +233,14 @@ if (this._profile.profileType().id === Profiler.TrackingHeapSnapshotProfileType.TypeId && this._profile.fromFile()) { const samples = await heapSnapshotProxy.getSamples(); - this._trackingOverviewGrid._setSamples(samples); + this._trackingOverviewGrid.setSamples(samples); } const list = this._profiles(); const profileIndex = list.indexOf(this._profile); this._baseSelect.setSelectedIndex(Math.max(0, profileIndex - 1)); if (this._trackingOverviewGrid) - this._trackingOverviewGrid._updateGrid(); + this._trackingOverviewGrid.updateGrid(); } /** @@ -795,7 +795,7 @@ heapSnapshotView._trackingOverviewGrid.show( heapSnapshotView._searchableView.element, heapSnapshotView._splitWidget.element); heapSnapshotView._trackingOverviewGrid.update(); - heapSnapshotView._trackingOverviewGrid._updateGrid(); + heapSnapshotView._trackingOverviewGrid.updateGrid(); } /** @@ -1585,368 +1585,6 @@ /** * @unrestricted */ -Profiler.HeapTrackingOverviewGrid = class extends UI.VBox { - /** - * @param {!Profiler.HeapProfileHeader} heapProfileHeader - */ - constructor(heapProfileHeader) { - super(); - this.element.id = 'heap-recording-view'; - this.element.classList.add('heap-tracking-overview'); - - this._overviewContainer = this.element.createChild('div', 'heap-overview-container'); - this._overviewGrid = new PerfUI.OverviewGrid('heap-recording'); - this._overviewGrid.element.classList.add('fill'); - - this._overviewCanvas = this._overviewContainer.createChild('canvas', 'heap-recording-overview-canvas'); - this._overviewContainer.appendChild(this._overviewGrid.element); - this._overviewCalculator = new Profiler.HeapTrackingOverviewGrid.OverviewCalculator(); - this._overviewGrid.addEventListener(PerfUI.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this); - - this._profileSamples = heapProfileHeader.fromFile() ? new Profiler.TrackingHeapSnapshotProfileType.Samples() : - heapProfileHeader._profileSamples; - this._profileType = heapProfileHeader.profileType(); - if (!heapProfileHeader.fromFile() && heapProfileHeader.profileType().profileBeingRecorded() === heapProfileHeader) { - this._profileType.addEventListener( - Profiler.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this); - this._profileType.addEventListener( - Profiler.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this); - } - this._windowLeft = 0.0; - this._windowRight = 1.0; - this._overviewGrid.setWindow(this._windowLeft, this._windowRight); - this._yScale = new Profiler.HeapTrackingOverviewGrid.SmoothScale(); - this._xScale = new Profiler.HeapTrackingOverviewGrid.SmoothScale(); - } - - dispose() { - this._onStopTracking(); - } - - _onStopTracking() { - this._profileType.removeEventListener( - Profiler.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this); - this._profileType.removeEventListener( - Profiler.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this); - } - - /** - * @param {!Common.Event} event - */ - _onHeapStatsUpdate(event) { - this._profileSamples = event.data; - this._scheduleUpdate(); - } - - /** - * @param {?HeapSnapshotModel.Samples} samples - */ - _setSamples(samples) { - if (!samples) - return; - console.assert(!this._profileSamples.timestamps.length, 'Should only call this method when loading from file.'); - console.assert(samples.timestamps.length); - this._profileSamples = new Profiler.TrackingHeapSnapshotProfileType.Samples(); - this._profileSamples.sizes = samples.sizes; - this._profileSamples.ids = samples.lastAssignedIds; - this._profileSamples.timestamps = samples.timestamps; - this._profileSamples.max = samples.sizes; - this._profileSamples.totalTime = /** @type{number} */ (samples.timestamps.peekLast()); - this.update(); - } - - /** - * @param {number} width - * @param {number} height - */ - _drawOverviewCanvas(width, height) { - if (!this._profileSamples) - return; - const profileSamples = this._profileSamples; - const sizes = profileSamples.sizes; - const topSizes = profileSamples.max; - const timestamps = profileSamples.timestamps; - const startTime = timestamps[0]; - const endTime = timestamps[timestamps.length - 1]; - - const scaleFactor = this._xScale.nextScale(width / profileSamples.totalTime); - let maxSize = 0; - /** - * @param {!Array.<number>} sizes - * @param {function(number, number):void} callback - */ - function aggregateAndCall(sizes, callback) { - let size = 0; - let currentX = 0; - for (let i = 1; i < timestamps.length; ++i) { - const x = Math.floor((timestamps[i] - startTime) * scaleFactor); - if (x !== currentX) { - if (size) - callback(currentX, size); - size = 0; - currentX = x; - } - size += sizes[i]; - } - callback(currentX, size); - } - - /** - * @param {number} x - * @param {number} size - */ - function maxSizeCallback(x, size) { - maxSize = Math.max(maxSize, size); - } - - aggregateAndCall(sizes, maxSizeCallback); - - const yScaleFactor = this._yScale.nextScale(maxSize ? height / (maxSize * 1.1) : 0.0); - - this._overviewCanvas.width = width * window.devicePixelRatio; - this._overviewCanvas.height = height * window.devicePixelRatio; - this._overviewCanvas.style.width = width + 'px'; - this._overviewCanvas.style.height = height + 'px'; - - const context = this._overviewCanvas.getContext('2d'); - context.scale(window.devicePixelRatio, window.devicePixelRatio); - - context.beginPath(); - context.lineWidth = 2; - context.strokeStyle = 'rgba(192, 192, 192, 0.6)'; - const currentX = (endTime - startTime) * scaleFactor; - context.moveTo(currentX, height - 1); - context.lineTo(currentX, 0); - context.stroke(); - context.closePath(); - - let gridY; - let gridValue; - const gridLabelHeight = 14; - if (yScaleFactor) { - const maxGridValue = (height - gridLabelHeight) / yScaleFactor; - // The round value calculation is a bit tricky, because - // it has a form k*10^n*1024^m, where k=[1,5], n=[0..3], m is an integer, - // e.g. a round value 10KB is 10240 bytes. - gridValue = Math.pow(1024, Math.floor(Math.log(maxGridValue) / Math.log(1024))); - gridValue *= Math.pow(10, Math.floor(Math.log(maxGridValue / gridValue) / Math.LN10)); - if (gridValue * 5 <= maxGridValue) - gridValue *= 5; - gridY = Math.round(height - gridValue * yScaleFactor - 0.5) + 0.5; - context.beginPath(); - context.lineWidth = 1; - context.strokeStyle = 'rgba(0, 0, 0, 0.2)'; - context.moveTo(0, gridY); - context.lineTo(width, gridY); - context.stroke(); - context.closePath(); - } - - /** - * @param {number} x - * @param {number} size - */ - function drawBarCallback(x, size) { - context.moveTo(x, height - 1); - context.lineTo(x, Math.round(height - size * yScaleFactor - 1)); - } - - context.beginPath(); - context.lineWidth = 2; - context.strokeStyle = 'rgba(192, 192, 192, 0.6)'; - aggregateAndCall(topSizes, drawBarCallback); - context.stroke(); - context.closePath(); - - context.beginPath(); - context.lineWidth = 2; - context.strokeStyle = 'rgba(0, 0, 192, 0.8)'; - aggregateAndCall(sizes, drawBarCallback); - context.stroke(); - context.closePath(); - - if (gridValue) { - const label = Number.bytesToString(gridValue); - const labelPadding = 4; - const labelX = 0; - const labelY = gridY - 0.5; - const labelWidth = 2 * labelPadding + context.measureText(label).width; - context.beginPath(); - context.textBaseline = 'bottom'; - context.font = '10px ' + window.getComputedStyle(this.element, null).getPropertyValue('font-family'); - context.fillStyle = 'rgba(255, 255, 255, 0.75)'; - context.fillRect(labelX, labelY - gridLabelHeight, labelWidth, gridLabelHeight); - context.fillStyle = 'rgb(64, 64, 64)'; - context.fillText(label, labelX + labelPadding, labelY); - context.fill(); - context.closePath(); - } - } - - /** - * @override - */ - onResize() { - this._updateOverviewCanvas = true; - this._scheduleUpdate(); - } - - _onWindowChanged() { - if (!this._updateGridTimerId) - this._updateGridTimerId = setTimeout(this._updateGrid.bind(this), 10); - } - - _scheduleUpdate() { - if (this._updateTimerId) - return; - this._updateTimerId = setTimeout(this.update.bind(this), 10); - } - - _updateBoundaries() { - this._windowLeft = this._overviewGrid.windowLeft(); - this._windowRight = this._overviewGrid.windowRight(); - this._windowWidth = this._windowRight - this._windowLeft; - } - - update() { - this._updateTimerId = null; - if (!this.isShowing()) - return; - this._updateBoundaries(); - this._overviewCalculator._updateBoundaries(this); - this._overviewGrid.updateDividers(this._overviewCalculator); - this._drawOverviewCanvas(this._overviewContainer.clientWidth, this._overviewContainer.clientHeight - 20); - } - - _updateGrid() { - this._updateGridTimerId = 0; - this._updateBoundaries(); - const ids = this._profileSamples.ids; - const timestamps = this._profileSamples.timestamps; - const sizes = this._profileSamples.sizes; - const startTime = timestamps[0]; - const totalTime = this._profileSamples.totalTime; - const timeLeft = startTime + totalTime * this._windowLeft; - const timeRight = startTime + totalTime * this._windowRight; - let minId = 0; - let maxId = ids[ids.length - 1] + 1; - let size = 0; - for (let i = 0; i < timestamps.length; ++i) { - if (!timestamps[i]) - continue; - if (timestamps[i] > timeRight) - break; - maxId = ids[i]; - if (timestamps[i] < timeLeft) { - minId = ids[i]; - continue; - } - size += sizes[i]; - } - - this.dispatchEventToListeners( - Profiler.HeapTrackingOverviewGrid.IdsRangeChanged, {minId: minId, maxId: maxId, size: size}); - } -}; - -Profiler.HeapTrackingOverviewGrid.IdsRangeChanged = Symbol('IdsRangeChanged'); - -Profiler.HeapTrackingOverviewGrid.SmoothScale = class { - constructor() { - this._lastUpdate = 0; - this._currentScale = 0.0; - } - - /** - * @param {number} target - * @return {number} - */ - nextScale(target) { - target = target || this._currentScale; - if (this._currentScale) { - const now = Date.now(); - const timeDeltaMs = now - this._lastUpdate; - this._lastUpdate = now; - const maxChangePerSec = 20; - const maxChangePerDelta = Math.pow(maxChangePerSec, timeDeltaMs / 1000); - const scaleChange = target / this._currentScale; - this._currentScale *= Number.constrain(scaleChange, 1 / maxChangePerDelta, maxChangePerDelta); - } else { - this._currentScale = target; - } - return this._currentScale; - } -}; - -/** - * @implements {PerfUI.TimelineGrid.Calculator} - * @unrestricted - */ -Profiler.HeapTrackingOverviewGrid.OverviewCalculator = class { - /** - * @param {!Profiler.HeapTrackingOverviewGrid} chart - */ - _updateBoundaries(chart) { - this._minimumBoundaries = 0; - this._maximumBoundaries = chart._profileSamples.totalTime; - this._xScaleFactor = chart._overviewContainer.clientWidth / this._maximumBoundaries; - } - - /** - * @override - * @param {number} time - * @return {number} - */ - computePosition(time) { - return (time - this._minimumBoundaries) * this._xScaleFactor; - } - - /** - * @override - * @param {number} value - * @param {number=} precision - * @return {string} - */ - formatValue(value, precision) { - return Number.secondsToString(value / 1000, !!precision); - } - - /** - * @override - * @return {number} - */ - maximumBoundary() { - return this._maximumBoundaries; - } - - /** - * @override - * @return {number} - */ - minimumBoundary() { - return this._minimumBoundaries; - } - - /** - * @override - * @return {number} - */ - zeroTime() { - return this._minimumBoundaries; - } - - /** - * @override - * @return {number} - */ - boundarySpan() { - return this._maximumBoundaries - this._minimumBoundaries; - } -}; - -/** - * @unrestricted - */ Profiler.HeapSnapshotStatisticsView = class extends UI.VBox { constructor() { super();
diff --git a/third_party/blink/renderer/devtools/front_end/profiler/HeapTimelineOverview.js b/third_party/blink/renderer/devtools/front_end/profiler/HeapTimelineOverview.js new file mode 100644 index 0000000..b3577d6 --- /dev/null +++ b/third_party/blink/renderer/devtools/front_end/profiler/HeapTimelineOverview.js
@@ -0,0 +1,365 @@ +// 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. + +/** + * @unrestricted + */ +Profiler.HeapTimelineOverview = class extends UI.VBox { + /** + * @param {!Profiler.HeapProfileHeader} heapProfileHeader + */ + constructor(heapProfileHeader) { + super(); + this.element.id = 'heap-recording-view'; + this.element.classList.add('heap-tracking-overview'); + + this._overviewContainer = this.element.createChild('div', 'heap-overview-container'); + this._overviewGrid = new PerfUI.OverviewGrid('heap-recording'); + this._overviewGrid.element.classList.add('fill'); + + this._overviewCanvas = this._overviewContainer.createChild('canvas', 'heap-recording-overview-canvas'); + this._overviewContainer.appendChild(this._overviewGrid.element); + this._overviewCalculator = new Profiler.HeapTimelineOverview.OverviewCalculator(); + this._overviewGrid.addEventListener(PerfUI.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this); + + this._profileSamples = heapProfileHeader.fromFile() ? new Profiler.TrackingHeapSnapshotProfileType.Samples() : + heapProfileHeader._profileSamples; + this._profileType = heapProfileHeader.profileType(); + if (!heapProfileHeader.fromFile() && heapProfileHeader.profileType().profileBeingRecorded() === heapProfileHeader) { + this._profileType.addEventListener( + Profiler.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this); + this._profileType.addEventListener( + Profiler.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this); + } + this._windowLeft = 0.0; + this._windowRight = 1.0; + this._overviewGrid.setWindow(this._windowLeft, this._windowRight); + this._yScale = new Profiler.HeapTimelineOverview.SmoothScale(); + this._xScale = new Profiler.HeapTimelineOverview.SmoothScale(); + } + + dispose() { + this._onStopTracking(); + } + + _onStopTracking() { + this._profileType.removeEventListener( + Profiler.TrackingHeapSnapshotProfileType.HeapStatsUpdate, this._onHeapStatsUpdate, this); + this._profileType.removeEventListener( + Profiler.TrackingHeapSnapshotProfileType.TrackingStopped, this._onStopTracking, this); + } + + /** + * @param {!Common.Event} event + */ + _onHeapStatsUpdate(event) { + this._profileSamples = event.data; + this._scheduleUpdate(); + } + + /** + * @param {?HeapSnapshotModel.Samples} samples + */ + setSamples(samples) { + if (!samples) + return; + console.assert(!this._profileSamples.timestamps.length, 'Should only call this method when loading from file.'); + console.assert(samples.timestamps.length); + this._profileSamples = new Profiler.TrackingHeapSnapshotProfileType.Samples(); + this._profileSamples.sizes = samples.sizes; + this._profileSamples.ids = samples.lastAssignedIds; + this._profileSamples.timestamps = samples.timestamps; + this._profileSamples.max = samples.sizes; + this._profileSamples.totalTime = /** @type{number} */ (samples.timestamps.peekLast()); + this.update(); + } + + /** + * @param {number} width + * @param {number} height + */ + _drawOverviewCanvas(width, height) { + if (!this._profileSamples) + return; + const profileSamples = this._profileSamples; + const sizes = profileSamples.sizes; + const topSizes = profileSamples.max; + const timestamps = profileSamples.timestamps; + const startTime = timestamps[0]; + const endTime = timestamps[timestamps.length - 1]; + + const scaleFactor = this._xScale.nextScale(width / profileSamples.totalTime); + let maxSize = 0; + /** + * @param {!Array.<number>} sizes + * @param {function(number, number):void} callback + */ + function aggregateAndCall(sizes, callback) { + let size = 0; + let currentX = 0; + for (let i = 1; i < timestamps.length; ++i) { + const x = Math.floor((timestamps[i] - startTime) * scaleFactor); + if (x !== currentX) { + if (size) + callback(currentX, size); + size = 0; + currentX = x; + } + size += sizes[i]; + } + callback(currentX, size); + } + + /** + * @param {number} x + * @param {number} size + */ + function maxSizeCallback(x, size) { + maxSize = Math.max(maxSize, size); + } + + aggregateAndCall(sizes, maxSizeCallback); + + const yScaleFactor = this._yScale.nextScale(maxSize ? height / (maxSize * 1.1) : 0.0); + + this._overviewCanvas.width = width * window.devicePixelRatio; + this._overviewCanvas.height = height * window.devicePixelRatio; + this._overviewCanvas.style.width = width + 'px'; + this._overviewCanvas.style.height = height + 'px'; + + const context = this._overviewCanvas.getContext('2d'); + context.scale(window.devicePixelRatio, window.devicePixelRatio); + + context.beginPath(); + context.lineWidth = 2; + context.strokeStyle = 'rgba(192, 192, 192, 0.6)'; + const currentX = (endTime - startTime) * scaleFactor; + context.moveTo(currentX, height - 1); + context.lineTo(currentX, 0); + context.stroke(); + context.closePath(); + + let gridY; + let gridValue; + const gridLabelHeight = 14; + if (yScaleFactor) { + const maxGridValue = (height - gridLabelHeight) / yScaleFactor; + // The round value calculation is a bit tricky, because + // it has a form k*10^n*1024^m, where k=[1,5], n=[0..3], m is an integer, + // e.g. a round value 10KB is 10240 bytes. + gridValue = Math.pow(1024, Math.floor(Math.log(maxGridValue) / Math.log(1024))); + gridValue *= Math.pow(10, Math.floor(Math.log(maxGridValue / gridValue) / Math.LN10)); + if (gridValue * 5 <= maxGridValue) + gridValue *= 5; + gridY = Math.round(height - gridValue * yScaleFactor - 0.5) + 0.5; + context.beginPath(); + context.lineWidth = 1; + context.strokeStyle = 'rgba(0, 0, 0, 0.2)'; + context.moveTo(0, gridY); + context.lineTo(width, gridY); + context.stroke(); + context.closePath(); + } + + /** + * @param {number} x + * @param {number} size + */ + function drawBarCallback(x, size) { + context.moveTo(x, height - 1); + context.lineTo(x, Math.round(height - size * yScaleFactor - 1)); + } + + context.beginPath(); + context.lineWidth = 2; + context.strokeStyle = 'rgba(192, 192, 192, 0.6)'; + aggregateAndCall(topSizes, drawBarCallback); + context.stroke(); + context.closePath(); + + context.beginPath(); + context.lineWidth = 2; + context.strokeStyle = 'rgba(0, 0, 192, 0.8)'; + aggregateAndCall(sizes, drawBarCallback); + context.stroke(); + context.closePath(); + + if (gridValue) { + const label = Number.bytesToString(gridValue); + const labelPadding = 4; + const labelX = 0; + const labelY = gridY - 0.5; + const labelWidth = 2 * labelPadding + context.measureText(label).width; + context.beginPath(); + context.textBaseline = 'bottom'; + context.font = '10px ' + window.getComputedStyle(this.element, null).getPropertyValue('font-family'); + context.fillStyle = 'rgba(255, 255, 255, 0.75)'; + context.fillRect(labelX, labelY - gridLabelHeight, labelWidth, gridLabelHeight); + context.fillStyle = 'rgb(64, 64, 64)'; + context.fillText(label, labelX + labelPadding, labelY); + context.fill(); + context.closePath(); + } + } + + /** + * @override + */ + onResize() { + this._updateOverviewCanvas = true; + this._scheduleUpdate(); + } + + _onWindowChanged() { + if (!this._updateGridTimerId) + this._updateGridTimerId = setTimeout(this.updateGrid.bind(this), 10); + } + + _scheduleUpdate() { + if (this._updateTimerId) + return; + this._updateTimerId = setTimeout(this.update.bind(this), 10); + } + + _updateBoundaries() { + this._windowLeft = this._overviewGrid.windowLeft(); + this._windowRight = this._overviewGrid.windowRight(); + this._windowWidth = this._windowRight - this._windowLeft; + } + + update() { + this._updateTimerId = null; + if (!this.isShowing()) + return; + this._updateBoundaries(); + this._overviewCalculator._updateBoundaries(this); + this._overviewGrid.updateDividers(this._overviewCalculator); + this._drawOverviewCanvas(this._overviewContainer.clientWidth, this._overviewContainer.clientHeight - 20); + } + + updateGrid() { + this._updateGridTimerId = 0; + this._updateBoundaries(); + const ids = this._profileSamples.ids; + const timestamps = this._profileSamples.timestamps; + const sizes = this._profileSamples.sizes; + const startTime = timestamps[0]; + const totalTime = this._profileSamples.totalTime; + const timeLeft = startTime + totalTime * this._windowLeft; + const timeRight = startTime + totalTime * this._windowRight; + let minId = 0; + let maxId = ids[ids.length - 1] + 1; + let size = 0; + for (let i = 0; i < timestamps.length; ++i) { + if (!timestamps[i]) + continue; + if (timestamps[i] > timeRight) + break; + maxId = ids[i]; + if (timestamps[i] < timeLeft) { + minId = ids[i]; + continue; + } + size += sizes[i]; + } + + this.dispatchEventToListeners( + Profiler.HeapTimelineOverview.IdsRangeChanged, {minId: minId, maxId: maxId, size: size}); + } +}; + +Profiler.HeapTimelineOverview.IdsRangeChanged = Symbol('IdsRangeChanged'); + +Profiler.HeapTimelineOverview.SmoothScale = class { + constructor() { + this._lastUpdate = 0; + this._currentScale = 0.0; + } + + /** + * @param {number} target + * @return {number} + */ + nextScale(target) { + target = target || this._currentScale; + if (this._currentScale) { + const now = Date.now(); + const timeDeltaMs = now - this._lastUpdate; + this._lastUpdate = now; + const maxChangePerSec = 20; + const maxChangePerDelta = Math.pow(maxChangePerSec, timeDeltaMs / 1000); + const scaleChange = target / this._currentScale; + this._currentScale *= Number.constrain(scaleChange, 1 / maxChangePerDelta, maxChangePerDelta); + } else { + this._currentScale = target; + } + return this._currentScale; + } +}; + +/** + * @implements {PerfUI.TimelineGrid.Calculator} + * @unrestricted + */ +Profiler.HeapTimelineOverview.OverviewCalculator = class { + /** + * @param {!Profiler.HeapTimelineOverview} chart + */ + _updateBoundaries(chart) { + this._minimumBoundaries = 0; + this._maximumBoundaries = chart._profileSamples.totalTime; + this._xScaleFactor = chart._overviewContainer.clientWidth / this._maximumBoundaries; + } + + /** + * @override + * @param {number} time + * @return {number} + */ + computePosition(time) { + return (time - this._minimumBoundaries) * this._xScaleFactor; + } + + /** + * @override + * @param {number} value + * @param {number=} precision + * @return {string} + */ + formatValue(value, precision) { + return Number.secondsToString(value / 1000, !!precision); + } + + /** + * @override + * @return {number} + */ + maximumBoundary() { + return this._maximumBoundaries; + } + + /** + * @override + * @return {number} + */ + minimumBoundary() { + return this._minimumBoundaries; + } + + /** + * @override + * @return {number} + */ + zeroTime() { + return this._minimumBoundaries; + } + + /** + * @override + * @return {number} + */ + boundarySpan() { + return this._maximumBoundaries - this._minimumBoundaries; + } +};
diff --git a/third_party/blink/renderer/devtools/front_end/profiler/module.json b/third_party/blink/renderer/devtools/front_end/profiler/module.json index aa037d8..fbbde79 100644 --- a/third_party/blink/renderer/devtools/front_end/profiler/module.json +++ b/third_party/blink/renderer/devtools/front_end/profiler/module.json
@@ -92,11 +92,12 @@ "CPUProfileFlameChart.js", "CPUProfileView.js", "HeapProfileView.js", + "HeapProfilerPanel.js", "HeapSnapshotProxy.js", "HeapSnapshotDataGrids.js", "HeapSnapshotGridNodes.js", "HeapSnapshotView.js", - "HeapProfilerPanel.js", + "HeapTimelineOverview.js", "IsolateSelector.js", "ProfileLauncherView.js", "ProfileTypeRegistry.js"
diff --git a/third_party/blink/renderer/modules/cache_storage/cache.cc b/third_party/blink/renderer/modules/cache_storage/cache.cc index 6808dec..ae162f6 100644 --- a/third_party/blink/renderer/modules/cache_storage/cache.cc +++ b/third_party/blink/renderer/modules/cache_storage/cache.cc
@@ -26,7 +26,7 @@ #include "third_party/blink/renderer/core/fetch/request.h" #include "third_party/blink/renderer/core/fetch/request_init.h" #include "third_party/blink/renderer/core/fetch/response.h" -#include "third_party/blink/renderer/core/frame/use_counter.h" +#include "third_party/blink/renderer/core/frame/deprecation.h" #include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h" #include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/modules/cache_storage/cache_storage_error.h" @@ -224,7 +224,7 @@ if (error->message.Contains( blink::cache_storage:: kDuplicateOperationBaseMessage)) { - UseCounter::Count( + Deprecation::CountDeprecation( context, WebFeature::kCacheStorageAddAllSuccessWithDuplicate); }
diff --git a/third_party/blink/renderer/modules/filesystem/dom_file_system.cc b/third_party/blink/renderer/modules/filesystem/dom_file_system.cc index 9d079872..34cd458 100644 --- a/third_party/blink/renderer/modules/filesystem/dom_file_system.cc +++ b/third_party/blink/renderer/modules/filesystem/dom_file_system.cc
@@ -33,6 +33,7 @@ #include <memory> #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/platform/web_file_system.h" #include "third_party/blink/public/platform/web_security_origin.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/modules/filesystem/directory_entry.h" @@ -149,7 +150,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks = FileWriterCallbacks::Create(file_writer, success_callback, error_callback, context_); - FileSystemDispatcher::From(context_).InitializeFileWriter( + FileSystemDispatcher::GetThreadSpecificInstance().InitializeFileWriter( CreateFileSystemURL(file_entry), std::move(callbacks)); } @@ -159,7 +160,7 @@ ErrorCallbackBase* error_callback) { KURL file_system_url = CreateFileSystemURL(file_entry); - FileSystemDispatcher::From(context_).CreateSnapshotFile( + FileSystemDispatcher::GetThreadSpecificInstance().CreateSnapshotFile( file_system_url, SnapshotFileCallback::Create(this, file_entry->name(), file_system_url, success_callback, error_callback, context_));
diff --git a/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc b/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc index 98e1a65..0dc350b 100644 --- a/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc +++ b/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc
@@ -32,6 +32,7 @@ #include <memory> #include "third_party/blink/public/platform/platform.h" +#include "third_party/blink/public/platform/web_file_system.h" #include "third_party/blink/public/platform/web_security_origin.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/fileapi/file.h" @@ -72,6 +73,13 @@ ScriptWrappable::Trace(visitor); } +WebFileSystem* DOMFileSystemBase::FileSystem() const { + Platform* platform = Platform::Current(); + if (!platform) + return nullptr; + return platform->FileSystem(); +} + const SecurityOrigin* DOMFileSystemBase::GetSecurityOrigin() const { return context_->GetSecurityOrigin(); } @@ -211,7 +219,8 @@ SynchronousType synchronous_type) { std::unique_ptr<AsyncFileSystemCallbacks> callbacks(MetadataCallbacks::Create( success_callback, error_callback, context_, this)); - FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_); + FileSystemDispatcher& dispatcher = + FileSystemDispatcher::GetThreadSpecificInstance(); if (synchronous_type == kSynchronous) { dispatcher.ReadMetadataSync(CreateFileSystemURL(entry), @@ -276,7 +285,8 @@ success_callback, error_callback, context_, parent->filesystem(), destination_path, source->isDirectory())); - FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_); + FileSystemDispatcher& dispatcher = + FileSystemDispatcher::GetThreadSpecificInstance(); const KURL& src = CreateFileSystemURL(source); const KURL& dest = parent->filesystem()->CreateFileSystemURL(destination_path); @@ -307,7 +317,8 @@ const KURL& src = CreateFileSystemURL(source); const KURL& dest = parent->filesystem()->CreateFileSystemURL(destination_path); - FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_); + FileSystemDispatcher& dispatcher = + FileSystemDispatcher::GetThreadSpecificInstance(); if (synchronous_type == kSynchronous) dispatcher.CopySync(src, dest, std::move(callbacks)); else @@ -329,7 +340,8 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks( VoidCallbacks::Create(success_callback, error_callback, context_, this)); const KURL& url = CreateFileSystemURL(entry); - FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_); + FileSystemDispatcher& dispatcher = + FileSystemDispatcher::GetThreadSpecificInstance(); if (synchronous_type == kSynchronous) dispatcher.RemoveSync(url, /*recursive=*/false, std::move(callbacks)); else @@ -352,7 +364,8 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks( VoidCallbacks::Create(success_callback, error_callback, context_, this)); const KURL& url = CreateFileSystemURL(entry); - FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_); + FileSystemDispatcher& dispatcher = + FileSystemDispatcher::GetThreadSpecificInstance(); if (synchronous_type == kSynchronous) dispatcher.RemoveSync(url, /*recursive=*/true, std::move(callbacks)); else @@ -366,7 +379,7 @@ DCHECK(entry); String path = DOMFilePath::GetDirectory(entry->fullPath()); - FileSystemDispatcher::From(context_).Exists( + FileSystemDispatcher::GetThreadSpecificInstance().Exists( CreateFileSystemURL(path), /*is_directory=*/true, EntryCallbacks::Create(success_callback, error_callback, context_, this, path, true)); @@ -388,7 +401,8 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks(EntryCallbacks::Create( success_callback, error_callback, context_, this, absolute_path, false)); const KURL& url = CreateFileSystemURL(absolute_path); - FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_); + FileSystemDispatcher& dispatcher = + FileSystemDispatcher::GetThreadSpecificInstance(); if (flags.createFlag()) { if (synchronous_type == kSynchronous) @@ -420,7 +434,8 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks(EntryCallbacks::Create( success_callback, error_callback, context_, this, absolute_path, true)); const KURL& url = CreateFileSystemURL(absolute_path); - FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_); + FileSystemDispatcher& dispatcher = + FileSystemDispatcher::GetThreadSpecificInstance(); if (flags.createFlag()) { if (synchronous_type == kSynchronous) { @@ -449,7 +464,8 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks(EntriesCallbacks::Create( success_callback, error_callback, context_, reader, path)); - FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context_); + FileSystemDispatcher& dispatcher = + FileSystemDispatcher::GetThreadSpecificInstance(); const KURL& url = CreateFileSystemURL(path); if (synchronous_type == kSynchronous) { dispatcher.ReadDirectorySync(url, std::move(callbacks));
diff --git a/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h b/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h index 83452e2..643929f 100644 --- a/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h +++ b/third_party/blink/renderer/modules/filesystem/dom_file_system_base.h
@@ -42,6 +42,10 @@ #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" namespace blink { +class WebFileSystem; +} // namespace blink + +namespace blink { class DirectoryReaderBase; class EntryBase; @@ -79,6 +83,7 @@ const String& name() const { return name_; } mojom::blink::FileSystemType GetType() const { return type_; } KURL RootURL() const { return filesystem_root_url_; } + WebFileSystem* FileSystem() const; const SecurityOrigin* GetSecurityOrigin() const; // The clonable flag is used in the structured clone algorithm to test
diff --git a/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc b/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc index 1d1b6e1..08b3747 100644 --- a/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc +++ b/third_party/blink/renderer/modules/filesystem/dom_file_system_sync.cc
@@ -33,6 +33,7 @@ #include <memory> #include "base/memory/ptr_util.h" +#include "third_party/blink/public/platform/web_file_system.h" #include "third_party/blink/renderer/core/fileapi/file.h" #include "third_party/blink/renderer/core/fileapi/file_error.h" #include "third_party/blink/renderer/modules/filesystem/directory_entry_sync.h" @@ -139,7 +140,7 @@ KURL file_system_url = CreateFileSystemURL(file_entry); CreateFileHelper::CreateFileResult* result( CreateFileHelper::CreateFileResult::Create()); - FileSystemDispatcher::From(context_).CreateSnapshotFileSync( + FileSystemDispatcher::GetThreadSpecificInstance().CreateSnapshotFileSync( file_system_url, CreateFileHelper::Create(result, file_entry->name(), file_system_url, GetType())); if (result->failed_) { @@ -156,7 +157,7 @@ ExceptionState& exception_state) { DCHECK(file_entry); - FileWriterSync* file_writer = FileWriterSync::Create(context_); + FileWriterSync* file_writer = FileWriterSync::Create(); FileWriterCallbacksSyncHelper* sync_helper = FileWriterCallbacksSyncHelper::Create(); @@ -165,7 +166,7 @@ sync_helper->GetSuccessCallback(), sync_helper->GetErrorCallback(), context_); - FileSystemDispatcher::From(context_).InitializeFileWriterSync( + FileSystemDispatcher::GetThreadSpecificInstance().InitializeFileWriterSync( CreateFileSystemURL(file_entry), std::move(callbacks)); FileWriterBase* success = sync_helper->GetResultOrThrow(exception_state);
diff --git a/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc b/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc index ec80085..1130460b 100644 --- a/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc +++ b/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.cc
@@ -5,10 +5,9 @@ #include "third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h" #include "build/build_config.h" -#include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/platform/file_path_conversion.h" +#include "third_party/blink/public/platform/interface_provider.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -69,34 +68,23 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks_; }; -FileSystemDispatcher::FileSystemDispatcher(ExecutionContext& context) - : Supplement<ExecutionContext>(context), next_operation_id_(1) {} +FileSystemDispatcher::FileSystemDispatcher() : next_operation_id_(1) {} // static -const char FileSystemDispatcher::kSupplementName[] = "FileSystemDispatcher"; - -// static -FileSystemDispatcher& FileSystemDispatcher::From(ExecutionContext* context) { - DCHECK(context); - FileSystemDispatcher* dispatcher = - Supplement<ExecutionContext>::From<FileSystemDispatcher>(context); - if (!dispatcher) { - dispatcher = new FileSystemDispatcher(*context); - Supplement<ExecutionContext>::ProvideTo(*context, dispatcher); - } - return *dispatcher; +FileSystemDispatcher& FileSystemDispatcher::GetThreadSpecificInstance() { + DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<FileSystemDispatcher>, + file_system_dispatcher, ()); + return *file_system_dispatcher; } -FileSystemDispatcher::~FileSystemDispatcher() = default; - void FileSystemDispatcher::OpenFileSystem( const KURL& origin_url, mojom::blink::FileSystemType type, std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().Open( origin_url, type, - WTF::Bind(&FileSystemDispatcher::DidOpenFileSystem, - WrapWeakPersistent(this), std::move(callbacks))); + WTF::Bind(&FileSystemDispatcher::DidOpenFileSystem, WTF::Unretained(this), + std::move(callbacks))); } void FileSystemDispatcher::OpenFileSystemSync( @@ -115,9 +103,8 @@ const KURL& filesystem_url, std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().ResolveURL( - filesystem_url, - WTF::Bind(&FileSystemDispatcher::DidResolveURL, WrapWeakPersistent(this), - std::move(callbacks))); + filesystem_url, WTF::Bind(&FileSystemDispatcher::DidResolveURL, + WTF::Unretained(this), std::move(callbacks))); } void FileSystemDispatcher::ResolveURLSync( @@ -139,7 +126,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().Move( src_path, dest_path, - WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this), + WTF::Bind(&FileSystemDispatcher::DidFinish, WTF::Unretained(this), std::move(callbacks))); } @@ -158,7 +145,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().Copy( src_path, dest_path, - WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this), + WTF::Bind(&FileSystemDispatcher::DidFinish, WTF::Unretained(this), std::move(callbacks))); } @@ -177,7 +164,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().Remove( path, recursive, - WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this), + WTF::Bind(&FileSystemDispatcher::DidFinish, WTF::Unretained(this), std::move(callbacks))); } @@ -195,7 +182,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().ReadMetadata( path, WTF::Bind(&FileSystemDispatcher::DidReadMetadata, - WrapWeakPersistent(this), std::move(callbacks))); + WTF::Unretained(this), std::move(callbacks))); } void FileSystemDispatcher::ReadMetadataSync( @@ -213,7 +200,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().Create( path, exclusive, /*is_directory=*/false, /*is_recursive=*/false, - WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this), + WTF::Bind(&FileSystemDispatcher::DidFinish, WTF::Unretained(this), std::move(callbacks))); } @@ -234,7 +221,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().Create( path, exclusive, /*is_directory=*/true, recursive, - WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this), + WTF::Bind(&FileSystemDispatcher::DidFinish, WTF::Unretained(this), std::move(callbacks))); } @@ -255,7 +242,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().Exists( path, is_directory, - WTF::Bind(&FileSystemDispatcher::DidFinish, WrapWeakPersistent(this), + WTF::Bind(&FileSystemDispatcher::DidFinish, WTF::Unretained(this), std::move(callbacks))); } @@ -297,7 +284,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().ReadMetadata( path, WTF::Bind(&FileSystemDispatcher::InitializeFileWriterCallback, - WrapWeakPersistent(this), path, std::move(callbacks))); + WTF::Unretained(this), path, std::move(callbacks))); } void FileSystemDispatcher::InitializeFileWriterSync( @@ -320,11 +307,11 @@ int operation_id = next_operation_id_++; op_ptr.set_connection_error_handler( WTF::Bind(&FileSystemDispatcher::RemoveOperationPtr, - WrapWeakPersistent(this), operation_id)); + WTF::Unretained(this), operation_id)); cancellable_operations_.insert(operation_id, std::move(op_ptr)); GetFileSystemManager().Truncate( path, offset, std::move(op_request), - WTF::Bind(&FileSystemDispatcher::DidTruncate, WrapWeakPersistent(this), + WTF::Bind(&FileSystemDispatcher::DidTruncate, WTF::Unretained(this), operation_id, std::move(callback))); if (request_id_out) @@ -351,7 +338,7 @@ int operation_id = next_operation_id_++; op_ptr.set_connection_error_handler( WTF::Bind(&FileSystemDispatcher::RemoveOperationPtr, - WrapWeakPersistent(this), operation_id)); + WTF::Unretained(this), operation_id)); cancellable_operations_.insert(operation_id, std::move(op_ptr)); mojom::blink::FileSystemOperationListenerPtr listener_ptr; @@ -392,7 +379,7 @@ } cancellable_operations_.find(request_id_to_cancel) ->value->Cancel(WTF::Bind(&FileSystemDispatcher::DidCancel, - WrapWeakPersistent(this), std::move(callback), + WTF::Unretained(this), std::move(callback), request_id_to_cancel)); } @@ -401,7 +388,7 @@ std::unique_ptr<AsyncFileSystemCallbacks> callbacks) { GetFileSystemManager().CreateSnapshotFile( file_path, WTF::Bind(&FileSystemDispatcher::DidCreateSnapshotFile, - WrapWeakPersistent(this), std::move(callbacks))); + WTF::Unretained(this), std::move(callbacks))); } void FileSystemDispatcher::CreateSnapshotFileSync( @@ -435,24 +422,9 @@ std::move(callbacks))); } -void FileSystemDispatcher::ChooseEntry( - std::unique_ptr<ChooseEntryCallbacks> callbacks) { - GetFileSystemManager().ChooseEntry(WTF::Bind( - [](std::unique_ptr<ChooseEntryCallbacks> callbacks, - base::File::Error result, - Vector<mojom::blink::FileSystemEntryPtr> entries) { - if (result != base::File::FILE_OK) { - callbacks->OnError(result); - } else { - callbacks->OnSuccess(std::move(entries)); - } - }, - std::move(callbacks))); -} - mojom::blink::FileSystemManager& FileSystemDispatcher::GetFileSystemManager() { if (!file_system_manager_ptr_) { - GetSupplementable()->GetInterfaceProvider()->GetInterface( + Platform::Current()->GetInterfaceProvider()->GetInterface( mojo::MakeRequest(&file_system_manager_ptr_)); } return *file_system_manager_ptr_;
diff --git a/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h b/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h index d8a899a..2b3b33a 100644 --- a/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h +++ b/third_party/blink/renderer/modules/filesystem/file_system_dispatcher.h
@@ -10,7 +10,6 @@ #include "third_party/blink/public/platform/web_callbacks.h" #include "third_party/blink/renderer/platform/async_file_system_callbacks.h" #include "third_party/blink/renderer/platform/heap/handle.h" -#include "third_party/blink/renderer/platform/supplementable.h" namespace WTF { class String; @@ -19,25 +18,18 @@ namespace blink { class KURL; -class ExecutionContext; // Sends messages via mojo to the blink::mojom::FileSystemManager service -// running in the browser process. It is owned by ExecutionContext, and -// instances are created lazily by calling FileSystemDispatcher::From(). -class FileSystemDispatcher - : public GarbageCollectedFinalized<FileSystemDispatcher>, - public Supplement<ExecutionContext> { - USING_GARBAGE_COLLECTED_MIXIN(FileSystemDispatcher); - +// running in the browser process. It is currently created and stored in a +// thread local variable. A thread specific instance can be obtained using +// GetThreadSpecificInstance(). +class FileSystemDispatcher { public: using StatusCallback = base::OnceCallback<void(base::File::Error error)>; using WriteCallback = base::RepeatingCallback<void(int64_t bytes, bool complete)>; - static const char kSupplementName[]; - - static FileSystemDispatcher& From(ExecutionContext* context); - virtual ~FileSystemDispatcher(); + static FileSystemDispatcher& GetThreadSpecificInstance(); void OpenFileSystem(const KURL& url, mojom::blink::FileSystemType type, @@ -141,15 +133,12 @@ void CreateFileWriter(const KURL& file_path, std::unique_ptr<CreateFileWriterCallbacks>); - using ChooseEntryCallbacks = - WebCallbacks<Vector<mojom::blink::FileSystemEntryPtr>, base::File::Error>; - void ChooseEntry(std::unique_ptr<ChooseEntryCallbacks> callbacks); - private: class WriteListener; class ReadDirectoryListener; + friend class WTF::ThreadSpecific<FileSystemDispatcher>; - explicit FileSystemDispatcher(ExecutionContext& context); + FileSystemDispatcher(); mojom::blink::FileSystemManager& GetFileSystemManager();
diff --git a/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc b/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc index 2b66212..5775e5c 100644 --- a/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc +++ b/third_party/blink/renderer/modules/filesystem/file_system_file_handle.cc
@@ -60,9 +60,9 @@ ScriptPromise FileSystemFileHandle::createWriter(ScriptState* script_state) { auto* resolver = ScriptPromiseResolver::Create(script_state); ScriptPromise result = resolver->Promise(); - FileSystemDispatcher::From(ExecutionContext::From(script_state)) - .CreateFileWriter(filesystem()->CreateFileSystemURL(this), - std::make_unique<CreateWriterCallbacks>(resolver)); + FileSystemDispatcher::GetThreadSpecificInstance().CreateFileWriter( + filesystem()->CreateFileSystemURL(this), + std::make_unique<CreateWriterCallbacks>(resolver)); return result; } @@ -70,13 +70,12 @@ auto* resolver = ScriptPromiseResolver::Create(script_state); ScriptPromise result = resolver->Promise(); KURL file_system_url = filesystem()->CreateFileSystemURL(this); - FileSystemDispatcher::From(ExecutionContext::From(script_state)) - .CreateSnapshotFile(file_system_url, - SnapshotFileCallback::Create( - filesystem(), name(), file_system_url, - new OnDidCreateSnapshotFilePromise(resolver), - new PromiseErrorCallback(resolver), - ExecutionContext::From(script_state))); + FileSystemDispatcher::GetThreadSpecificInstance().CreateSnapshotFile( + file_system_url, + SnapshotFileCallback::Create(filesystem(), name(), file_system_url, + new OnDidCreateSnapshotFilePromise(resolver), + new PromiseErrorCallback(resolver), + ExecutionContext::From(script_state))); return result; }
diff --git a/third_party/blink/renderer/modules/filesystem/file_writer.cc b/third_party/blink/renderer/modules/filesystem/file_writer.cc index 427f69d..56e910f 100644 --- a/third_party/blink/renderer/modules/filesystem/file_writer.cc +++ b/third_party/blink/renderer/modules/filesystem/file_writer.cc
@@ -225,25 +225,23 @@ } void FileWriter::DoTruncate(const KURL& path, int64_t offset) { - FileSystemDispatcher::From(GetExecutionContext()) - .Truncate(path, offset, &request_id_, - WTF::Bind(&FileWriter::DidFinish, WrapWeakPersistent(this))); + FileSystemDispatcher::GetThreadSpecificInstance().Truncate( + path, offset, &request_id_, + WTF::Bind(&FileWriter::DidFinish, WrapWeakPersistent(this))); } void FileWriter::DoWrite(const KURL& path, const String& blob_id, int64_t offset) { - FileSystemDispatcher::From(GetExecutionContext()) - .Write( - path, blob_id, offset, &request_id_, - WTF::BindRepeating(&FileWriter::DidWrite, WrapWeakPersistent(this)), - WTF::Bind(&FileWriter::DidFinish, WrapWeakPersistent(this))); + FileSystemDispatcher::GetThreadSpecificInstance().Write( + path, blob_id, offset, &request_id_, + WTF::BindRepeating(&FileWriter::DidWrite, WrapWeakPersistent(this)), + WTF::Bind(&FileWriter::DidFinish, WrapWeakPersistent(this))); } void FileWriter::DoCancel() { - FileSystemDispatcher::From(GetExecutionContext()) - .Cancel(request_id_, - WTF::Bind(&FileWriter::DidFinish, WrapWeakPersistent(this))); + FileSystemDispatcher::GetThreadSpecificInstance().Cancel( + request_id_, WTF::Bind(&FileWriter::DidFinish, WrapWeakPersistent(this))); } void FileWriter::CompleteAbort() { @@ -330,8 +328,6 @@ DoOperation(kOperationAbort); ready_state_ = kDone; } - // Prevents any queued operations from running after abort completes. - queued_operation_ = kOperationNone; } void FileWriter::Trace(blink::Visitor* visitor) {
diff --git a/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc b/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc index e9c20b16..3242da55 100644 --- a/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc +++ b/third_party/blink/renderer/modules/filesystem/file_writer_sync.cc
@@ -98,33 +98,26 @@ } void FileWriterSync::DoTruncate(const KURL& path, int64_t offset) { - if (!GetExecutionContext()) - return; - FileSystemDispatcher::From(GetExecutionContext()) - .TruncateSync( - path, offset, - WTF::Bind(&FileWriterSync::DidFinish, WrapWeakPersistent(this))); + FileSystemDispatcher::GetThreadSpecificInstance().TruncateSync( + path, offset, + WTF::Bind(&FileWriterSync::DidFinish, WrapWeakPersistent(this))); } void FileWriterSync::DoWrite(const KURL& path, const String& blob_id, int64_t offset) { - if (!GetExecutionContext()) - return; - FileSystemDispatcher::From(GetExecutionContext()) - .WriteSync( - path, blob_id, offset, - WTF::BindRepeating(&FileWriterSync::DidWrite, - WrapWeakPersistent(this)), - WTF::Bind(&FileWriterSync::DidFinish, WrapWeakPersistent(this))); + FileSystemDispatcher::GetThreadSpecificInstance().WriteSync( + path, blob_id, offset, + WTF::BindRepeating(&FileWriterSync::DidWrite, WrapWeakPersistent(this)), + WTF::Bind(&FileWriterSync::DidFinish, WrapWeakPersistent(this))); } void FileWriterSync::DoCancel() { NOTREACHED(); } -FileWriterSync::FileWriterSync(ExecutionContext* context) - : ContextClient(context), error_(base::File::FILE_OK), complete_(true) {} +FileWriterSync::FileWriterSync() + : error_(base::File::FILE_OK), complete_(true) {} void FileWriterSync::PrepareForWrite() { DCHECK(complete_); @@ -137,7 +130,6 @@ void FileWriterSync::Trace(blink::Visitor* visitor) { ScriptWrappable::Trace(visitor); FileWriterBase::Trace(visitor); - ContextClient::Trace(visitor); } } // namespace blink
diff --git a/third_party/blink/renderer/modules/filesystem/file_writer_sync.h b/third_party/blink/renderer/modules/filesystem/file_writer_sync.h index 6561606..4a8002a 100644 --- a/third_party/blink/renderer/modules/filesystem/file_writer_sync.h +++ b/third_party/blink/renderer/modules/filesystem/file_writer_sync.h
@@ -31,7 +31,6 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_WRITER_SYNC_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_FILESYSTEM_FILE_WRITER_SYNC_H_ -#include "third_party/blink/renderer/core/dom/context_lifecycle_observer.h" #include "third_party/blink/renderer/core/fileapi/file_error.h" #include "third_party/blink/renderer/modules/filesystem/file_writer_base.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" @@ -42,16 +41,12 @@ class Blob; class ExceptionState; -class FileWriterSync final : public ScriptWrappable, - public FileWriterBase, - public ContextClient { +class FileWriterSync final : public ScriptWrappable, public FileWriterBase { DEFINE_WRAPPERTYPEINFO(); USING_GARBAGE_COLLECTED_MIXIN(FileWriterSync); public: - static FileWriterSync* Create(ExecutionContext* context) { - return new FileWriterSync(context); - } + static FileWriterSync* Create() { return new FileWriterSync(); } ~FileWriterSync() override; void Trace(blink::Visitor*) override; @@ -70,7 +65,7 @@ void DoCancel() override; private: - explicit FileWriterSync(ExecutionContext* context); + FileWriterSync(); void PrepareForWrite(); base::File::Error error_;
diff --git a/third_party/blink/renderer/modules/filesystem/local_file_system.cc b/third_party/blink/renderer/modules/filesystem/local_file_system.cc index 29c34b3..0a7e003 100644 --- a/third_party/blink/renderer/modules/filesystem/local_file_system.cc +++ b/third_party/blink/renderer/modules/filesystem/local_file_system.cc
@@ -35,6 +35,7 @@ #include "third_party/blink/public/common/features.h" #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/public/platform/task_type.h" +#include "third_party/blink/public/platform/web_file_system.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" @@ -115,14 +116,12 @@ namespace { -class ChooseEntryCallbacks - : public WebCallbacks<Vector<mojom::blink::FileSystemEntryPtr>, - base::File::Error> { +class ChooseEntryCallbacks : public WebFileSystem::ChooseEntryCallbacks { public: ChooseEntryCallbacks(ScriptPromiseResolver* resolver, bool return_multiple) : resolver_(resolver), return_multiple_(return_multiple) {} - void OnSuccess(Vector<mojom::blink::FileSystemEntryPtr> entries) override { + void OnSuccess(WebVector<WebFileSystem::FileSystemEntry> entries) override { ScriptState::Scope scope(resolver_->GetScriptState()); if (return_multiple_) { Vector<ScriptPromise> result; @@ -142,16 +141,15 @@ } private: - ScriptPromise CreateFileHandle( - const mojom::blink::FileSystemEntryPtr& entry) { + ScriptPromise CreateFileHandle(const WebFileSystem::FileSystemEntry& entry) { auto* new_resolver = ScriptPromiseResolver::Create(resolver_->GetScriptState()); ScriptPromise result = new_resolver->Promise(); auto* fs = DOMFileSystem::CreateIsolatedFileSystem( - resolver_->GetExecutionContext(), entry->file_system_id); + resolver_->GetExecutionContext(), entry.file_system_id); // TODO(mek): Try to create handle directly rather than having to do more // IPCs to get the actual entries. - fs->GetFile(fs->root(), entry->base_name, FileSystemFlags(), + fs->GetFile(fs->root(), entry.base_name, FileSystemFlags(), new EntryCallbacks::OnDidGetEntryPromiseImpl(new_resolver), new PromiseErrorCallback(new_resolver)); return result; @@ -170,8 +168,24 @@ return; } - FileSystemDispatcher::From(resolver->GetExecutionContext()) - .ChooseEntry(std::make_unique<ChooseEntryCallbacks>(resolver, false)); + WebFileSystem* file_system = GetFileSystem(); + if (!file_system) { + resolver->Reject( + FileError::CreateDOMException(base::File::FILE_ERROR_ABORT)); + return; + } + + file_system->ChooseEntry( + Supplement<LocalFrame>::GetSupplementable()->Client()->GetWebFrame(), + std::make_unique<ChooseEntryCallbacks>(resolver, false)); +} + +WebFileSystem* LocalFileSystem::GetFileSystem() const { + Platform* platform = Platform::Current(); + if (!platform) + return nullptr; + + return platform->FileSystem(); } void LocalFileSystem::RequestFileSystemAccessInternal( @@ -216,7 +230,8 @@ KURL(NullURL(), context->GetSecurityOrigin()->ToString()); std::unique_ptr<AsyncFileSystemCallbacks> async_callbacks = callbacks->Release(); - FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context); + FileSystemDispatcher& dispatcher = + FileSystemDispatcher::GetThreadSpecificInstance(); if (sync_type == kSynchronous) { dispatcher.OpenFileSystemSync(storage_partition, type, std::move(async_callbacks)); @@ -230,7 +245,8 @@ const KURL& file_system_url, CallbackWrapper* callbacks, SynchronousType sync_type) { - FileSystemDispatcher& dispatcher = FileSystemDispatcher::From(context); + FileSystemDispatcher& dispatcher = + FileSystemDispatcher::GetThreadSpecificInstance(); std::unique_ptr<AsyncFileSystemCallbacks> async_callbacks = callbacks->Release(); if (sync_type == kSynchronous) {
diff --git a/third_party/blink/renderer/modules/filesystem/local_file_system.h b/third_party/blink/renderer/modules/filesystem/local_file_system.h index b137d0e9..b3e2823b 100644 --- a/third_party/blink/renderer/modules/filesystem/local_file_system.h +++ b/third_party/blink/renderer/modules/filesystem/local_file_system.h
@@ -49,6 +49,7 @@ class ExecutionContext; class KURL; class ScriptPromiseResolver; +class WebFileSystem; class LocalFileSystem final : public GarbageCollectedFinalized<LocalFileSystem>, public Supplement<LocalFrame>, @@ -86,6 +87,7 @@ const char* NameInHeapSnapshot() const override { return "LocalFileSystem"; } private: + WebFileSystem* GetFileSystem() const; void FileSystemNotAvailable(ExecutionContext*, CallbackWrapper*); void RequestFileSystemAccessInternal(ExecutionContext*,
diff --git a/third_party/blink/renderer/platform/exported/web_url_response.cc b/third_party/blink/renderer/platform/exported/web_url_response.cc index d2d9b33..6b1d6b1 100644 --- a/third_party/blink/renderer/platform/exported/web_url_response.cc +++ b/third_party/blink/renderer/platform/exported/web_url_response.cc
@@ -249,7 +249,7 @@ resource_response_->SetCTPolicyCompliance( ResourceResponse::kCTPolicyComplies); break; - case net::ct::CTPolicyCompliance::CT_POLICY_MAX: + case net::ct::CTPolicyCompliance::CT_POLICY_COUNT: NOTREACHED(); resource_response_->SetCTPolicyCompliance( ResourceResponse::kCTPolicyComplianceDetailsNotAvailable);
diff --git a/third_party/blink/renderer/platform/graphics/image_decoder_wrapper.cc b/third_party/blink/renderer/platform/graphics/image_decoder_wrapper.cc index 803b7d50..0d8fe6b 100644 --- a/third_party/blink/renderer/platform/graphics/image_decoder_wrapper.cc +++ b/third_party/blink/renderer/platform/graphics/image_decoder_wrapper.cc
@@ -136,7 +136,13 @@ ExternalMemoryAllocator external_memory_allocator(info_, pixels_, row_bytes_); if (decode_to_external_memory) decoder->SetMemoryAllocator(&external_memory_allocator); - ImageFrame* frame = decoder->DecodeFrameBufferAtIndex(frame_index_); + ImageFrame* frame = nullptr; + { + // This trace event is important since it is used by telemetry scripts to + // measure the decode time. + TRACE_EVENT0("blink", "ImageFrameGenerator::decode"); + frame = decoder->DecodeFrameBufferAtIndex(frame_index_); + } // SetMemoryAllocator() can try to access decoder's data, so we have to // clear it before clearing SegmentReader. if (decode_to_external_memory)
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 66ce29b..8f4318f 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -10797,6 +10797,19 @@ </summary> </histogram> +<histogram name="Bookmarks.Count.OnProfileLoad" units="bookmarks" + expires_after="2019-03-24"> + <owner>supertri@chromium.org</owner> + <owner>isherman@chromium.org</owner> + <owner>aidanday@google.com</owner> + <summary> + The total number of bookmarks a user has saved. Recorded when a profile is + opened - precisely, when bookmarks are loaded into storage from disk. The + count includes all bookmarks both in the "Bookmarks Bar" and also + under "Other Bookmarks". + </summary> +</histogram> + <histogram name="Bookmarks.EntryPoint" enum="BookmarksEntryPoint"> <owner>ianwen@chromium.org</owner> <summary>How users add a new bookmark.</summary> @@ -46232,6 +46245,15 @@ </summary> </histogram> +<histogram name="Memory.Experimental.OomIntervention.RendererBlinkUsage" + units="MB"> + <owner>yuzus@chromium.org</owner> + <summary> + The renderer process's memory usage reported every second when OOM + intervention is enabled. + </summary> +</histogram> + <histogram name="Memory.Experimental.OomIntervention.RendererBlinkUsageAtOOM" units="MB"> <owner>ssid@chromium.org</owner> @@ -46268,6 +46290,16 @@ </histogram> <histogram + name="Memory.Experimental.OomIntervention.RendererPrivateMemoryFootprint" + units="MB"> + <owner>yuzus@chromium.org</owner> + <summary> + The renderer process's PMF size reported every second when OOM intervention + is enabled. + </summary> +</histogram> + +<histogram name="Memory.Experimental.OomIntervention.RendererPrivateMemoryFootprintAtOOM" units="MB"> <owner>ssid@chromium.org</owner> @@ -46279,6 +46311,15 @@ </summary> </histogram> +<histogram name="Memory.Experimental.OomIntervention.RendererSwapFootPrint" + units="MB"> + <owner>yuzus@chromium.org</owner> + <summary> + The renderer process's swap size reported every second when OOM intervention + is enabled. + </summary> +</histogram> + <histogram name="Memory.Experimental.OomIntervention.RendererSwapFootprintAtOOM" units="MB"> @@ -46291,6 +46332,17 @@ </histogram> <histogram + name="Memory.Experimental.OomIntervention.RendererTimeSinceLastNavigationAtIntervention" + units="seconds"> + <owner>yuzus@chromium.org</owner> + <summary> + Records the time since last main frame navigation start on the renderer + process when intervention is triggered. Record only when navigation happened + at least once. + </summary> +</histogram> + +<histogram name="Memory.Experimental.OomIntervention.RendererTimeSinceLastNavigationAtOOM" units="seconds"> <owner>ssid@chromium.org</owner> @@ -46302,6 +46354,14 @@ </summary> </histogram> +<histogram name="Memory.Experimental.OomIntervention.RendererVMSize" units="MB"> + <owner>yuzus@chromium.org</owner> + <summary> + The renderer process's virtual memory usage reported every second when OOM + intervention is enabled. + </summary> +</histogram> + <histogram name="Memory.Experimental.OomIntervention.RendererVmSizeAtOOM" units="MB" expires_after="2018-06-12"> <obsolete> @@ -97779,6 +97839,17 @@ </summary> </histogram> +<histogram name="Signin.SigninAllowed" units="BooleanEnabled" + expires_after="2019-10-01"> + <owner>droger@chromium.org</owner> + <owner>msarda@chromium.org</owner> + <owner>tangltom@chromium.org</owner> + <summary> + Tracks the state of a user's signin-allowed preference. This is recorded at + every startup. + </summary> +</histogram> + <histogram name="Signin.SigninCompletedAccessPoint" enum="SigninAccessPoint"> <owner>gogerald@chromium.org</owner> <summary>Logs the original access point of each completed sign in.</summary>
diff --git a/ui/file_manager/file_manager/background/js/test_util.js b/ui/file_manager/file_manager/background/js/test_util.js index 160e8a61..6b7b803 100644 --- a/ui/file_manager/file_manager/background/js/test_util.js +++ b/ui/file_manager/file_manager/background/js/test_util.js
@@ -92,13 +92,13 @@ test.util.sync.selectFile = function(contentWindow, filename) { var rows = contentWindow.document.querySelectorAll('#detail-table li'); test.util.sync.fakeKeyDown( - contentWindow, '#file-list', 'Home', 'Home', false, false, false); + contentWindow, '#file-list', 'Home', false, false, false); for (var index = 0; index < rows.length; ++index) { var selection = test.util.sync.getSelectedFiles(contentWindow); if (selection.length === 1 && selection[0] === filename) return true; test.util.sync.fakeKeyDown( - contentWindow, '#file-list', 'ArrowDown', 'Down', false, false, false); + contentWindow, '#file-list', 'ArrowDown', false, false, false); } console.error('Failed to select file "' + filename + '"'); return false; @@ -193,19 +193,17 @@ var items = contentWindow.document.querySelectorAll('#directory-tree .tree-item'); test.util.sync.fakeKeyDown( - contentWindow, '#directory-tree', 'Home', 'Home', false, false, false); + contentWindow, '#directory-tree', 'Home', false, false, false); for (var index = 0; index < items.length; ++index) { var selectedTreeItemName = test.util.sync.getSelectedTreeItem(contentWindow); if (selectedTreeItemName === folderName) { test.util.sync.fakeKeyDown( - contentWindow, '#directory-tree', 'Enter', 'Enter', false, false, - false); + contentWindow, '#directory-tree', 'Enter', false, false, false); return true; } test.util.sync.fakeKeyDown( - contentWindow, '#directory-tree', 'ArrowDown', 'Down', false, false, - false); + contentWindow, '#directory-tree', 'ArrowDown', false, false, false); } console.error('Failed to select folder in tree "' + folderName + '"'); @@ -228,7 +226,7 @@ } test.util.sync.fakeKeyDown( contentWindow, '#directory-tree .tree-item[selected]', 'ArrowRight', - 'Right', false, false, false); + false, false, false); return true; }; @@ -248,7 +246,7 @@ } test.util.sync.fakeKeyDown( contentWindow, '#directory-tree .tree-item[selected]', 'ArrowLeft', - 'Left', false, false, false); + false, false, false); return true; }; @@ -339,9 +337,9 @@ return false; // Ctrl+C and Ctrl+V test.util.sync.fakeKeyDown( - contentWindow, '#file-list', 'c', 'U+0043', true, false, false); + contentWindow, '#file-list', 'c', true, false, false); test.util.sync.fakeKeyDown( - contentWindow, '#file-list', 'v', 'U+0056', true, false, false); + contentWindow, '#file-list', 'v', true, false, false); return true; }; @@ -358,7 +356,7 @@ return false; // Delete test.util.sync.fakeKeyDown( - contentWindow, '#file-list', 'Delete', 'U+007F', false, false, false); + contentWindow, '#file-list', 'Delete', false, false, false); return true; };
diff --git a/ui/file_manager/file_manager/background/js/test_util_base.js b/ui/file_manager/file_manager/background/js/test_util_base.js index 5251ec1..a49d360 100644 --- a/ui/file_manager/file_manager/background/js/test_util_base.js +++ b/ui/file_manager/file_manager/background/js/test_util_base.js
@@ -350,25 +350,23 @@ /** * Sends a fake key event to the element specified by |targetQuery| or active - * element with the given |keyIdentifier| and optional |ctrl| modifier. + * element with the given |key| and optional |ctrl,shift,alt| modifier. * * @param {Window} contentWindow Window to be tested. * @param {?string} targetQuery Query to specify the element. If this value is * null, key event is dispatched to active element of the document. * @param {string} key DOM UI Events key value. - * @param {string} keyIdentifier Identifier of the emulated key. * @param {boolean} ctrl Whether CTRL should be pressed, or not. * @param {boolean} shift whether SHIFT should be pressed, or not. * @param {boolean} alt whether ALT should be pressed, or not. * @return {boolean} True if the event is sent to the target, false otherwise. */ test.util.sync.fakeKeyDown = function( - contentWindow, targetQuery, key, keyIdentifier, ctrl, shift, alt) { + contentWindow, targetQuery, key, ctrl, shift, alt) { const event = new KeyboardEvent('keydown', { bubbles: true, composed: true, // Allow the event to bubble past shadow DOM root. key: key, - keyIdentifier: keyIdentifier, ctrlKey: ctrl, shiftKey: shift, altKey: alt
diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html index de1bc1f..dbd427ce8 100644 --- a/ui/file_manager/file_manager/main.html +++ b/ui/file_manager/file_manager/main.html
@@ -25,67 +25,69 @@ <link rel="stylesheet" href="foreground/css/common.css"> <link rel="stylesheet" href="chrome-extension://fbjakikfhfdajcamjleinfciajelkpek/cws_widget/cws_widget_container.css"> - <style is="custom-style"> - #search-box cr-input { - --cr-input-color: white; - --cr-input-focus-color: white; - --cr-input-container: { - border-radius: 0; - } - --cr-input-error-display: none; - --cr-input-input: { - background-color: transparent; - border-bottom: 1px solid rgba(255, 255, 255, 0.5); - } - --cr-input-padding-end: 20px; - --cr-input-padding-start: 0; - --cr-input-placeholder-color: rgba(255, 255, 255, 0.5); - display: inline-block; - transition: width 200ms ease; - vertical-align: middle; - width: 0; - } - - .dialog-footer cr-input { - --cr-input-container: { - border-radius: 0; - } - --cr-input-error-display: none; - --cr-input-input: { - background-color: transparent; - border-bottom: 1px solid var(--paper-grey-800); - } - --cr-input-padding-end: 0; - --cr-input-padding-start: 0; - --cr-input-padding-bottom: 2px; - width: 100%; - } - - paper-progress { - --paper-progress-active-color: rgb(26, 194, 34); - } - - body.check-select .dialog-header files-toggle-ripple { - --files-toggle-ripple: { - background-color: black; - }; - --files-toggle-ripple-activated: { - opacity: 0.08; - }; - } - - body.check-select .dialog-header files-ripple { - --files-ripple: { - background-color: black; - } - } - </style> - <script src="foreground/js/elements_importer.js"></script> <script src="foreground/js/main_scripts.js" defer></script> </head> <body tabindex="-1"> + <custom-style> + <style is="custom-style"> + #search-box cr-input { + --cr-input-color: white; + --cr-input-focus-color: white; + --cr-input-container: { + border-radius: 0; + } + --cr-input-error-display: none; + --cr-input-input: { + background-color: transparent; + border-bottom: 1px solid rgba(255, 255, 255, 0.5); + } + --cr-input-padding-end: 20px; + --cr-input-padding-start: 0; + --cr-input-placeholder-color: rgba(255, 255, 255, 0.5); + display: inline-block; + transition: width 200ms ease; + vertical-align: middle; + width: 0; + } + + .dialog-footer cr-input { + --cr-input-container: { + border-radius: 0; + } + --cr-input-error-display: none; + --cr-input-input: { + background-color: transparent; + border-bottom: 1px solid var(--paper-grey-800); + } + --cr-input-padding-end: 0; + --cr-input-padding-start: 0; + --cr-input-padding-bottom: 2px; + width: 100%; + } + + paper-progress { + --paper-progress-active-color: rgb(26, 194, 34); + } + + body.check-select .dialog-header files-toggle-ripple { + --files-toggle-ripple: { + background-color: black; + }; + --files-toggle-ripple-activated: { + opacity: 0.08; + }; + } + + body.check-select .dialog-header files-ripple { + --files-ripple: { + background-color: black; + } + } + </style> + </custom-style> + <commands> <command id="cut" i18n-values="label:CUT_BUTTON_LABEL" shortcut="x|Ctrl">
diff --git a/ui/file_manager/file_manager/test/quick_view.js b/ui/file_manager/file_manager/test/quick_view.js index 6c16936..62decfe 100644 --- a/ui/file_manager/file_manager/test/quick_view.js +++ b/ui/file_manager/file_manager/test/quick_view.js
@@ -16,7 +16,7 @@ // changed to text file 'hello.txt'. assertTrue(test.selectFile(file)); // Press Space key. - assertTrue(test.fakeKeyDown('#file-list', ' ', ' ', false, false, false)); + assertTrue(test.fakeKeyDown('#file-list', ' ', false, false, false)); // Wait until Quick View is displayed and files-safe-media.src is set. return test .repeatUntil(() => {
diff --git a/ui/file_manager/integration_tests/file_manager/create_new_folder.js b/ui/file_manager/integration_tests/file_manager/create_new_folder.js index 7a6e9a4..7e93b44 100644 --- a/ui/file_manager/integration_tests/file_manager/create_new_folder.js +++ b/ui/file_manager/integration_tests/file_manager/create_new_folder.js
@@ -24,7 +24,7 @@ return remoteCall.waitForElementLost(appId, '#file-list [selected]'); }).then(function() { // Press DownArrow key to select an item. - const key = ['#file-list', 'ArrowDown', 'Down', false, false, false]; + const key = ['#file-list', 'ArrowDown', false, false, false]; return remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key); }).then(function(result) { chrome.test.assertTrue(result); @@ -58,7 +58,7 @@ }).then(function(result) { chrome.test.assertTrue(result); // Press Ctrl+E to create a new folder. - const key = ['#file-list', 'e', 'U+0045', true, false, false]; + const key = ['#file-list', 'e', true, false, false]; return remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key); }).then(function(result) { chrome.test.assertTrue(result); @@ -101,7 +101,7 @@ 'inputText', appId, [textInput, 'Test Folder Name']); }).then(function() { // Press the Enter key. - const key = [textInput, 'Enter', 'Enter', false, false, false]; + const key = [textInput, 'Enter', false, false, false]; return remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key); }).then(function(result) { chrome.test.assertTrue(result);
diff --git a/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js b/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js index 4115266..597387a8 100644 --- a/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js +++ b/ui/file_manager/integration_tests/file_manager/directory_tree_context_menu.js
@@ -87,7 +87,7 @@ // Paste return remoteCall.callRemoteTestUtil( 'fakeKeyDown', windowId, - ['body', 'v', 'U+0056' /* v */, true /* ctrl */, false, false]); + ['body', 'v', true /* ctrl */, false, false]); }) .then(function() { // Confirm the photos directory is pasted correctly. @@ -104,7 +104,7 @@ return (useKeyboardShortcut ? remoteCall.callRemoteTestUtil( 'fakeKeyDown', windowId, - ['body', 'Enter', 'Enter', true /* ctrl */, false, false]) : + ['body', 'Enter', true /* ctrl */, false, false]) : clickDirectoryTreeContextMenuItem(windowId, '/photos', 'rename') ).then(function() { return remoteCall.waitForElement(windowId, '.tree-row > input'); @@ -114,7 +114,7 @@ }).then(function() { return remoteCall.callRemoteTestUtil( 'fakeKeyDown', windowId, - ['.tree-row > input', 'Enter', 'Enter', false, false, false]); + ['.tree-row > input', 'Enter', false, false, false]); }); } @@ -171,7 +171,7 @@ }).then(function() { if (useKeyboardShortcut) { return remoteCall.callRemoteTestUtil('fakeKeyDown', windowId, - ['body', 'e', 'U+0045' /* e */, true /* ctrl */, false, false]); + ['body', 'e', true /* ctrl */, false, false]); } else { return clickDirectoryTreeContextMenuItem( windowId, '/photos', 'new-folder'); @@ -184,7 +184,7 @@ }).then(function() { return remoteCall.callRemoteTestUtil( 'fakeKeyDown', windowId, - ['.tree-row > input', 'Enter', 'Enter', false, false, false]); + ['.tree-row > input', 'Enter', false, false, false]); }).then(function() { // Confirm that new directory is added to the directory tree. return remoteCall.waitForElement( @@ -228,7 +228,7 @@ }).then(function() { // Press Ctrl+C. return remoteCall.callRemoteTestUtil('fakeKeyDown', windowId, - ['body', 'c', 'U+0043' /* c */, true /* ctrl */, false, false]); + ['body', 'c', true /* ctrl */, false, false]); }).then(function() { return navigateToDestinationDirectoryAndTestPaste(windowId); })); @@ -281,7 +281,7 @@ }).then(function() { // Press Ctrl+X. return remoteCall.callRemoteTestUtil('fakeKeyDown', windowId, - ['body', 'x', 'U+0058' /* x */, true /* ctrl */, false, false]); + ['body', 'x', true /* ctrl */, false, false]); }).then(function() { return navigateToDestinationDirectoryAndTestPaste(windowId); }).then(function() { @@ -325,7 +325,7 @@ .then(function() { return remoteCall.callRemoteTestUtil( 'fakeKeyDown', windowId, - ['body', 'c', 'U+0043' /* c */, true /* ctrl */, false, false]); + ['body', 'c', true /* ctrl */, false, false]); }) .then(function() { return remoteCall.navigateWithDirectoryTree( @@ -437,7 +437,7 @@ }) .then(function() { const enterKey = [ - '.tree-row > input', 'Enter', 'Enter', false, false, false + '.tree-row > input', 'Enter', false, false, false ]; return remoteCall.callRemoteTestUtil( 'fakeKeyDown', appId, enterKey);
diff --git a/ui/file_manager/integration_tests/file_manager/drive_specific.js b/ui/file_manager/integration_tests/file_manager/drive_specific.js index 6a977731..dd24d71 100644 --- a/ui/file_manager/integration_tests/file_manager/drive_specific.js +++ b/ui/file_manager/integration_tests/file_manager/drive_specific.js
@@ -167,7 +167,7 @@ appId = id; remoteCall.callRemoteTestUtil( 'fakeKeyDown', appId, - ['#autocomplete-list', 'ArrowDown', 'Down', false, false, false], + ['#autocomplete-list', 'ArrowDown', false, false, false], this.next); }, function(result) { @@ -216,8 +216,7 @@ function(result) { remoteCall.callRemoteTestUtil( 'fakeKeyDown', appId, - ['#search-box cr-input', 'Enter', 'Enter', false, false, false], - this.next); + ['#search-box cr-input', 'Enter', false, false, false], this.next); }, function(result) { remoteCall.waitForFileListChange(appId, BASIC_DRIVE_ENTRY_SET.length) @@ -330,7 +329,7 @@ function(result) { remoteCall.callRemoteTestUtil( 'fakeKeyDown', appId, - ['#search-box cr-input', 'A', 'A', true, false, false], this.next); + ['#search-box cr-input', 'A', true, false, false], this.next); }, // Check we didn't enter check-select mode. function(result) {
diff --git a/ui/file_manager/integration_tests/file_manager/file_dialog.js b/ui/file_manager/integration_tests/file_manager/file_dialog.js index 37980477..9f1679a 100644 --- a/ui/file_manager/integration_tests/file_manager/file_dialog.js +++ b/ui/file_manager/integration_tests/file_manager/file_dialog.js
@@ -176,7 +176,7 @@ function openFileDialogSendEscapeKey(volume, name) { const type = {type: 'openFile'}; - const escapeKey = ['#file-list', 'Escape', 'U+001B', false, false, false]; + const escapeKey = ['#file-list', 'Escape', false, false, false]; let closer = sendOpenFileDialogKey.bind(null, name, escapeKey); return createFileEntryPromise(volume)
diff --git a/ui/file_manager/integration_tests/file_manager/folder_shortcuts.js b/ui/file_manager/integration_tests/file_manager/folder_shortcuts.js index 33a71dd6..2b227f11 100644 --- a/ui/file_manager/integration_tests/file_manager/folder_shortcuts.js +++ b/ui/file_manager/integration_tests/file_manager/folder_shortcuts.js
@@ -265,7 +265,7 @@ }, // Send Ctrl+3 key to file-list to select 3rd shortcut. function() { - const key = ['#file-list', '3', '3', true, false, false]; + const key = ['#file-list', '3', true, false, false]; remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key, this.next); }, // Check: current directory and selection should be D. @@ -275,7 +275,7 @@ }, // Send UpArrow key to directory tree to select the shortcut above D. function() { - const key = ['#directory-tree', 'ArrowUp', 'Up', false, false, false]; + const key = ['#directory-tree', 'ArrowUp', false, false, false]; remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key, this.next); }, // Check: current directory should be D, with shortcut C selected. @@ -285,7 +285,7 @@ }, // Send Enter key to the directory tree to change to directory C. function() { - const key = ['#directory-tree', 'Enter', 'Enter', false, false, false]; + const key = ['#directory-tree', 'Enter', false, false, false]; remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key, this.next); }, // Check: current directory and selection should be C.
diff --git a/ui/file_manager/integration_tests/file_manager/gear_menu.js b/ui/file_manager/integration_tests/file_manager/gear_menu.js index 489cf078..ab345b6 100644 --- a/ui/file_manager/integration_tests/file_manager/gear_menu.js +++ b/ui/file_manager/integration_tests/file_manager/gear_menu.js
@@ -269,7 +269,7 @@ }, // Open the gear meny by a shortcut (Alt-E). function() { - remoteCall.fakeKeyDown(appId, 'body', 'e', 'U+0045', false, false, true) + remoteCall.fakeKeyDown(appId, 'body', 'e', false, false, true) .then(this.next); }, // Wait for menu to appear. @@ -548,7 +548,7 @@ function(result) { chrome.test.assertTrue(result); remoteCall - .fakeKeyDown(appId, '#file-list', 'c', 'U+0043', true, false, false) + .fakeKeyDown(appId, '#file-list', 'c', true, false, false) .then(this.next); }, function() {
diff --git a/ui/file_manager/integration_tests/file_manager/keyboard_operations.js b/ui/file_manager/integration_tests/file_manager/keyboard_operations.js index 8cd346b..4beb05eb 100644 --- a/ui/file_manager/integration_tests/file_manager/keyboard_operations.js +++ b/ui/file_manager/integration_tests/file_manager/keyboard_operations.js
@@ -179,7 +179,7 @@ }).then(function(result) { chrome.test.assertTrue(result, 'selectFile failed'); // Press Ctrl+Enter key to rename the file. - const key = ['#file-list', 'Enter', 'Enter', true, false, false]; + const key = ['#file-list', 'Enter', true, false, false]; return remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key); }).then(function(result) { chrome.test.assertTrue(result); @@ -191,7 +191,7 @@ 'inputText', appId, [textInput, newName]); }).then(function() { // Send Enter key to the text input. - const key = [textInput, 'Enter', 'Enter', false, false, false]; + const key = [textInput, 'Enter', false, false, false]; return remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key); }).then(function(result) { chrome.test.assertTrue(result); @@ -227,7 +227,7 @@ }).then(function(result) { chrome.test.assertTrue(result); // Press ArrowDown to select the photos folder. - const select = ['#file-list', 'ArrowDown', 'Down', false, false, false]; + const select = ['#file-list', 'ArrowDown', false, false, false]; return remoteCall.callRemoteTestUtil('fakeKeyDown', appId, select); }).then(function(result) { chrome.test.assertTrue(result); @@ -236,7 +236,7 @@ return remoteCall.waitForElement(appId, selectedItem); }).then(function() { // Press Ctrl+Enter to rename the photos folder. - const key = ['#file-list', 'Enter', 'Enter', true, false, false]; + const key = ['#file-list', 'Enter', true, false, false]; return remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key); }).then(function(result) { chrome.test.assertTrue(result); @@ -248,12 +248,12 @@ 'inputText', appId, [textInput, 'bbq photos']); }).then(function() { // Send Enter to the list to attempt to enter the directory. - const key = ['#list-container', 'Enter', 'Enter', false, false, false]; + const key = ['#list-container', 'Enter', false, false, false]; return remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key); }).then(function(result) { chrome.test.assertTrue(result); // Send Enter to the text input to complete renaming. - const key = [textInput, 'Enter', 'Enter', false, false, false]; + const key = [textInput, 'Enter', false, false, false]; return remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key); }).then(function(result) { chrome.test.assertTrue(result);
diff --git a/ui/file_manager/integration_tests/file_manager/open_audio_files.js b/ui/file_manager/integration_tests/file_manager/open_audio_files.js index 3539e3e..1dd52c0 100644 --- a/ui/file_manager/integration_tests/file_manager/open_audio_files.js +++ b/ui/file_manager/integration_tests/file_manager/open_audio_files.js
@@ -77,7 +77,7 @@ function audioTimeLeapForward(audioAppId) { for (let i = 1; i <= 9; ++i) { audioPlayerApp.fakeKeyDown( - audioAppId, 'body', 'ArrowRight', 'Right', false, false, false); + audioAppId, 'body', 'ArrowRight', false, false, false); } }
diff --git a/ui/file_manager/integration_tests/file_manager/quick_view.js b/ui/file_manager/integration_tests/file_manager/quick_view.js index 1c931d21..aaf964d 100644 --- a/ui/file_manager/integration_tests/file_manager/quick_view.js +++ b/ui/file_manager/integration_tests/file_manager/quick_view.js
@@ -30,7 +30,7 @@ // Press the space key. function(result) { chrome.test.assertTrue(!!result, 'selectFile failed'); - const space = ['#file-list', ' ', ' ', false, false, false]; + const space = ['#file-list', ' ', false, false, false]; remoteCall.callRemoteTestUtil('fakeKeyDown', appId, space, this.next); }, // Check: the Quick View element should be shown.
diff --git a/ui/file_manager/integration_tests/file_manager/tab_index.js b/ui/file_manager/integration_tests/file_manager/tab_index.js index 9215657..ce9bb7c 100644 --- a/ui/file_manager/integration_tests/file_manager/tab_index.js +++ b/ui/file_manager/integration_tests/file_manager/tab_index.js
@@ -22,9 +22,7 @@ // Press the Ctrl-F key. function(element) { remoteCall.callRemoteTestUtil( - 'fakeKeyDown', appId, - ['body', 'f', 'U+0046', true, false, false], - this.next); + 'fakeKeyDown', appId, ['body', 'f', true, false, false], this.next); }, // Check that the search box has the focus. function(result) { @@ -36,8 +34,7 @@ function(element) { remoteCall.callRemoteTestUtil( 'fakeKeyDown', appId, - ['#search-box cr-input', 'Escape', 'U+001B', false, false, false], - this.next); + ['#search-box cr-input', 'Escape', false, false, false], this.next); }, // Check that the file list has the focus. function(result) { @@ -286,8 +283,7 @@ promise = promise.then(function() { // Closes the window by pressing Enter. return remoteCall.callRemoteTestUtil( - 'fakeKeyDown', appId, ['#file-list', 'Enter', 'Enter', false, false, - false]); + 'fakeKeyDown', appId, ['#file-list', 'Enter', false, false, false]); }); return promise;
diff --git a/ui/file_manager/integration_tests/file_manager/zip_files.js b/ui/file_manager/integration_tests/file_manager/zip_files.js index b311ba2..ef7a694 100644 --- a/ui/file_manager/integration_tests/file_manager/zip_files.js +++ b/ui/file_manager/integration_tests/file_manager/zip_files.js
@@ -36,7 +36,7 @@ // Press the Enter key. function(result) { chrome.test.assertTrue(!!result, 'selectFile failed'); - const key = ['#file-list', 'Enter', 'Enter', false, false, false]; + const key = ['#file-list', 'Enter', false, false, false]; remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key, this.next); }, // Check: the zip file content should be shown (unzip). @@ -69,7 +69,7 @@ // Press the Enter key. function(result) { chrome.test.assertTrue(!!result, 'selectFile failed'); - const key = ['#file-list', 'Enter', 'Enter', false, false, false]; + const key = ['#file-list', 'Enter', false, false, false]; remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key, this.next); }, // Check: the zip file content should be shown (unzip). @@ -127,7 +127,7 @@ // Press the Enter key. function(result) { chrome.test.assertTrue(!!result, 'selectFile failed'); - const key = ['#file-list', 'Enter', 'Enter', false, false, false]; + const key = ['#file-list', 'Enter', false, false, false]; remoteCall.callRemoteTestUtil('fakeKeyDown', appId, key, this.next); }, // Check: the zip file content should be shown (unzip).
diff --git a/ui/file_manager/integration_tests/gallery/open_image_files.js b/ui/file_manager/integration_tests/gallery/open_image_files.js index 013fc3b1..b6e69b53 100644 --- a/ui/file_manager/integration_tests/gallery/open_image_files.js +++ b/ui/file_manager/integration_tests/gallery/open_image_files.js
@@ -114,7 +114,7 @@ // Press Enter key and mode should be changed to slide mode. return gallery.callRemoteTestUtil( 'fakeKeyDown', appId, - [null /* active element */, 'Enter', 'Enter', false, false, false]); + [null /* active element */, 'Enter', false, false, false]); }).then(function() { // Wait until it changes to slide mode. return gallery.waitForElement(appId, '.gallery[mode="slide"]');
diff --git a/ui/file_manager/integration_tests/gallery/photo_editor.js b/ui/file_manager/integration_tests/gallery/photo_editor.js index 110bbc36..12c83ad 100644 --- a/ui/file_manager/integration_tests/gallery/photo_editor.js +++ b/ui/file_manager/integration_tests/gallery/photo_editor.js
@@ -94,7 +94,7 @@ }). then(function() { return gallery.fakeKeyDown( - appId, 'body', 'Enter', 'Enter', false, false, false); + appId, 'body', 'Enter', false, false, false); }). then(function(ret) { chrome.test.assertTrue(ret); @@ -158,8 +158,7 @@ origMetadata = metadata; // Push the Enter key. - return gallery.fakeKeyDown(appId, 'body', 'Enter', 'Enter', false, false, - false); + return gallery.fakeKeyDown(appId, 'body', 'Enter', false, false, false); }).then(function() { // Wait until the image is updated. return repeatUntil(function() { @@ -209,7 +208,7 @@ }) .then(function() { return gallery.fakeKeyDown( - appId, 'body', 'Enter', 'Enter', false, false, false); + appId, 'body', 'Enter', false, false, false); }) .then(function() { return gallery.waitForSlideImage(appId, 667, 500, @@ -248,7 +247,7 @@ }) .then(function() { return gallery.fakeKeyDown( - appId, 'body', 'Enter', 'Enter', false, false, false); + appId, 'body', 'Enter', false, false, false); }) .then(function() { return gallery.waitForSlideImage(appId, 500, 300,
diff --git a/ui/file_manager/integration_tests/gallery/thumbnail_mode.js b/ui/file_manager/integration_tests/gallery/thumbnail_mode.js index 03b8e544..010b73d5 100644 --- a/ui/file_manager/integration_tests/gallery/thumbnail_mode.js +++ b/ui/file_manager/integration_tests/gallery/thumbnail_mode.js
@@ -96,7 +96,7 @@ }).then(function() { return gallery.callRemoteTestUtil( 'fakeKeyDown', appId, - ['button.delete', 'Enter', 'Enter', false, false, false]); + ['button.delete', 'Enter', false, false, false]); }).then(function() { // When user has pressed enter key on button, click event is // dispatched after keydown event. @@ -107,8 +107,7 @@ case 'delete-key': // Press delete key. return gallery.callRemoteTestUtil( - 'fakeKeyDown', appId, - ['body', 'Delete', 'U+007F' /* Delete */, false, false, false]); + 'fakeKeyDown', appId, ['body', 'Delete', false, false, false]); break; } }).then(function(result) { @@ -198,8 +197,7 @@ // Press Right key with shift. return gallery.fakeKeyDown( - appId, '.thumbnail-view', 'ArrowRight', 'Right', false, - true /* Shift */, false); + appId, '.thumbnail-view', 'ArrowRight', false, true /* Shift */, false); }).then(function() { // Confirm 2 images are selected: [1][2] 3 return gallery.callRemoteTestUtil('queryAllElements', appId, @@ -211,8 +209,7 @@ // Press Right key with shift. return gallery.fakeKeyDown( - appId, '.thumbnail-view', 'ArrowRight', 'Right', false, - true /* Shift */, false); + appId, '.thumbnail-view', 'ArrowRight', false, true /* Shift */, false); }).then(function() { // Confirm 3 images are selected: [1][2][3] return gallery.callRemoteTestUtil('queryAllElements', appId, @@ -226,8 +223,7 @@ // Press Left key with shift. return gallery.fakeKeyDown( - appId, '.thumbnail-view', 'ArrowLeft', 'Left', false, - true /* Shift */, false); + appId, '.thumbnail-view', 'ArrowLeft', false, true /* Shift */, false); }).then(function() { // Confirm 2 images are selected: [1][2] 3 return gallery.callRemoteTestUtil('queryAllElements', appId, @@ -239,8 +235,7 @@ // Press Right key without shift. return gallery.fakeKeyDown( - appId, '.thumbnail-view', 'ArrowRight', 'Right', false, - false, false); + appId, '.thumbnail-view', 'ArrowRight', false, false, false); }).then(function() { // Confirm only the last image is selected: 1 2 [3] return gallery.callRemoteTestUtil('queryAllElements', appId, @@ -285,8 +280,7 @@ }).then(function() { // Press Ctrl+A to select all images. return gallery.fakeKeyDown(appId, '.thumbnail-view', - 'a', 'U+0041' /* A */, true /* Ctrl*/, false /* Shift */, - false /* Alt */); + 'a', true /* Ctrl*/, false /* Shift */, false /* Alt */); }).then(function() { // Confirm that 2 images are selected. return gallery.callRemoteTestUtil('queryAllElements', appId,
diff --git a/ui/file_manager/integration_tests/remote_call.js b/ui/file_manager/integration_tests/remote_call.js index d30bfd8..0e08480a 100644 --- a/ui/file_manager/integration_tests/remote_call.js +++ b/ui/file_manager/integration_tests/remote_call.js
@@ -259,7 +259,6 @@ * @param {string} windowId Window ID. * @param {string} query Query for the target element. * @param {string} key DOM UI Events Key value. - * @param {string} keyIdentifer Key identifier. * @param {boolean} ctrlKey Control key flag. * @param {boolean} shiftKey Shift key flag. * @param {boolean} altKey Alt key flag. @@ -267,10 +266,9 @@ * result. */ RemoteCall.prototype.fakeKeyDown = - function(windowId, query, key, keyIdentifer, ctrlKey, shiftKey, altKey) { + function(windowId, query, key, ctrlKey, shiftKey, altKey) { var resultPromise = this.callRemoteTestUtil( - 'fakeKeyDown', windowId, - [query, key, keyIdentifer, ctrlKey, shiftKey, altKey]); + 'fakeKeyDown', windowId, [query, key, ctrlKey, shiftKey, altKey]); return resultPromise.then(function(result) { if (result) return true; @@ -422,9 +420,8 @@ */ RemoteCallFilesApp.prototype.checkNextTabFocus = function(windowId, elementId) { - return remoteCall.callRemoteTestUtil('fakeKeyDown', - windowId, - ['body', 'Tab', 'U+0009', false]).then( + return remoteCall.callRemoteTestUtil( + 'fakeKeyDown', windowId, ['body', 'Tab', false, false, false]).then( function(result) { chrome.test.assertTrue(result); return remoteCall.callRemoteTestUtil('getActiveElement',
diff --git a/ui/message_center/BUILD.gn b/ui/message_center/BUILD.gn index 6a16f56..9924381 100644 --- a/ui/message_center/BUILD.gn +++ b/ui/message_center/BUILD.gn
@@ -134,8 +134,6 @@ "views/notification_control_buttons_view.h", "views/notification_header_view.cc", "views/notification_header_view.h", - "views/notification_swipe_control_view.cc", - "views/notification_swipe_control_view.h", "views/notification_view.cc", "views/notification_view.h", "views/notification_view_md.cc", @@ -146,8 +144,6 @@ "views/popup_alignment_delegate.h", "views/proportional_image_view.cc", "views/proportional_image_view.h", - "views/slidable_message_view.cc", - "views/slidable_message_view.h", "views/slide_out_controller.cc", "views/slide_out_controller.h", ]
diff --git a/ui/message_center/views/slidable_message_view.h b/ui/message_center/views/slidable_message_view.h deleted file mode 100644 index 86e18b09..0000000 --- a/ui/message_center/views/slidable_message_view.h +++ /dev/null
@@ -1,82 +0,0 @@ -// Copyright (c) 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 UI_MESSAGE_CENTER_VIEWS_SLIDABLE_MESSAGE_VIEW_H_ -#define UI_MESSAGE_CENTER_VIEWS_SLIDABLE_MESSAGE_VIEW_H_ - -#include "ui/message_center/views/message_view.h" -#include "ui/message_center/views/notification_swipe_control_view.h" -#include "ui/views/view.h" - -namespace message_center { - -class MESSAGE_CENTER_EXPORT SlidableMessageView - : public views::View, - public MessageView::SlideObserver, - public NotificationSwipeControlView::Observer { - public: - SlidableMessageView(message_center::MessageView* message_view); - ~SlidableMessageView() override; - - MessageView* GetMessageView() const { return message_view_; } - static SlidableMessageView* GetFromMessageView(MessageView* message_view); - - // MessageView::SlideObserver - void OnSlideChanged(const std::string& notification_id) override; - - // NotificationSwipeControlView::Observer - void OnSettingsButtonPressed(const ui::Event& event) override; - void OnSnoozeButtonPressed(const ui::Event& event) override; - - void SetExpanded(bool expanded) { - return message_view_->SetExpanded(expanded); - } - - bool IsExpanded() const { return message_view_->IsExpanded(); } - - bool IsAutoExpandingAllowed() const { - return message_view_->IsAutoExpandingAllowed(); - } - - bool IsCloseButtonFocused() const { - return message_view_->IsCloseButtonFocused(); - } - - bool IsManuallyExpandedOrCollapsed() const { - return message_view_->IsManuallyExpandedOrCollapsed(); - } - - void SetManuallyExpandedOrCollapsed(bool value) { - return message_view_->SetManuallyExpandedOrCollapsed(value); - } - - // Updates this view with the new data contained in the notification. - void UpdateWithNotification(const Notification& notification); - - std::string notification_id() const { - return message_view_->notification_id(); - } - - MessageView::Mode GetMode() const { return message_view_->GetMode(); } - - void CloseSwipeControl(); - - void StartDismissAnimation(); - - // views::View - void ChildPreferredSizeChanged(views::View* child) override; - void ChildVisibilityChanged(views::View* child) override; - gfx::Size CalculatePreferredSize() const override; - int GetHeightForWidth(int width) const override; - - void UpdateCornerRadius(int top_radius, int bottom_radius); - - private: - MessageView* message_view_; - std::unique_ptr<NotificationSwipeControlView> control_view_; -}; - -} // namespace message_center - -#endif // UI_MESSAGE_CENTER_VIEWS_SLIDABLE_MESSAGE_VIEW_H_
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/BUILD.gn b/ui/webui/resources/cr_components/chromeos/multidevice_setup/BUILD.gn index ef70a27..f59a915 100644 --- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/BUILD.gn +++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/BUILD.gn
@@ -10,7 +10,7 @@ deps = [ ":button_bar", ":fake_mojo_service", - ":mojo_api_behavior", + ":mojo_api", ":multidevice_setup", ":multidevice_setup_browser_proxy", ":setup_failed_page", @@ -49,14 +49,14 @@ ] } -js_library("mojo_api_behavior") { +js_library("mojo_api") { } js_library("multidevice_setup") { deps = [ ":button_bar", ":fake_mojo_service", - ":mojo_api_behavior", + ":mojo_api", ":password_page", ":setup_failed_page", ":setup_succeeded_page",
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/mojo_api_behavior.html b/ui/webui/resources/cr_components/chromeos/multidevice_setup/mojo_api.html similarity index 93% rename from ui/webui/resources/cr_components/chromeos/multidevice_setup/mojo_api_behavior.html rename to ui/webui/resources/cr_components/chromeos/multidevice_setup/mojo_api.html index 13db6c6..0b76207 100644 --- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/mojo_api_behavior.html +++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/mojo_api.html
@@ -8,5 +8,5 @@ </script> <script src="chrome://resources/js/chromeos/multidevice_setup_constants.mojom.js"> </script> -<script src="chrome://resources/cr_components/chromeos/multidevice_setup/mojo_api_behavior.js"> +<script src="chrome://resources/cr_components/chromeos/multidevice_setup/mojo_api.js"> </script>
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/mojo_api.js b/ui/webui/resources/cr_components/chromeos/multidevice_setup/mojo_api.js new file mode 100644 index 0000000..0fd824c1 --- /dev/null +++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/mojo_api.js
@@ -0,0 +1,36 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +cr.define('multidevice_setup', function() { + /** @interface */ + class MojoInterfaceProvider { + /** + * @return {!chromeos.multideviceSetup.mojom.MultiDeviceSetupImpl} + */ + getInterfacePtr() {} + } + + /** @implements {multidevice_setup.MojoInterfaceProvider} */ + class MojoInterfaceProviderImpl { + constructor() { + /** @private {!chromeos.multideviceSetup.mojom.MultiDeviceSetupPtr} */ + this.ptr_ = new chromeos.multideviceSetup.mojom.MultiDeviceSetupPtr(); + Mojo.bindInterface( + chromeos.multideviceSetup.mojom.MultiDeviceSetup.name, + mojo.makeRequest(this.ptr_).handle); + } + + /** @override */ + getInterfacePtr() { + return this.ptr_; + } + } + + cr.addSingletonGetter(MojoInterfaceProviderImpl); + + return { + MojoInterfaceProvider: MojoInterfaceProvider, + MojoInterfaceProviderImpl: MojoInterfaceProviderImpl, + }; +});
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/mojo_api_behavior.js b/ui/webui/resources/cr_components/chromeos/multidevice_setup/mojo_api_behavior.js deleted file mode 100644 index 197ee84..0000000 --- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/mojo_api_behavior.js +++ /dev/null
@@ -1,23 +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. - -/** @polymerBehavior */ -const MojoApiBehavior = { - properties: { - /** - * Provides access to the MultiDeviceSetup Mojo service. - * @type {!chromeos.multideviceSetup.mojom.MultiDeviceSetupImpl} - */ - multideviceSetup: { - type: Object, - value: function() { - let ptr = new chromeos.multideviceSetup.mojom.MultiDeviceSetupPtr(); - Mojo.bindInterface( - chromeos.multideviceSetup.mojom.MultiDeviceSetup.name, - mojo.makeRequest(ptr).handle); - return ptr; - }, - } - }, -};
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.html b/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.html index b7e16c6b..f9968ae6 100644 --- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.html +++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.html
@@ -2,7 +2,7 @@ <link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/button_bar.html"> <link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/fake_mojo_service.html"> -<link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/mojo_api_behavior.html"> +<link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/mojo_api.html"> <link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/multidevice_setup_shared_css.html"> <link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/password_page.html"> <link rel="import" href="chrome://resources/cr_components/chromeos/multidevice_setup/setup_failed_page.html"> @@ -19,7 +19,12 @@ @apply --layout-vertical; box-sizing: border-box; color: var(--google-grey-700); + font-size: 13px; height: 100%; + line-height: 16px; + margin: auto; + max-height: 640px; + max-width: 768px; padding: 60px 64px 32px 64px; } </style>
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.js b/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.js index fa5f57e6..ca9bd40 100644 --- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.js +++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/multidevice_setup.js
@@ -88,11 +88,13 @@ computed: 'shouldForwardButtonBeDisabled_(' + 'passwordPageForwardButtonDisabled_, visiblePageName_)', }, - }, - behaviors: [ - MojoApiBehavior, - ], + /** + * Interface to the MultiDeviceSetup Mojo service. + * @private {!chromeos.multideviceSetup.mojom.MultiDeviceSetupImpl} + */ + multideviceSetup_: Object + }, listeners: { 'backward-navigation-requested': 'onBackwardNavigationRequested_', @@ -100,8 +102,15 @@ }, /** @override */ + created: function() { + this.multideviceSetup_ = + multidevice_setup.MojoInterfaceProviderImpl.getInstance() + .getInterfacePtr(); + }, + + /** @override */ attached: function() { - this.multideviceSetup.getEligibleHostDevices() + this.multideviceSetup_.getEligibleHostDevices() .then((responseParams) => { if (responseParams.eligibleHostDevices.length == 0) { console.warn('Potential host list is empty.'); @@ -138,7 +147,7 @@ case PageName.PASSWORD: this.$.passwordPage.clearPasswordTextInput(); let deviceId = /** @type {string} */ (this.selectedDeviceId_); - this.multideviceSetup.setHostDevice(deviceId, this.authToken_) + this.multideviceSetup_.setHostDevice(deviceId, this.authToken_) .then((responseParams) => { if (!responseParams.success) { console.warn(
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/password_page.html b/ui/webui/resources/cr_components/chromeos/multidevice_setup/password_page.html index b4c388ed..388eeb25 100644 --- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/password_page.html +++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/password_page.html
@@ -11,20 +11,22 @@ <style include="multidevice-setup-shared"> #user-info-container { @apply --layout-horizontal; - border: 1px solid rgb(95, 99, 104); - border-radius: 15px; - color: rgb(95, 99, 104); - margin: 35px 0; - padding: 5px 20px 5px 5px; - width: fit-content; + align-items: center; + color: var(--paper-grey-600); } #profile-photo { border-radius: 50%; height: 20px; - margin-right: 4px; + margin-right: 8px; width: 20px; } + + #passwordInput { + height: 32px; + margin-top: 64px; + width: 560px; + } </style> <ui-page header-text="[[headerText]]" icon-name="google-g"> <div id="content-container" slot="additional-content"> @@ -38,7 +40,8 @@ error-message="[[i18n('wrongPassword')]]" value="{{inputValue_}}" aria-disabled="false" - on-change="onUserPressedEnter_"> + on-change="onUserPressedEnter_" + autofocus> </cr-input> </div> </ui-page>
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/password_page.js b/ui/webui/resources/cr_components/chromeos/multidevice_setup/password_page.js index eba7b26..87c58da 100644 --- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/password_page.js +++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/password_page.js
@@ -99,8 +99,6 @@ this.profilePhotoUrl_ = profileInfo.profilePhotoUrl; this.email_ = profileInfo.email; }); - - this.$.passwordInput.focus(); }, /** Overridden from UiPageContainerBehavior. */
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/setup_succeeded_page.html b/ui/webui/resources/cr_components/chromeos/multidevice_setup/setup_succeeded_page.html index 4624bb8..a899610 100644 --- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/setup_succeeded_page.html +++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/setup_succeeded_page.html
@@ -19,7 +19,7 @@ url(setup_succeeded_icon_1x.png) 1x, url(setup_succeeded_icon_2x.png) 2x); height: 156px; - margin-top: 20px; + margin-top: 64px; width: 416px; } </style>
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/start_setup_page.html b/ui/webui/resources/cr_components/chromeos/multidevice_setup/start_setup_page.html index 3d8996f..d9a187b6 100644 --- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/start_setup_page.html +++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/start_setup_page.html
@@ -12,6 +12,12 @@ <style include="multidevice-setup-shared"> #selector-and-details-container { @apply --layout-horizontal; + margin-top: 48px; + } + + #singleDeviceName { + color: var(--google-grey-900); + margin-top: 16px; } #deviceDropdown { @@ -73,7 +79,8 @@ <div id="deviceSelectionContainer" class="flex"> [[getDeviceSelectionHeader_(devices)]] <div class="flex"></div> - <div hidden$="[[!doesDeviceListHaveOneElement_(devices)]]"> + <div id="singleDeviceName" + hidden$="[[!doesDeviceListHaveOneElement_(devices)]]"> [[getFirstDeviceNameInList_(devices)]] </div> <div hidden$="[[!doesDeviceListHaveMultipleElements_(devices)]]">
diff --git a/ui/webui/resources/cr_components/chromeos/multidevice_setup/ui_page.html b/ui/webui/resources/cr_components/chromeos/multidevice_setup/ui_page.html index 84b9710..289e0864 100644 --- a/ui/webui/resources/cr_components/chromeos/multidevice_setup/ui_page.html +++ b/ui/webui/resources/cr_components/chromeos/multidevice_setup/ui_page.html
@@ -16,18 +16,17 @@ color: var(--google-grey-900); font-family: 'Google Sans'; font-size: 28px; + font-weight: normal; line-height: 28px; margin: 0; padding-top: 36px; } #message-container { + box-sizing: border-box; + min-height: 32px; padding-top: 16px; } - - #additional-content-container { - padding-top: 48px; - } </style> <iron-icon icon="[[computeIconIdentifier_(iconName)]]"></iron-icon> <h1>[[headerText]]</h1>
diff --git a/ui/webui/resources/cr_components/cr_components_resources.grdp b/ui/webui/resources/cr_components/cr_components_resources.grdp index ed911f4..25851f9 100644 --- a/ui/webui/resources/cr_components/cr_components_resources.grdp +++ b/ui/webui/resources/cr_components/cr_components_resources.grdp
@@ -264,12 +264,12 @@ file="cr_components/chromeos/multidevice_setup/icons.html" type="chrome_html" compress="gzip" /> - <structure name="IDR_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_MOJO_API_BEHAVIOR_HTML" - file="cr_components/chromeos/multidevice_setup/mojo_api_behavior.html" + <structure name="IDR_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_MOJO_API_HTML" + file="cr_components/chromeos/multidevice_setup/mojo_api.html" type="chrome_html" compress="gzip" /> - <structure name="IDR_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_MOJO_API_BEHAVIOR_JS" - file="cr_components/chromeos/multidevice_setup/mojo_api_behavior.js" + <structure name="IDR_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_MOJO_API_JS" + file="cr_components/chromeos/multidevice_setup/mojo_api.js" type="chrome_html" compress="gzip" /> <structure name="IDR_WEBUI_CHROMEOS_MULTIDEVICE_SETUP_MULTIDEVICE_SETUP_HTML"
diff --git a/ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.html b/ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.html index 3cf6faa..168a5fec 100644 --- a/ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.html +++ b/ui/webui/resources/cr_elements/cr_searchable_drop_down/cr_searchable_drop_down.html
@@ -13,7 +13,7 @@ iron-dropdown, cr-input { - width: 270px; + width: var(--cr-searchable-drop-down-width, 270px); } iron-dropdown {